Android应用开发中View绘制的一些优化点解析

2019-12-10 18:40:55刘景俊


        另外的一个高代价的操作是布局过程(layout)。 任何时刻对View调用requestLayout()方法,Android UI 框架
  都需要遍历整个View树,确定每个视图它们所占用的大小。如果在measure过程中有任何冲突,可能会多次遍历
  View树。UI设计人员有时为了实现某些效果,创建了较深层次的ViewGroup。但这些深层次View树会引发效率
  问题。确保你的View树层次尽可能浅。


        如果你有的UI设计是复杂地,你应该考虑设计一个自定义ViewGroup来实现layout过程。不同于内置View控件,
  自定义View能够假定它的每个子View的大小以及形状,同时能够避免为每个子View进行measure过程。 PieChart
  展示了如何继承ViewGroup类。 PieChart带有子View,但它从来没有measure它们。相反,它根据自己的布局算法
  去直接设置每个子View的大小。
          
       如下代码所示:

/** 
 * Custom view that shows a pie chart and, optionally, a label. 
 */ 
public class PieChart extends ViewGroup { 
 ... 
 // 
 // Measurement functions. This example uses a simple heuristic: it assumes that 
 // the pie chart should be at least as wide as its label. 
 // 
 @Override 
 protected int getSuggestedMinimumWidth() { 
  return (int) mTextWidth * 2; 
 } 
 @Override 
 protected int getSuggestedMinimumHeight() { 
  return (int) mTextWidth; 
 } 
 
 @Override 
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
  // Try for a width based on our minimum 
  int minw = getPaddingLeft() + getPaddingRight() + getSuggestedMinimumWidth(); 
 
  int w = Math.max(minw, MeasureSpec.getSize(widthMeasureSpec)); 
 
  // Whatever the width ends up being, ask for a height that would let the pie 
  // get as big as it can 
  int minh = (w - (int) mTextWidth) + getPaddingBottom() + getPaddingTop(); 
  int h = Math.min(MeasureSpec.getSize(heightMeasureSpec), minh); 
 
  setMeasuredDimension(w, h); 
 } 
 
 @Override 
 protected void onLayout(boolean changed, int l, int t, int r, int b) { 
  // Do nothing. Do not call the superclass method--that would start a layout pass 
  // on this view's children. PieChart lays out its children in onSizeChanged(). 
 } 
  
 @Override 
 protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
  super.onSizeChanged(w, h, oldw, oldh); 
 
  // 
  // Set dimensions for text, pie chart, etc 
  // 
  // Account for padding 
 
  ... 
 
  // Lay out the child view that actually draws the pie. 
  mPieView.layout((int) mPieBounds.left, 
    (int) mPieBounds.top, 
    (int) mPieBounds.right, 
    (int) mPieBounds.bottom); 
  mPieView.setPivot(mPieBounds.width() / 2, mPieBounds.height() / 2); 
 
  mPointerView.layout(0, 0, w, h); 
  onDataChanged(); 
 } 
 
}