Android之ACRA 和自定义布局

ACRA : Application crash report for android

  1. 作用: 为自己的应用找bug
  2. 使用步骤:参考文档

自定义布局的实现:流程图

参照流程图:当有孩子时,是否需要对孩子控件大小进行布置,如果需要就得重写onMeasure()这个方法调用child.layout()方法。需要孩子控件布局进行控制也要重写onLayout()方法,需要对控件的显示进行控制时要重写onDraw()方法。

一般实现全部构造函数。

重写

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
    //临时top
    int topmt=0;
    int parentWidth = getMeasuredWidth();
    
    //获得孩子个数
    int count =getChildCount();
    for(int i=0;i

还需要重写onMeasure()

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
    //获得父亲的宽高
    int widthsize=MeasureSpec.getSize(widthMeasureSpec);
    int heightsize=MeasureSpec.getSize(heightMeasureSpec);
    
    measureChildren(0, 0);//设置孩子,为0由父亲安排宽高
    
    setMeasuredDimension(widthsize, heightsize);
}

自定义布局的使用:


    
    
        
     
        
     
        
    
        
      

如果需要切换布局,一般定义一个boolean类型值进行切换

FlowLayout

  1. 分析:
    1. 多行摆放
    2. 单行如果摆不下去,换行摆放

看下效果图:

一下子看到这种布局说真的我无从下手,不知道这个怎么实现,每行个数不一样,列数不一样,后来知道自定义布局可以实现。根据上面的view实现的流程图可以知道,需要对控件的布局、大小进行控制,所以需要重写onLayout()、onMeasure()的方法。再重写方法之前,需要先分析每一行是怎么布局的,以面向对象的思想封装每一行需要的属性、和方法。如下:

行的类

    class Line{
        //存储孩子
        private List mChildViews=new LinkedList();
        
        private int usedWidth;//已经使用过的宽度
        private int lineHeight;//行最大的高度
        
        private int maxWidth;//行最大的宽度,父类给的
        private int horizontalSpace;//中间的间隔
        
        public Line(int maxWidth,int horizontalSpace){
            this.maxWidth=maxWidth;
            this.horizontalSpace=horizontalSpace;
        }
    //判断该行是否能添加view
        public boolean canAddView(View view){
            //如果使用的宽度+准备加的View的宽度+中间的间隔>最大的宽度,加不上去
            
            //准备加的View的宽度
            int childwidth=view.getMeasuredWidth();
            
            int size=mChildViews.size();
            if(size==0){
                return true;
            }else if(usedWidth+childwidth+horizontalSpace>maxWidth){
                return false;
            }
            return true;
        }
    //添加view到布局
        public void addView(View view){
            //
            int childWidth=view.getMeasuredWidth();
            int childHeight=view.getMeasuredHeight();
            int size=mChildViews.size();
            
            if(size==0){
                //没有孩子      已经使用的宽度
                if(childWidth>maxWidth){
                    usedWidth=maxWidth;
                }else{
                    usedWidth=childWidth;
                }
                //高度
                lineHeight=childHeight;
                
            }else{
                //已经使用的宽度
                usedWidth=usedWidth+childWidth+horizontalSpace;
                
                //高度
                lineHeight=lineHeight>childHeight?lineHeight:childHeight;
            }
            //加孩子
            mChildViews.add(view);
        }

//给行布局

        public void layout(int left,int top)
        {
            //给孩子布局
            int size=mChildViews.size();
            
            int tmpLeft=0;
            
            //将每一行右侧无法显示的空白部分平分给每一行显示的每个控件
            int extraWidth=(int) ((maxWidth-usedWidth)*1f/size+0.5f);
            
            for(int i=0;i0){
                    //希望孩子再宽点,填充右侧空白
                    int widthMeasureSpec=MeasureSpec.makeMeasureSpec(childWidth+extraWidth, MeasureSpec.EXACTLY);
                    int heightMeasureSpec=MeasureSpec.makeMeasureSpec(childHeight,MeasureSpec.EXACTLY);
                    child.measure(widthMeasureSpec, heightMeasureSpec);
                    
                    //重新获得宽高
                     childWidth=child.getMeasuredWidth();
                     childHeight=child.getMeasuredHeight();
                }
                
                int extraHeight=(int) ((lineHeight-childHeight)/2f+0.5f);
                
                int l=left+tmpLeft;
                int t=top+extraHeight;
                int r=l+childWidth;
                int b=t+childHeight;
                child.layout(l, t, r, b);
                
                //添加记录
                tmpLeft +=childWidth + horizontalSpace;
            }
            
        }
}

重写onLayout()方法:

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
    int left=getPaddingLeft();
    int top=getPaddingTop();
    
    //让行进行布局
    for(int i=0;i

重写onMeasure()方法

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
    //孩子个数记录清空
    mLines.clear();
    mCurrentLine=null;
    
    int widthSize=MeasureSpec.getSize(widthMeasureSpec);
    int lineMaxWidth=widthSize-getPaddingLeft()-getPaddingRight();
    
    //测量孩子完成时,就记录到行里面
    int count=getChildCount();
    for(int i=0;i

在MainActivity中:

public class MainActivity extends Activity {

    private FlowLayout layout;
    
    private String []mDatas={"单机游戏","美女","游戏","单机游戏","美女","淘宝","单机游戏","美女","淘宝","游戏" ,"单机游戏","淘宝","游戏","单机游戏","美女","淘宝","游戏","单机游戏","美女","淘宝","游戏" ,"有道","天猫","汽车商城","新闻","运动","熊出没之大逃跑"};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        layout=(FlowLayout) findViewById(R.id.flow_layout);
        layout.setPadding(10, 10, 10, 10);
        initData();
    }
    private void initData()
    {
        for(int i=0;i

使用自定义布局时:



    


到这里,上图的效果就已经出来,这种布局的逻辑判断有点繁琐,稍有差错就显示不出来了。记得要多看。

你可能感兴趣的:(Android之ACRA 和自定义布局)