在網上看到很多人都在問自定義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);
}
}
});
}
這種錯誤是很低級,但容易忽略,如果你不是這種原因,那就可以試試網上其他方法,這裡就不貼那些方法了。