天天看點

invalidate()方法不調用onDraw()方法的原因及解決辦法

在網上看到很多人都在問自定義View中,使用invalidate()方法并不會不調用onDraw(),其實很容易忽略的一個原因是:你調用invalidate()的對象是哪個?你使用你要重新整理的那個View對象調用的invalidate()嗎?我曾經就遇到過這樣一個低級的錯誤。

代碼如下:

//自定義View中有一個文本,對外提供接口動态改變文字。
public class ImgTextView extends View {



    public ImgTextView(Context context) {
        super(context);
    }

    public ImgTextView(Context context, AttributeSet attrs) {
        super(context, attrs);

        .....//代碼省略

    }

    private void initPaint() {

        paint = new Paint();

        paint.setAntiAlias(true);

        paint.setColor(color);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);


       ....//自定義view的坐标測量操作
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        Log.e("ly","onDraw: "+titleMsg);

        ........//其它操作


        //畫出文本
        canvas.drawText(titleMsg, imgWidth, (imgHeight - textHei) / 2 + textHei, paint);




    }

    //在Activity中調用
    public void setText(String titleMsg) {
        Log.e("ly","Msg: "+titleMsg);
        this.titleMsg = titleMsg;


        invalidate();

    }
}
           
public class MainActivity extends AppCompatActivity {

    private EditText et;
    private Button btn;
    private ImgTextView itv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        et = ((EditText) findViewById(R.id.et));
        btn = ((Button) findViewById(R.id.btn));

        //所要重新整理的View
        itv = (ImgTextView) findViewById(R.id.imgTextView);

        //并不是所要重新整理的View
        final ImgTextView imgTextView = new ImgTextView(this);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String msg = et.getText().toString();
                if (msg != null) {

                    //使用這種方式調用setText(),根本不能重新整理文本,
                    // 原因是imgTextView是自己new出來的不是所要重新整理對象
                    imgTextView.setText(msg);

                    //此種方式調用可完美運作,動态重新整理文本
                    itv.setText(msg);



                }
            }
        });
    }
           

這種錯誤是很低級,但容易忽略,如果你不是這種原因,那就可以試試網上其他方法,這裡就不貼那些方法了。