Android开发之瀑布流控件的实现与使用方法示例
本文实例讲述了Android开发之瀑布流控件的实现与使用方法。分享给大家供大家参考,具体如下:
publicclassFlowLayoutextendsViewGroup{ /**行里子view之间的行距离*/ publicintmHorizontolSpace=Util.getDimen(R.dimen.top_padding); /**行里子view之间的垂直距离*/ publicintmVerticalSpace=Util.getDimen(R.dimen.top_padding); /**创建行的集合*/ privateListmLines=newArrayList (); /**当前行*/ privateLinemCurrentLine; /**当前行使用的宽度*/ privateintmCurrentUseWidth=0; /**父容器的宽高*/ privateintparentWidthSize; privateintparentHeightSize; publicFlowLayout(Contextcontext,AttributeSetattrs,intdefStyleAttr){ super(context,attrs,defStyleAttr); } publicFlowLayout(Contextcontext,AttributeSetattrs){ super(context,attrs); } publicFlowLayout(Contextcontext){ super(context); } @Override protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){ //0.先清空行集合里的数据 clear(); //1.得到父viewGroup的模式与大小 intparentWidthMode=MeasureSpec.getMode(widthMeasureSpec);// parentWidthSize=MeasureSpec.getSize(widthMeasureSpec)-getPaddingLeft()-getPaddingRight(); intparentHeightMode=MeasureSpec.getMode(heightMeasureSpec); parentHeightSize=MeasureSpec.getSize(heightMeasureSpec)-getPaddingBottom()-getPaddingTop(); /*每个子view都是包裹内容 *layout.addView(mTextView,newLinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT *得到每个孩子的测量规则 */ //2.得到每个孩子的模式 intchildWidthMode=parentWidthMode==MeasureSpec.EXACTLY?MeasureSpec.EXACTLY:parentWidthMode; intchildHeightMode=parentHeightMode==MeasureSpec.EXACTLY?MeasureSpec.EXACTLY:parentHeightMode; //3.根据模式得到子控件的大小 intchildWidthMeasureSpec=MeasureSpec.makeMeasureSpec(childWidthMode,parentWidthSize); intchildHeightMeasureSpec=MeasureSpec.makeMeasureSpec(childHeightMode,parentHeightSize); //得到子view的个数 intcount=getChildCount(); //创建新的行 mCurrentLine=newLine(); for(inti=0;i parentWidthSize){ //8.如果当前的子view的宽度大于父容器的宽度,强行把这个view添加的集合里 if(mCurrentLine.getChildCount()<1){ mLines.add(mCurrentLine); } //9.换行 newLine(); }else{ //8.把当前子view添加到行里 mCurrentLine.addChild(childView); //9.添加间隔 mCurrentUseWidth+=mHorizontolSpace; if(mCurrentUseWidth>parentWidthSize){ //10.换行 newLine(); } } } //11.如果集合里没有添加当前行,则把当前添加到集合 if(!mLines.contains(mCurrentLine)){ mLines.add(mCurrentLine); } //12.设置富容器的总宽高 intparentWidth=parentWidthSize+getPaddingLeft()+getPaddingRight(); intparentHeight=(mLines.size()-1)*mVerticalSpace+getPaddingBottom()+getPaddingTop(); for(Lineline:mLines){ //得到所以line的高度 parentHeight+=line.getHeight(); } //13.resolveSize表示哪个高度合适,就用哪个 setMeasuredDimension(parentWidth,resolveSize(parentHeightSize,parentHeight)); /*setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec), getDefaultSize(getSuggestedMinimumHeight(),heightMeasureSpec));*/ } /** *换行 */ privatevoidnewLine(){ //a.先把当前的行添加到集合 mLines.add(mCurrentLine); //b.创建新的一行 mCurrentLine=newLine(); //c.新行里的使用的行必须设置为0 mCurrentUseWidth=0; } publicvoidclear(){ mLines.clear(); mCurrentLine=null; mCurrentUseWidth=0; } @Override protectedvoidonLayout(booleanchanged,intl,intt,intr,intb){ //15.得到每个line孩子的左上角的坐标 intleft=l+getPaddingLeft(); inttop=t+getPaddingTop(); //现在容器里只有line是子孩子 for(inti=0;i children=newArrayList (); publicvoidaddChild(ViewchildView){ children.add(childView); //取得之view里最高的高度 if(childView.getMeasuredHeight()>mHeight){ mHeight=childView.getMeasuredHeight(); } //18.得到行宽度 mWidth+=childView.getMeasuredWidth(); } /** *定位每个line在富容器里的额位置 *@paramleft *@paramtop */ publicvoidlayout(intleft,inttop){ //18.得到行宽度 mWidth+=mHorizontolSpace*(children.size()-1); //19.得到剩余的宽度大小 //intpadding=getMeasuredWidth()-mWidth; intpadding=parentWidthSize-mWidth; if(padding>0){ mChildPdding=padding/children.size(); } //getWidth()view显示的时候大小,如果view没显示,这个值就为0,步包括隐藏的部分,getMeasuredWidth()控件实际大小,包括隐藏的部分 //一般来说getMeasuredWidth()>getWidth(); for(inti=0;i 使用方法:
publicclassTopFragmentextendsFragment{ @Override publicViewonCreateView(LayoutInflaterinflater,ViewGroupcontainer,BundlesavedInstanceState){ ScrollViewscrollView=newScrollView(getActivity()); FlowLayoutlayout=newFlowLayout(getActivity()); layout.setBackgroundDrawable(Util.getDrawable(R.drawable.list_item_bg)); intpadding=Util.getDimen(R.dimen.top_padding); layout.setPadding(padding,padding,padding,padding); GradientDrawablepressDrawable=DrawableUtil.createDrawable(0xffcecece); for(inti=0;i工具类:
publicclassDrawableUtil{ /** *创建随机背景的drawable *@return */ publicstaticGradientDrawablecreateRandomDrawable(){ GradientDrawabledrawable=newGradientDrawable(); drawable.setCornerRadius(Util.px2dip(5)); Randomrandom=newRandom(); intred=random.nextInt(200)+20; intgreen=random.nextInt(200)+20; intblue=random.nextInt(200)+20; intcolor=Color.rgb(red,green,blue); drawable.setColor(color); returndrawable; } /** *创建带有背景的drawable *@return */ publicstaticGradientDrawablecreateDrawable(intcolor){ GradientDrawabledrawable=newGradientDrawable(); drawable.setCornerRadius(Util.px2dip(5)); drawable.setColor(color); returndrawable; } /** *状态选择器 *@parampress *@paramnormal *@return */ publicstaticStateListDrawablecreateStateDrawable(Drawablepress,Drawablenormal){ StateListDrawabledrawable=newStateListDrawable(); //按下 drawable.addState(newint[]{android.R.attr.state_pressed},press); //正常 drawable.addState(newint[]{},normal); returndrawable; } }更多关于Android相关内容感兴趣的读者可查看本站专题:《Android窗口相关操作技巧总结》、《Android开发入门与进阶教程》、《Android调试技巧与常见问题解决方法汇总》、《Android基本组件用法总结》、《Android视图View技巧总结》、《Android布局layout技巧总结》及《Android控件用法总结》
希望本文所述对大家Android程序设计有所帮助。