由于前段時間項(xiàng)目中使用到了自動換行的線性布局,本來打算用表格布局在里面一個個的用Java代碼添加ImageView的,但是添加的View控件是不確定的,因?yàn)榈每?a title="服務(wù)器" target="_blank" >服務(wù)器的數(shù)據(jù)返回,就這樣手動用Java代碼畫布局的方式就這樣夭折了,因?yàn)樵诒砀绮季种形覠o法確定一行顯示多少個ImageView的數(shù)目,所以無法動態(tài)添加,最后自能自己去看看那種能夠換行的線性布局了,線性布局比較不好的是不能自動換行,也就是當(dāng)設(shè)置LinearLayout的orentation 設(shè)置為vertical 為豎直方向也就是只有一列,每行只能顯示一個View或者View的子類,當(dāng)設(shè)置LinearLayout的orentitation為Horizontal,LinearLayout的只能顯示為一行,橫向顯示,當(dāng)屏幕滿了的時候,View控件并不會自動換行,所以我們要做的就是在LinearLayout滿的時候自動換行。
站在用戶的角度思考問題,與客戶深入溝通,找到魏縣網(wǎng)站設(shè)計(jì)與魏縣網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗(yàn)好的作品,建站類型包括:成都網(wǎng)站建設(shè)、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、主機(jī)域名、網(wǎng)絡(luò)空間、企業(yè)郵箱。業(yè)務(wù)覆蓋魏縣地區(qū)。
需要了解的是怎么樣繪制根據(jù)子控件的長寬繪制父控件的寬度與高度,所以需要傳入的參數(shù)控件的高度,視圖分為兩種一種是View類型的,代表控件有TextView,Button,EditText 等等,還有一種是裝視圖的容器控件繼承自ViewGroup的控件,如LinearLayout,RelativeLayout,TabHost等等控件,需要自動換行的線性布局的話,就需要根據(jù)子控件的高度與寬度,來動態(tài)加載父控件的高度與寬度,所以需要在構(gòu)造函數(shù)中傳入每一個子控件的固定的高度,或者是動態(tài)設(shè)置子控件的高度與寬度。
將自定義的LinearLayout 也繼承自ViewGroup 并且重寫抽象類ViewGrouop的幾個方法:onMeasure(),onLayout(),dispathDraw() 三個方法的意思分別是:第一個onMeasure()是用來計(jì)算控件以及子控件所占用的區(qū)域,第二個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(); // 計(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的總個數(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è)置畫筆的各個屬性 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+"個"); fixGridLayout.addView(box); } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } }
效果截圖:
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
名稱欄目:AndroidLinearLayout實(shí)現(xiàn)自動換行
本文網(wǎng)址:http://muchs.cn/article30/jchppo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、App設(shè)計(jì)、小程序開發(fā)、做網(wǎng)站、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)