• 自定义View调用onDraw方法



    ====================问题描述====================
    我现在有一个需求,要自定义View,初始化的时候调用了onDraw方法,完后我自定义一个方法,调用该方法的时候,要重新调用onDraw方法,但我用postInvalidate无效,代码如下:

    启动类:
    public class MainActivity extends Activity {
            TestOnDraw view;
            
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                    setContentView(R.layout.activity_main);
                    
                    view = (TestOnDraw) findViewById(R.id.test);
                    
                    new Thread(new Runnable() {
                            
                            @Override
                            public void run() {
                                    view.test();
                            }
                    }).start();
            }
    }
    


    布局文件:
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >
    
        <com.example.testdraw.TestOnDraw 
            android:id="@+id/test"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            />
    
    </LinearLayout>
    


    自定义View
    public class TestOnDraw extends View {
    
            public TestOnDraw(Context context) {
                    this(context, null);
            }
            
            public TestOnDraw(Context context, AttributeSet attrs) {
                    this(context, attrs, 0);
            }
            
            public TestOnDraw(Context context, AttributeSet attrs, int defStyle) {
                    super(context, attrs, defStyle);
            }
    
            @Override
            protected void onDraw(Canvas canvas) {
                    // TODO Auto-generated method stub
                    super.onDraw(canvas);
            
                    Log.d("test", "in");
            }
            
            public void test() {
                    postInvalidate();
            }
    }
    


    我查看日志,onDraw方法只进了一次,就是说postInvalidate();没有生效,我如何修改能实现在初始化进入onDraw后,调用test方法时再次进入onDraw方法
    ====================解决方案1====================
    onDraw()的方法是当在屏幕中需要显示界面的时候才调用的,android会判断某个界面是否需要绘制,如果不需要就根本不会调用到他的onDraw 方法, 例如你把你的自定义view设置为GONE,那么你根本看不到打出来的log了


    另外,为什幺要调用postInviliade呢, Java 的动态绑定机制不是会默认调用子类的onDraw方法吗? 你在线程中再调取一次postInvliade有什么意义吗?
    ====================解决方案2====================
    引用 7 楼 luqing414 的回复:
    Quote: 引用 3 楼 kifile 的回复:

    onDraw()的方法是当在屏幕中需要显示界面的时候才调用的,android会判断某个界面是否需要绘制,如果不需要就根本不会调用到他的onDraw 方法, 例如你把你的自定义view设置为GONE,那么你根本看不到打出来的log了


    另外,为什幺要调用postInviliade呢, Java 的动态绑定机制不是会默认调用子类的onDraw方法吗? 你在线程中再调取一次postInvliade有什么意义吗?


    我是程序要不断的去改变这个自定义View的显示形状,所以要不断的重绘,我这里为了让问题清楚没有将其他逻辑包含进来


    ..那就在 onDraw() 里调用invaliade,另外建议使用Surface View 实现,避免阻塞线程
    ====================解决方案3====================
    引用 6 楼 luqing414 的回复:
    Quote: 引用 5 楼 lionfresh 的回复:

    我觉得在view = (TestOnDraw) findViewById(R.id.test)时onDraw并不是延迟执行了,而是根本就没有执行。

    执行了,我说清空test方法就是将test方法弄成空实现,里面一行代码都没有,完后可以看到onDraw还是调用了的


    postInvalidate() 是往UI队列中丢一个线程,之后开始渲染流程。

    在onCreate中 所有的界面并没有实际生成,所以会优先执行postInvalidate中的代码(这个在渲染队列前头)。
    但是这个是没有效果的。 view 中有个skipInvalidate()方法 说的就是 当view未显示时候,是被skip掉的。

    假如你delay了这个1-2秒,  这个代码执行时后界面已经生成了,他的invalidate就生效, 就会出现你想要的执行两次。

    另 界面生成时候,必然会调用一次onDraw。


        /**
         * Invalidate the whole view. If the view is visible,
         * {@link #onDraw(android.graphics.Canvas)} will be called at some point in
         * the future. This must be called from a UI thread. To call from a non-UI thread,
         * call {@link #postInvalidate()}.
         */
        public void invalidate() {
            invalidate(true);
        }

        public void invalidate(Rect dirty) {
            if (skipInvalidate()) {
                return;
            }
         }
    }

  • 相关阅读:
    c# 第29节 类
    c# 第28节 面向对象概述
    c# 第27节 结构、枚举
    c# 第26节 Main方法
    c# 第25节 方法重载
    Python接口自动化之yaml配置文件
    Python接口自动化之数据驱动
    Python接口自动化之登录接口测试
    测试面试题集-逻辑推理题
    Python接口自动化之unittest单元测试
  • 原文地址:https://www.cnblogs.com/lianxu61/p/4002131.html
Copyright © 2020-2023  润新知