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;iparentWidthSize){
//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;ichildren=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程序设计有所帮助。