本文共 3440 字,大约阅读时间需要 11 分钟。
Android视图更新有多种方法,具体使用时要根据需求选择合适的方式。以下是几种常见的情况,帮助开发者更好地理解和使用。
这种情况最简单,也是最常用的。只需要在Activity中显式调用View对象的invalidate()方法,系统会自动触发View的onDraw()方法进行重绘。
优点:代码简单,容易实现。
缺点:当View内容频繁更新时,可能会由于线程 invalide() 在不同线程中导致UI更新异常。
示例代码:
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final TextView TextView = (TextView) findViewById(R.id.TextView); new Thread(new Runnable() { @Override public void run() { while (true) { TextView.invalidate(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); }}
这种情况需要在新线程中执行UI更新操作,但直接访问View对象会导致异常(CalledFromWrongThread)。
解决方法是使用Handler类进行消息传递和UI更新。具体步骤如下:
示例代码:
public class TimeViewHandler extends Handler { private TextView timeView; public TimeViewHandler(TextView timeView) { super(); this.timeView = timeView; } @Override public void handleMessage(Message msg) { if (msg.what == MSG_UPDATE) { timeView.setText(DateHelper.getNow("kk:mm:ss")); timeView.invalidate(); } super.handleMessage(msg); }}public class MainActivity extends Activity { private static final int MSG_UPDATE = 123; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final TextView TextView = (TextView) findViewById(R.id.TextView); final TimeViewHandler handler = new TimeViewHandler(TextView); new Thread(new Runnable() { @Override public void run() { while (true) { handler.sendEmptyMessage(MSG_UPDATE); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); }}
如果需要更高频率的UI更新而避免因多线程操作导致的性能问题,可以使用SurfaceView和双缓冲的组合。
SurfaceView是View的子类,同时实现了双缓冲功能。通过继承SurfaceHolder.Callback接口,可以在新线程中直接进行绘制操作,而无需通过Handler。
优点:支持高频率的渲染和动画效果,适合需要复杂图形操作的场景。
示例代码:
public class TouchDrawView extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder holder; private TouchDrawListener listener; public TouchDrawView(Context context) { super(context); holder = getHolder(); holder.addCallback(this); listener = new TouchDrawListener(holder); listener.setShape(TouchDrawListener.SHAPE_LINE); listener.setShape_style(TouchDrawListener.SHAPE_STYLE_FILL); setOnClickListener(listener); setLongClickable(true); setFocusable(true); setFocusableInTouchMode(true); } @Override public void surfaceCreated(SurfaceHolder holder) { Canvas canvas = holder.lockCanvas(null); canvas.drawColor(Color.WHITE); holder.unlockCanvasAndPost(canvas); }}
通过以上方法,开发者可以根据具体需求选择合适的View更新方式。在需要高频率更新或复杂图形处理时,可以选择多线程加双缓冲的方案;在简单场景中直接使用主线程的invalidate()方法即可满足需求。
转载地址:http://deroz.baihongyu.com/