Android LinearLayout實(shí)現(xiàn)自動(dòng)換行
由于前段時(shí)間項(xiàng)目中使用到了自動(dòng)換行的線性布局,本來打算用表格布局在里面一個(gè)個(gè)的用Java代碼添加ImageView的,但是添加的View控件是不確定的,因?yàn)榈每糠?wù)器的數(shù)據(jù)返回,就這樣手動(dòng)用Java代碼畫布局的方式就這樣夭折了,因?yàn)樵诒砀绮季种形覠o法確定一行顯示多少個(gè)ImageView的數(shù)目,所以無法動(dòng)態(tài)添加,最后自能自己去看看那種能夠換行的線性布局了,線性布局比較不好的是不能自動(dòng)換行,也就是當(dāng)設(shè)置LinearLayout的orentation 設(shè)置為vertical 為豎直方向也就是只有一列,每行只能顯示一個(gè)View或者View的子類,當(dāng)設(shè)置LinearLayout的orentitation為Horizontal,LinearLayout的只能顯示為一行,橫向顯示,當(dāng)屏幕滿了的時(shí)候,View控件并不會(huì)自動(dòng)換行,所以我們要做的就是在LinearLayout滿的時(shí)候自動(dòng)換行。
需要了解的是怎么樣繪制根據(jù)子控件的長寬繪制父控件的寬度與高度,所以需要傳入的參數(shù)控件的高度,視圖分為兩種一種是View類型的,代表控件有TextView,Button,EditText 等等,還有一種是裝視圖的容器控件繼承自ViewGroup的控件,如LinearLayout,RelativeLayout,TabHost等等控件,需要自動(dòng)換行的線性布局的話,就需要根據(jù)子控件的高度與寬度,來動(dòng)態(tài)加載父控件的高度與寬度,所以需要在構(gòu)造函數(shù)中傳入每一個(gè)子控件的固定的高度,或者是動(dòng)態(tài)設(shè)置子控件的高度與寬度。
將自定義的LinearLayout 也繼承自ViewGroup 并且重寫抽象類ViewGrouop的幾個(gè)方法:onMeasure(),onLayout(),dispathDraw() 三個(gè)方法的意思分別是:第一個(gè)onMeasure()是用來計(jì)算控件以及子控件所占用的區(qū)域,第二個(gè)onLayout()是控制子控件的換行,第三個(gè)可寫可不寫,主要是用來繪制控件的邊框,
自定義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 自定義自動(dòng)換行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(); // 計(jì)算子控件的頂點(diǎn)坐標(biāo) 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; } } } /** * 計(jì)算控件及子控件所占區(qū)域 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // 創(chuàng)建測量參數(shù) int cellWidthSpec = MeasureSpec.makeMeasureSpec(mCellWidth, MeasureSpec.AT_MOST); int cellHeightSpec = MeasureSpec.makeMeasureSpec(mCellHeight, MeasureSpec.AT_MOST); // 記錄ViewGroup中Child的總個(gè)數(shù) int count = getChildCount(); // 設(shè)置子空間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); } // 設(shè)置容器控件所占區(qū)域大小 // 注意setMeasuredDimension和resolveSize的用法 setMeasuredDimension(resolveSize(mCellWidth * count, widthMeasureSpec), resolveSize(mCellHeight * count, heightMeasureSpec)); // setMeasuredDimension(widthMeasureSpec, heightMeasureSpec); // 不需要調(diào)用父類的方法 // super.onMeasure(widthMeasureSpec, heightMeasureSpec); } /** * 為控件添加邊框 */ @Override protected void dispatchDraw(Canvas canvas) { // 獲取布局控件寬高 int width = getWidth(); int height = getHeight(); // 創(chuàng)建畫筆 Paint mPaint = new Paint(); // 設(shè)置畫筆的各個(gè)屬性 mPaint.setColor(Color.BLUE); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(10); mPaint.setAntiAlias(true); // 創(chuàng)建矩形框 Rect mRect = new Rect(0, 0, width, height); // 繪制邊框 canvas.drawRect(mRect, mPaint); // 最后必須調(diào)用父類的方法 super.dispatchDraw(canvas); } }
然后在Xml文件中引用自己定義的控件,在Java代碼中調(diào)用:
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+"個(gè)"); fixGridLayout.addView(box); } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } }
效果截圖:
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android實(shí)現(xiàn)控件的縮放移動(dòng)功能
這篇文章主要介紹了android控件的縮放,移動(dòng)功能,本文圖文并茂給大家介紹的非常詳細(xì),需要的朋友可以參考下2018-01-01Android App開發(fā)中將View或Drawable轉(zhuǎn)為Bitmap的方法
這篇文章主要介紹了Android App開發(fā)中將View或Drawable轉(zhuǎn)為Bitmap的方法,其中View轉(zhuǎn)換時(shí)作者特別提到了getDrawingCache=null問題的解決方法,需要的朋友可以參考下2016-03-03Android抓取CSDN首頁極客頭條內(nèi)容完整實(shí)例
這篇文章主要介紹了Android抓取CSDN首頁極客頭條內(nèi)容完整實(shí)例,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01Android設(shè)置TextView顯示指定個(gè)數(shù)字符,超過部分顯示...(省略號)的方法
這篇文章主要介紹了Android設(shè)置TextView顯示指定個(gè)數(shù)字符,超過部分顯示...(省略號)的方法,涉及Android TextView屬性設(shè)置的相關(guān)技巧,需要的朋友可以參考下2016-02-02Android實(shí)現(xiàn)自定義Crash handler記錄崩潰信息實(shí)例代碼
這篇文章主要給大家介紹了Android實(shí)現(xiàn)自定義Crash handler記錄崩潰信息的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-02-02ExpandListView實(shí)現(xiàn)下拉列表案例
這篇文章主要為大家詳細(xì)介紹了ExpandListView實(shí)現(xiàn)下拉列表案例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08在RecyclerView中實(shí)現(xiàn)button的跳轉(zhuǎn)功能
本次實(shí)驗(yàn)就是在RecyclerView中添加一個(gè)button控件并實(shí)現(xiàn)監(jiān)聽,使鼠標(biāo)點(diǎn)擊時(shí)可以跳轉(zhuǎn)到另外一個(gè)設(shè)計(jì)好的界面,對RecyclerView實(shí)現(xiàn)button跳轉(zhuǎn)功能感興趣的朋友一起看看吧2021-10-10