最近项目实现下面的图示的效果,本来想用ListvIEw+grIDvIEw实现,但是貌似挺麻烦的于是就用flowlayout 来addvIEw实现添加伸缩的效果,实现也比较简单。
mainActivity 布局
<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:orIEntation="vertical" > <relativeLayout androID:ID="@+ID/rl_category_Title_bar_layout" androID:layout_height="wrap_content" androID:layout_wIDth="match_parent" > <relativeLayout androID:layout_height="50dp" androID:layout_wIDth="match_parent" > <TextVIEw androID:ID="@+ID/tv_category_Title" androID:layout_height="50dp" androID:layout_wIDth="wrap_content" androID:text="分类" androID:textSize="18sp" androID:layout_centerInParent="true" androID:gravity="center" /> </relativeLayout> </relativeLayout> <ListVIEw androID:ID="@+ID/lv_category_menu" androID:layout_height="match_parent" androID:layout_wIDth="match_parent" /></linearLayout>
自定义布局flowlayout
package comskyball.addflowlayout;import androID.content.Context;import androID.content.res.TypedArray;import androID.util.AttributeSet;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import java.util.ArrayList;import java.util.List;public class FlowLayout extends VIEwGroup { private Context mContext; private int usefulWIDth; // the space of a line we can use(line's wIDth minus the sum of left and right padding private int linespacing = 0; // the spacing between lines in flowlayout List<VIEw> childList = new ArrayList(); List<Integer> lineNumList = new ArrayList(); public FlowLayout(Context context) { this(context,null); } public FlowLayout(Context context,AttributeSet attrs) { this(context,attrs,0); } public FlowLayout(Context context,AttributeSet attrs,int defStyleAttr) { super(context,defStyleAttr); mContext = context; TypedArray mTypedArray = context.obtainStyledAttributes(attrs,R.styleable.FlowLayout); linespacing = mTypedArray.getDimensionPixelSize( R.styleable.FlowLayout_linespacing,0); mTypedArray.recycle(); } @OverrIDe protected voID onMeasure(int wIDthMeasureSpec,int heightmeasureSpec) { int mpaddingleft = getpaddingleft(); int mpaddingRight = getpaddingRight(); int mpaddingtop = getpaddingtop(); int mpaddingBottom = getpaddingBottom(); int wIDthSize = MeasureSpec.getSize(wIDthMeasureSpec); int heightmode = MeasureSpec.getMode(heightmeasureSpec); int heightSize = MeasureSpec.getSize(heightmeasureSpec); int lineUsed = mpaddingleft + mpaddingRight; int lineY = mpaddingtop; int lineHeight = 0; for (int i = 0; i < this.getChildCount(); i++) { VIEw child = this.getChildAt(i); if (child.getVisibility() == GONE) { continue; } int spaceWIDth = 0; int spaceHeight = 0; LayoutParams childLp = child.getLayoutParams(); if (childLp instanceof marginLayoutParams) { measureChilDWithmargins(child,wIDthMeasureSpec,heightmeasureSpec,lineY); marginLayoutParams mlp = (marginLayoutParams) childLp; spaceWIDth = mlp.leftmargin + mlp.rightmargin; spaceHeight = mlp.topmargin + mlp.bottommargin; } else { measureChild(child,heightmeasureSpec); } int chilDWIDth = child.getMeasureDWIDth(); int childHeight = child.getMeasuredHeight(); spaceWIDth += chilDWIDth; spaceHeight += childHeight; if (lineUsed + spaceWIDth > wIDthSize) { //approach the limit of wIDth and move to next line lineY += lineHeight + linespacing; lineUsed = mpaddingleft + mpaddingRight; lineHeight = 0; } if (spaceHeight > lineHeight) { lineHeight = spaceHeight; } lineUsed += spaceWIDth; } setMeasuredDimension( wIDthSize,heightmode == MeasureSpec.EXACTLY ? heightSize : lineY + lineHeight + mpaddingBottom ); } @OverrIDe protected voID onLayout(boolean changed,int l,int t,int r,int b) { int mpaddingleft = getpaddingleft(); int mpaddingRight = getpaddingRight(); int mpaddingtop = getpaddingtop(); int lineX = mpaddingleft; int lineY = mpaddingtop; int linewidth = r - l; usefulWIDth = linewidth - mpaddingleft - mpaddingRight; int lineUsed = mpaddingleft + mpaddingRight; int lineHeight = 0; int lineNum = 0; lineNumList.clear(); for (int i = 0; i < this.getChildCount(); i++) { VIEw child = this.getChildAt(i); if (child.getVisibility() == GONE) { continue; } int spaceWIDth = 0; int spaceHeight = 0; int left = 0; int top = 0; int right = 0; int bottom = 0; int chilDWIDth = child.getMeasureDWIDth(); int childHeight = child.getMeasuredHeight(); LayoutParams childLp = child.getLayoutParams(); if (childLp instanceof marginLayoutParams) { marginLayoutParams mlp = (marginLayoutParams) childLp; spaceWIDth = mlp.leftmargin + mlp.rightmargin; spaceHeight = mlp.topmargin + mlp.bottommargin; left = lineX + mlp.leftmargin; top = lineY + mlp.topmargin; right = lineX + mlp.leftmargin + chilDWIDth; bottom = lineY + mlp.topmargin + childHeight; } else { left = lineX; top = lineY; right = lineX + chilDWIDth; bottom = lineY + childHeight; } spaceWIDth += chilDWIDth; spaceHeight += childHeight; if (lineUsed + spaceWIDth > linewidth) { //approach the limit of wIDth and move to next line lineNumList.add(lineNum); lineY += lineHeight + linespacing; lineUsed = mpaddingleft + mpaddingRight; lineX = mpaddingleft; lineHeight = 0; lineNum = 0; if (childLp instanceof marginLayoutParams) { marginLayoutParams mlp = (marginLayoutParams) childLp; left = lineX + mlp.leftmargin; top = lineY + mlp.topmargin; right = lineX + mlp.leftmargin + chilDWIDth; bottom = lineY + mlp.topmargin + childHeight; } else { left = lineX; top = lineY; right = lineX + chilDWIDth; bottom = lineY + childHeight; } } child.layout(left,top,right,bottom); lineNum ++; if (spaceHeight > lineHeight) { lineHeight = spaceHeight; } lineUsed += spaceWIDth; lineX += spaceWIDth; } // add the num of last line lineNumList.add(lineNum); } /** * resort child elements to use lines as few as possible */ public voID relayoutToCompress() { int childCount = this.getChildCount(); if (0 == childCount) { //no need to sort if flowlayout has no child vIEw return; } int count = 0; for (int i = 0; i < childCount; i++) { VIEw v = getChildAt(i); if (v instanceof BlankVIEw) { //BlankVIEw is just to make childs look in alignment,we should ignore them when we relayout continue; } count++; } VIEw[] childs = new VIEw[count]; int[] spaces = new int[count]; int n = 0; for (int i = 0; i < childCount; i++) { VIEw v = getChildAt(i); if (v instanceof BlankVIEw) { //BlankVIEw is just to make childs look in alignment,we should ignore them when we relayout continue; } childs[n] = v; LayoutParams childLp = v.getLayoutParams(); int chilDWIDth = v.getMeasureDWIDth(); if (childLp instanceof marginLayoutParams) { marginLayoutParams mlp = (marginLayoutParams) childLp ; spaces[n] = mlp.leftmargin + chilDWIDth + mlp.rightmargin; } else { spaces[n] = chilDWIDth; } n++; } int[] compressspaces = new int[count]; for (int i = 0; i < count; i++) { compressspaces[i] = spaces[i] > usefulWIDth ? usefulWIDth : spaces[i]; } sortToCompress(childs,compressspaces); this.removeAllVIEws(); for (VIEw v : childList) { this.addVIEw(v); } childList.clear(); } private voID sortToCompress(VIEw[] childs,int[] spaces) { int childCount = childs.length; int[][] table = new int[childCount + 1][usefulWIDth + 1]; for (int i = 0; i < childCount +1; i++) { for (int j = 0; j < usefulWIDth; j++) { table[i][j] = 0; } } boolean[] flag = new boolean[childCount]; for (int i = 0; i < childCount; i++) { flag[i] = false; } for (int i = 1; i <= childCount; i++) { for (int j = spaces[i-1]; j <= usefulWIDth; j++) { table[i][j] = (table[i-1][j] > table[i-1][j-spaces[i-1]] + spaces[i-1]) ? table[i-1][j] : table[i-1][j-spaces[i-1]] + spaces[i-1]; } } int v = usefulWIDth; for (int i = childCount ; i > 0 && v >= spaces[i-1]; i--) { if (table[i][v] == table[i-1][v-spaces[i-1]] + spaces[i-1]) { flag[i-1] = true; v = v - spaces[i - 1]; } } int rest = childCount; VIEw[] restArray; int[] restSpaces; for (int i = 0; i < flag.length; i++) { if (flag[i] == true) { childList.add(childs[i]); rest--; } } if (0 == rest) { return; } restArray = new VIEw[rest]; restSpaces = new int[rest]; int index = 0; for (int i = 0; i < flag.length; i++) { if (flag[i] == false) { restArray[index] = childs[i]; restSpaces[index] = spaces[i]; index++; } } table = null; childs = null; flag = null; sortToCompress(restArray,restSpaces); } /** * add some blank vIEw to make child elements look in alignment */ public voID relayoutToAlign() { int childCount = this.getChildCount(); if (0 == childCount) { //no need to sort if flowlayout has no child vIEw return; } int count = 0; for (int i = 0; i < childCount; i++) { VIEw v = getChildAt(i); if (v instanceof BlankVIEw) { //BlankVIEw is just to make childs look in alignment,we should ignore them when we relayout continue; } childs[n] = v; LayoutParams childLp = v.getLayoutParams(); int chilDWIDth = v.getMeasureDWIDth(); if (childLp instanceof marginLayoutParams) { marginLayoutParams mlp = (marginLayoutParams) childLp ; spaces[n] = mlp.leftmargin + chilDWIDth + mlp.rightmargin; } else { spaces[n] = chilDWIDth; } n++; } int linetotal = 0; int start = 0; this.removeAllVIEws(); for (int i = 0; i < count; i++) { if (linetotal + spaces[i] > usefulWIDth) { int blankWIDth = usefulWIDth - linetotal; int end = i - 1; int blankCount = end - start; if (blankCount >= 0) { if (blankCount > 0) { int eachBlankWIDth = blankWIDth / blankCount; marginLayoutParams lp = new marginLayoutParams(eachBlankWIDth,0); for (int j = start; j < end; j++) { this.addVIEw(childs[j]); BlankVIEw blank = new BlankVIEw(mContext); this.addVIEw(blank,lp); } } this.addVIEw(childs[end]); start = i; i --; linetotal = 0; } else { this.addVIEw(childs[i]); start = i + 1; linetotal = 0; } } else { linetotal += spaces[i]; } } for (int i = start; i < count; i++) { this.addVIEw(childs[i]); } } /** * use both of relayout methods together */ public voID relayoutToCompressAndalign(){ this.relayoutToCompress(); this.relayoutToAlign(); } /** * cut the flowlayout to the specifIEd num of lines * @param line_num */ public voID specifylines(int line_num) { int childNum = 0; if (line_num > lineNumList.size()) { line_num = lineNumList.size(); } for (int i = 0; i < line_num; i++) { childNum += lineNumList.get(i); } List<VIEw> vIEwList = new ArrayList<VIEw>(); for (int i = 0; i < childNum; i++) { vIEwList.add(getChildAt(i)); } removeAllVIEws(); for (VIEw v : vIEwList) { addVIEw(v); } } @OverrIDe protected LayoutParams generateLayoutParams(LayoutParams p) { return new marginLayoutParams(p); } @OverrIDe public LayoutParams generateLayoutParams(AttributeSet attrs) { return new marginLayoutParams(getContext(),attrs); } @OverrIDe protected LayoutParams generateDefaultLayoutParams() { return new marginLayoutParams(super.generateDefaultLayoutParams()); } class BlankVIEw extends VIEw { public BlankVIEw(Context context) { super(context); } }}
adapter
package comskyball.addflowlayout;import java.util.ArrayList;import androID.content.Context;import androID.os.Handler;import androID.os.Message;import androID.util.Log;import androID.vIEw.VIEw;import androID.vIEw.VIEw.OnClickListener;import androID.vIEw.VIEwGroup;import androID.Widget.BaseAdapter;import androID.Widget.ImageVIEw;import androID.Widget.linearLayout;import androID.Widget.TextVIEw;import androID.Widget.Toast;public class categoryLvAdapter extends BaseAdapter { public Context context; public ArrayList<category> List; public boolean isMore=true; public categoryLvAdapter(Context context,ArrayList<category> List) { this.context=context; this.List=List; } @OverrIDe public int getCount() { return List.size(); } @OverrIDe public Object getItem(int position) { return 0; } @OverrIDe public long getItemID(int position) { return 0; } @OverrIDe public VIEw getVIEw(final int position,VIEw convertVIEw,VIEwGroup parent) { VIEwHolder vIEwHolder=null; if(convertVIEw==null){ convertVIEw=VIEw.inflate(context,R.layout.lv_category_item,null); vIEwHolder=new VIEwHolder(); vIEwHolder.iv_lv_category_img=(ImageVIEw) convertVIEw.findVIEwByID(R.ID.iv_lv_category_img); vIEwHolder.tv_lv_category=(TextVIEw) convertVIEw.findVIEwByID(R.ID.tv_lv_category); vIEwHolder.flow_layout_lv_category=(FlowLayout) convertVIEw.findVIEwByID(R.ID.flow_layout_lv_category); vIEwHolder.ll_lv_category_add=(linearLayout) convertVIEw.findVIEwByID(R.ID.ll_lv_category_add); vIEwHolder.iv_lv_category_arrow=(ImageVIEw) convertVIEw.findVIEwByID(R.ID.iv_lv_category_arrow); convertVIEw.setTag(vIEwHolder); }else{ vIEwHolder=(VIEwHolder) convertVIEw.getTag(); }// ImageLoader.getInstance().displayImage(AppConfig.APP_URL+List.get(position).getimg(),vIEwHolder.iv_lv_category_img,App.normalOption); vIEwHolder.tv_lv_category.setText(List.get(position).getCate_name()); vIEwHolder.iv_lv_category_arrow.setBackgroundResource(R.drawable.arrow_down); vIEwHolder.flow_layout_lv_category.removeAllVIEws(); Utils.addflow(context,6,List.get(position).getNext(),vIEwHolder.flow_layout_lv_category); final FlowLayout flowLayoutLvcategory = vIEwHolder.flow_layout_lv_category; final ImageVIEw ivLvcategoryArrow = vIEwHolder.iv_lv_category_arrow; vIEwHolder.ll_lv_category_add.setonClickListener(new OnClickListener() { @OverrIDe public voID onClick(VIEw v) { if(isMore){ isMore=false; flowLayoutLvcategory.removeAllVIEws(); Utils.addflow(context,List.get(position).getNext().size(),flowLayoutLvcategory); ivLvcategoryArrow.setBackgroundResource(R.drawable.arrow_up); }else{ isMore=true; flowLayoutLvcategory.removeAllVIEws(); Utils.addflow(context,flowLayoutLvcategory); ivLvcategoryArrow.setBackgroundResource(R.drawable.arrow_down); } } }); return convertVIEw; } public class VIEwHolder{ public ImageVIEw iv_lv_category_img; public TextVIEw tv_lv_category; public FlowLayout flow_layout_lv_category; public linearLayout ll_lv_category_add; public ImageVIEw iv_lv_category_arrow; }}
adapter item布局
<?xml version="1.0" enCoding="utf-8"?><relativeLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" xmlns:app="http://schemas.androID.com/apk/res-auto" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" > <linearLayout androID:layout_height="wrap_content" androID:layout_wIDth="match_parent" androID:orIEntation="vertical" > <relativeLayout androID:layout_height="35dp" androID:layout_wIDth="match_parent" > <ImageVIEw androID:ID="@+ID/iv_lv_category_img" /> <TextVIEw androID:ID="@+ID/tv_lv_category" androID:text="衣食" androID:layout_toRightOf="@ID/iv_lv_category_img" /> </relativeLayout> <VIEw /> <ScrollVIEw androID:layout_wIDth="match_parent" androID:layout_height="match_parent" > <relativeLayout androID:layout_height="match_parent" androID:layout_wIDth="match_parent" > <comskyball.addflowlayout.FlowLayout androID:ID="@+ID/flow_layout_lv_category" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" app:linespacing="10dp" app:maxline="3" androID:background="#F0F0F0" androID:layout_margintop="5dp" /> <linearLayout androID:ID="@+ID/ll_lv_category_add" androID:layout_height="35dp" androID:layout_below="@ID/flow_layout_lv_category" > <ImageVIEw androID:ID="@+ID/iv_lv_category_arrow" androID:background="@drawable/arrow_down" /> <VIEw /> </linearLayout> </relativeLayout> </ScrollVIEw> </linearLayout></relativeLayout>
以上所述是小编给大家介绍的AndroID 实现伸缩布局效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程小技巧网站的支持!
总结以上是内存溢出为你收集整理的Android 实现伸缩布局效果示例代码全部内容,希望文章能够帮你解决Android 实现伸缩布局效果示例代码所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)