热门标签之流式布局
来源:互联网 发布:python update mysql 编辑:程序博客网 时间:2024/05/01 18:44
说到流式布局第一时间想起的就是RecyclerView,但是在很多很多种情况下,并不适用于用它。因为RecyclerView是一个带滚动的view,而当我们需要多个RecyclerView在一个界面上拼接一起滑动的时候,也就是说可能会遇到ScrollView嵌套RecyclerView的情况下,这个时候无论是改写RecyclerView的LayoutParams还是重写RecyclervView的滑动事件都不是一个好主意,因为RecyclerView是一个布局复用的控件,改写了这些东西意味着你将不能再使用复用模式而导致内耗加大,当item不可见时,内存不会回收,从而造成OOM的风险。
所以使用新的方式替代RecyclerView是我们目前唯一的选择,新的选择和RecyclerView的最大区别在于是否有滑动事件,也就是说,它不是一个AbsListView,也没有滑动事件。它是一个ViewGroup,这个GroupView像LinearLayout、RadioGroup一样是一个可以装载子控件的布局集合,我们可以通过动态的添加子控件方式,进行界面效果的实现。
第一步,自定义View,继承ViewGroup,重写onMeasure()方法,动态的适配子控件的宽高从而达到流式布局的效果。
public class FlowLayout extends ViewGroup { private float mVerticalSpacing; //每个item纵向间距 private float mHorizontalSpacing; //每个item横向间距 private int mMinimumWidth = 0; private FlowLayoutAdapter mAdapter; public FlowLayout(Context context) { super(context); this.mMinimumWidth = (ConstantsUtils.DISPLAYW - 100) / 2; } public FlowLayout(Context context, AttributeSet attrs) { super(context, attrs); this.mMinimumWidth = (ConstantsUtils.DISPLAYW - 100) / 2; } public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.mMinimumWidth = (ConstantsUtils.DISPLAYW - 100) / 2; } public void setHorizontalSpacing(float pixelSize) { mHorizontalSpacing = pixelSize; } public void setVerticalSpacing(float pixelSize) { mVerticalSpacing = pixelSize; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int selfWidth = resolveSize(0, widthMeasureSpec); int paddingLeft = getPaddingLeft(); int paddingTop = getPaddingTop(); int paddingRight = getPaddingRight(); int paddingBottom = getPaddingBottom(); int childLeft = paddingLeft; int childTop = paddingTop; int lineHeight = 0; //通过计算每一个子控件的高度,得到自己的高度 for (int i = 0, childCount = getChildCount(); i < childCount; ++i) { View childView = getChildAt(i); childView.setMinimumWidth(mMinimumWidth); LayoutParams childLayoutParams = childView.getLayoutParams(); childView.measure( getChildMeasureSpec(widthMeasureSpec, paddingLeft + paddingRight, childLayoutParams.width), getChildMeasureSpec(heightMeasureSpec, paddingTop + paddingBottom, childLayoutParams.height)); int childWidth = childView.getMeasuredWidth(); int childHeight = childView.getMeasuredHeight(); // 如果子控件有需要设置最小宽度的可以在此重设 if (childWidth < mMinimumWidth){ childView.setMinimumWidth(mMinimumWidth); } lineHeight = Math.max(childHeight, lineHeight); if (childLeft + childWidth + paddingRight > selfWidth) { childLeft = paddingLeft; childTop += mVerticalSpacing + lineHeight; lineHeight = childHeight; } else { childLeft += childWidth + mHorizontalSpacing; } } int wantedHeight = childTop + lineHeight + paddingBottom; setMeasuredDimension(selfWidth, resolveSize(wantedHeight, heightMeasureSpec)); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int myWidth = r - l; int paddingLeft = getPaddingLeft(); int paddingTop = getPaddingTop(); int paddingRight = getPaddingRight(); int childLeft = paddingLeft; int childTop = paddingTop; int lineHeight = 0; //根据子控件的宽高,计算子控件应该出现的位置。 for (int i = 0, childCount = getChildCount(); i < childCount; ++i) { View childView = getChildAt(i); if (childView.getVisibility() == View.GONE) { continue; } int childWidth = childView.getMeasuredWidth(); int childHeight = childView.getMeasuredHeight(); lineHeight = Math.max(childHeight, lineHeight); if (childLeft + childWidth + paddingRight > myWidth) { childLeft = paddingLeft; childTop += mVerticalSpacing + lineHeight; lineHeight = childHeight; } childView.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight); childLeft += childWidth + mHorizontalSpacing; } } public void setAdapter(FlowLayoutAdapter adapter){ this.mAdapter = adapter; mAdapter.init(); } // 数据适配器 public interface FlowLayoutAdapter{ /** 初始化布局,可在此方法内动态添加控件*/ void init(); /** 刷新布局*/ void refresh(); /** 设置动作事件的刷新回调*/ void setChoosed(String name,String value); }}
第二步,布局文件中写入ScrollView,内包含一个子控件LinearLayout,并在java代码中动态添加FlowLayout控件。
第三步,重写FlowLayout的监听器,并进行监听调用
0 0
- 热门标签之流式布局
- Android开发之流式标签布局
- Andorid 流式布局 热门标签解决方案
- 关于流式布局与热门标签
- android 流式布局(热门标签)
- 自定义布局之流式布局
- Android自定义之流式布局
- 自定义控件之流式布局
- 自定义ViewGroup之流式布局
- 自定义view之流式布局
- 热门标签流式布局的实现--防网易云音乐热门标签
- 自定义流式布局(应用:热门标签,照片)
- Android 实现FlowLayout流式布局(类似热门标签)
- Android 实现FlowLayout流式布局(类似热门标签)
- Java Swing 之流式布局管理器
- Android自定义控件之流式布局
- 自定义View之流式布局FlowLayout
- 自定义控件之流式布局FlowLayout
- Schmid滤波器
- sp lr pc详解
- Redis学习记录之命令KEY(五)
- ConnectionPoolTimeoutException 异常
- Using Databases with Python-Counting Organizations
- 热门标签之流式布局
- ctags 的安装和使用
- 华为交换机基本配置命令
- LeetCode OJ - 3Sum Closest
- Gabor滤波器
- java-getClass().getResource()与getClassLoader().getResource()
- EditText的两个高冷用法
- 随机重命名MP3文件
- 如何判断自己IP是内网IP还是外网IP