国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android LinearLayout實現自動換行

2019-10-21 21:40:04
字體:
來源:轉載
供稿:網友

由于前段時間項目中使用到了自動換行的線性布局,本來打算用表格布局在里面一個個的用Java代碼添加ImageView的,但是添加的View控件是不確定的,因為得靠服務器的數據返回,就這樣手動用Java代碼畫布局的方式就這樣夭折了,因為在表哥布局中我無法確定一行顯示多少個ImageView的數目,所以無法動態添加,最后自能自己去看看那種能夠換行的線性布局了,線性布局比較不好的是不能自動換行,也就是當設置LinearLayout的orentation 設置為vertical 為豎直方向也就是只有一列,每行只能顯示一個View或者View的子類,當設置LinearLayout的orentitation為Horizontal,LinearLayout的只能顯示為一行,橫向顯示,當屏幕滿了的時候,View控件并不會自動換行,所以我們要做的就是在LinearLayout滿的時候自動換行。

需要了解的是怎么樣繪制根據子控件的長寬繪制父控件的寬度與高度,所以需要傳入的參數控件的高度,視圖分為兩種一種是View類型的,代表控件有TextView,Button,EditText 等等,還有一種是裝視圖的容器控件繼承自ViewGroup的控件,如LinearLayout,RelativeLayout,TabHost等等控件,需要自動換行的線性布局的話,就需要根據子控件的高度與寬度,來動態加載父控件的高度與寬度,所以需要在構造函數中傳入每一個子控件的固定的高度,或者是動態設置子控件的高度與寬度。

將自定義的LinearLayout 也繼承自ViewGroup 并且重寫抽象類ViewGrouop的幾個方法:onMeasure(),onLayout(),dispathDraw()  三個方法的意思分別是:第一個onMeasure()是用來計算控件以及子控件所占用的區域,第二個onLayout()是控制子控件的換行,第三個可寫可不寫,主要是用來繪制控件的邊框,

自定義LinearLayout的代碼如下:

package com.huanglong.mylinearlayout; import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.util.AttributeSet;import android.view.View;import android.view.ViewGroup; /** * @author huanglong 2013-5-28 自定義自動換行LinearLayout */public class FixGridLayout extends ViewGroup { private int mCellWidth; private int mCellHeight;  public FixGridLayout(Context context) {  super(context); }  public FixGridLayout(Context context, AttributeSet attrs) {  super(context, attrs); }  public FixGridLayout(Context context, AttributeSet attrs, int defStyle) {  super(context, attrs, defStyle); }  public void setmCellWidth(int w) {  mCellWidth = w;  requestLayout(); }  public void setmCellHeight(int h) {  mCellHeight = h;  requestLayout(); }  /**  * 控制子控件的換行  */ @Override protected void onLayout(boolean changed, int l, int t, int r, int b) {  int cellWidth = mCellWidth;  int cellHeight = mCellHeight;  int columns = (r - l) / cellWidth;  if (columns < 0) {   columns = 1;  }  int x = 0;  int y = 0;  int i = 0;  int count = getChildCount();  for (int j = 0; j < count; j++) {   final View childView = getChildAt(j);   // 獲取子控件Child的寬高   int w = childView.getMeasuredWidth();   int h = childView.getMeasuredHeight();   // 計算子控件的頂點坐標   int left = x + ((cellWidth - w) / 2);   int top = y + ((cellHeight - h) / 2);   // int left = x;   // int top = y;   // 布局子控件   childView.layout(left, top, left + w, top + h);    if (i >= (columns - 1)) {    i = 0;    x = 0;    y += cellHeight;   } else {    i++;    x += cellWidth;    }  } }  /**  * 計算控件及子控件所占區域  */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  // 創建測量參數  int cellWidthSpec = MeasureSpec.makeMeasureSpec(mCellWidth, MeasureSpec.AT_MOST);  int cellHeightSpec = MeasureSpec.makeMeasureSpec(mCellHeight, MeasureSpec.AT_MOST);  // 記錄ViewGroup中Child的總個數  int count = getChildCount();  // 設置子空間Child的寬高  for (int i = 0; i < count; i++) {   View childView = getChildAt(i);   /*    * 090 This is called to find out how big a view should be. 091 The    * parent supplies constraint information in the width and height    * parameters. 092 The actual mesurement work of a view is performed    * in onMeasure(int, int), 093 called by this method. 094 Therefore,    * only onMeasure(int, int) can and must be overriden by subclasses.    * 095    */   childView.measure(cellWidthSpec, cellHeightSpec);  }  // 設置容器控件所占區域大小  // 注意setMeasuredDimension和resolveSize的用法  setMeasuredDimension(resolveSize(mCellWidth * count, widthMeasureSpec),    resolveSize(mCellHeight * count, heightMeasureSpec));  // setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);   // 不需要調用父類的方法  // super.onMeasure(widthMeasureSpec, heightMeasureSpec); }  /**  * 為控件添加邊框  */ @Override protected void dispatchDraw(Canvas canvas) {  // 獲取布局控件寬高  int width = getWidth();  int height = getHeight();  // 創建畫筆  Paint mPaint = new Paint();  // 設置畫筆的各個屬性  mPaint.setColor(Color.BLUE);  mPaint.setStyle(Paint.Style.STROKE);  mPaint.setStrokeWidth(10);  mPaint.setAntiAlias(true);  // 創建矩形框  Rect mRect = new Rect(0, 0, width, height);  // 繪制邊框  canvas.drawRect(mRect, mPaint);  // 最后必須調用父類的方法  super.dispatchDraw(canvas); } }

然后在Xml文件中引用自己定義的控件,在Java代碼中調用:

package com.huanglong.mylinearlayout; import android.os.Bundle;import android.app.Activity;import android.view.Menu;import android.view.MenuItem;import android.widget.CheckBox;import android.widget.SimpleAdapter;import android.support.v4.app.NavUtils; public class MainActivity extends Activity { private SimpleAdapter adapter; @Override public void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  FixGridLayout fixGridLayout = (FixGridLayout) findViewById(R.id.ll);  fixGridLayout.setmCellHeight(30);  fixGridLayout.setmCellWidth(100);  for (int i = 0; i < 7; i++) {   CheckBox box = new CheckBox(MainActivity.this);   box.setText("第"+i+"個");   fixGridLayout.addView(box);  } }  @Override public boolean onCreateOptionsMenu(Menu menu) {  getMenuInflater().inflate(R.menu.activity_main, menu);  return true; }  }

效果截圖:

Android,LinearLayout,自動換行

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 合山市| 青河县| 淳安县| 株洲市| 利津县| 绥芬河市| 沽源县| 澄迈县| 灵丘县| 资阳市| 长沙县| 阳东县| 开原市| 繁昌县| 资兴市| 拜城县| 隆安县| 武定县| 南川市| 辉县市| 本溪市| 靖边县| 正宁县| 邵东县| 乌拉特前旗| 宜城市| 长泰县| 韩城市| 清水县| 灌云县| 枣阳市| 临澧县| 湛江市| 唐海县| 富民县| 鹰潭市| 苗栗县| 山西省| 微山县| 连州市| 汕头市|