編輯:關於Android編程
參照流程圖:當有孩子時,是否需要對孩子控件大小進行布置,如果需要就得重寫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<count;i++){ 2="=0){" bottom="top+childHidth;" child="getChildAt(i);" childhidth="child.getMeasuredHeight();" childwidth="child.getMeasuredWidth();" int="" left="parentWidth-childWidth;" pre="" right="left+childWidth;" top="topmt;" view="">
還需要重寫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類型值進行切換
看下效果圖:
一下子看到這種布局說真的我無從下手,不知道這個怎麼實現,每行個數不一樣,列數不一樣,後來知道自定義布局可以實現。根據上面的view實現的流程圖可以知道,需要對控件的布局、大小進行控制,所以需要重寫onLayout()、onMeasure()的方法。再重寫方法之前,需要先分析每一行是怎麼布局的,以面向對象的思想封裝每一行需要的屬性、和方法。如下:
class Line{ //存儲孩子 private ListmChildViews=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;i 0){ //希望孩子再寬點,填充右側空白 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; } } }
@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<mdatas.length;i++){ pre="" textview="" tv="new">
使用自定義布局時:
到這裡,上圖的效果就已經出來,這種布局的邏輯判斷有點繁瑣,稍有差錯就顯示不出來了。記得要多看。
Android 5.0(21)之後,android.hardware.Camera被廢棄(下面稱為Camera1),還有一個android.graphics.Camera
前言在一些APP中我們可以看到一些存放標簽的容器控件,和我們平時使用的一些布局方式有些不同,它們一般都可以自動適應屏幕的寬度進行布局,根據對自定義控件的一些理解,今天寫一
1 Content Provider組件簡介Content Provider組件是Android應用的重要組件之一,管理對數據的訪問,主要用於不同的應用程序之間實現數據共
1,講解build.gradle文件。1.1根目錄Android1.1.1defaultConfig是Android的根目錄,可以配置包名等信息,若AndroidMain