Android第三十八期 - 评价标签FlowLayout
16lz
2021-12-04
代码已经整理好,这里要说一下,因为手动和Json获取写法不一样。
手动直接xml设置:
效果如下:
Json获取:
if(message.what == 1) { // 处理操作 pingjia = newArrayList(); pingjia.addAll(JsonUtils.getBeanList(message.result,"Items", Pingjia.class)); FlowLayout layout = (FlowLayout)findViewById(R.id.layou23); LinearLayout.LayoutParams params = newLinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); params.gravity =Gravity.CENTER_VERTICAL; // 加载TextView for (int i = 0; i < pingjia.size();i++) { Pingjia ping = pingjia.get(i); tvNav = new TextView(this); tvNav.setTextSize(13.f); // tvNav.setWidth((int)Math.floor(Double.valueOf(a))); // tvNav.setHeight((int)Math.floor(Double.valueOf(b))); tvNav.setText(ping.getContent()); tvNav.setId(ping.getId()); tvNav.setBackgroundResource(R.anim.flag_022); tvNav.setTag(false); tvNav.setTextColor(getResources().getColor(R.color.gray)); // tvNav.setPadding(30, 10, 30, 10); // tvNav.setGravity(Gravity.CENTER_HORIZONTAL); tvNav.setOnClickListener(newTvClickListener(tvNav)); layout.addView(tvNav, params); } private TextView tvNav;private String str = "";private String strId = "";/** * 标题栏textview 点击事件 * * @author fei * */private final class TvClickListener implements View.OnClickListener {// private int index;private TextView tvNav;public TvClickListener(TextView tvNav) {super();// this.index = index;this.tvNav = tvNav;}@Overridepublic void onClick(View v) {Boolean isclick = (Boolean) tvNav.getTag();if (!isclick) {tvNav.setBackgroundResource(R.anim.flag_0444);tvNav.setTextColor(getResources().getColor(R.color.red));tvNav.setTag(true);// 显示到上面str = str + tvNav.getText().toString() + ",";ed_en.setText(str);// 记录IdstrId = strId + tvNav.getId() + ",";// strId = strId.substring(0, strId.length() - 1);// MyLogUtil.v("传->strId", strId);} else {tvNav.setBackgroundResource(R.anim.flag_022);tvNav.setTextColor(getResources().getColor(R.color.gray));tvNav.setTag(false);// 显示到上面str = str.replace(tvNav.getText().toString() + ",", "");ed_en.setText(str);// 记录IdstrId = strId.replace(tvNav.getId() + ",", "");// strId = strId.substring(0, strId.length() - 1);// MyLogUtil.v("Delete->strId", strId);}// ToastUtil.showToastLong(tvNav.getId() + ","// + tvNav.getText().toString());}}
xml设置:
效果如下:
最后是自定义layout类FlowLayout:
package com.zhy.zhy_flowlayout02;import java.util.ArrayList;import java.util.List;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.View;import android.view.ViewGroup;public class FlowLayout extends ViewGroup{private static final String TAG = "FlowLayout";public FlowLayout(Context context, AttributeSet attrs){super(context, attrs);}@Overrideprotected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p){return new MarginLayoutParams(p);}@Overridepublic ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs){return new MarginLayoutParams(getContext(), attrs);}@Overrideprotected ViewGroup.LayoutParams generateDefaultLayoutParams(){return new MarginLayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);}/** * 负责设置子控件的测量模式和大小 根据所有子控件设置自己的宽和高 */@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){super.onMeasure(widthMeasureSpec, heightMeasureSpec);// 获得它的父容器为它设置的测量模式和大小int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);int modeWidth = MeasureSpec.getMode(widthMeasureSpec);int modeHeight = MeasureSpec.getMode(heightMeasureSpec);Log.e(TAG, sizeWidth + "," + sizeHeight);// 如果是warp_content情况下,记录宽和高int width = 0;int height = 0;/** * 记录每一行的宽度,width不断取最大宽度 */int lineWidth = 0;/** * 每一行的高度,累加至height */int lineHeight = 0;int cCount = getChildCount();// 遍历每个子元素for (int i = 0; i < cCount; i++){View child = getChildAt(i);// 测量每一个child的宽和高measureChild(child, widthMeasureSpec, heightMeasureSpec);// 得到child的lpMarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();// 当前子空间实际占据的宽度int childWidth = child.getMeasuredWidth() + lp.leftMargin+ lp.rightMargin;// 当前子空间实际占据的高度int childHeight = child.getMeasuredHeight() + lp.topMargin+ lp.bottomMargin;/** * 如果加入当前child,则超出最大宽度,则的到目前最大宽度给width,类加height 然后开启新行 */if (lineWidth + childWidth > sizeWidth){width = Math.max(lineWidth, childWidth);// 取最大的lineWidth = childWidth; // 重新开启新行,开始记录// 叠加当前高度,height += lineHeight;// 开启记录下一行的高度lineHeight = childHeight;} else// 否则累加值lineWidth,lineHeight取最大高度{lineWidth += childWidth;lineHeight = Math.max(lineHeight, childHeight);}// 如果是最后一个,则将当前记录的最大宽度和当前lineWidth做比较if (i == cCount - 1){width = Math.max(width, lineWidth);height += lineHeight;}}setMeasuredDimension((modeWidth == MeasureSpec.EXACTLY) ? sizeWidth: width, (modeHeight == MeasureSpec.EXACTLY) ? sizeHeight: height);}/** * 存储所有的View,按行记录 */private List> mAllViews = new ArrayList
>();/** * 记录每一行的最大高度 */private List
mLineHeight = new ArrayList ();@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b){mAllViews.clear();mLineHeight.clear();int width = getWidth();int lineWidth = 0;int lineHeight = 0;// 存储每一行所有的childViewList lineViews = new ArrayList ();int cCount = getChildCount();// 遍历所有的孩子for (int i = 0; i < cCount; i++){View child = getChildAt(i);MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();int childWidth = child.getMeasuredWidth();int childHeight = child.getMeasuredHeight();// 如果已经需要换行if (childWidth + lp.leftMargin + lp.rightMargin + lineWidth > width){// 记录这一行所有的View以及最大高度mLineHeight.add(lineHeight);// 将当前行的childView保存,然后开启新的ArrayList保存下一行的childViewmAllViews.add(lineViews);lineWidth = 0;// 重置行宽lineViews = new ArrayList ();}/** * 如果不需要换行,则累加 */lineWidth += childWidth + lp.leftMargin + lp.rightMargin;lineHeight = Math.max(lineHeight, childHeight + lp.topMargin+ lp.bottomMargin);lineViews.add(child);}// 记录最后一行mLineHeight.add(lineHeight);mAllViews.add(lineViews);int left = 0;int top = 0;// 得到总行数int lineNums = mAllViews.size();for (int i = 0; i < lineNums; i++){// 每一行的所有的viewslineViews = mAllViews.get(i);// 当前行的最大高度lineHeight = mLineHeight.get(i);Log.e(TAG, "第" + i + "行 :" + lineViews.size() + " , " + lineViews);Log.e(TAG, "第" + i + "行, :" + lineHeight);// 遍历当前行所有的Viewfor (int j = 0; j < lineViews.size(); j++){View child = lineViews.get(j);if (child.getVisibility() == View.GONE){continue;}MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();//计算childView的left,top,right,bottomint lc = left + lp.leftMargin;int tc = top + lp.topMargin;int rc =lc + child.getMeasuredWidth();int bc = tc + child.getMeasuredHeight();Log.e(TAG, child + " , l = " + lc + " , t = " + t + " , r ="+ rc + " , b = " + bc);child.layout(lc, tc, rc, bc);left += child.getMeasuredWidth() + lp.rightMargin+ lp.leftMargin;}left = 0;top += lineHeight;}}}
最后感谢 hongyang大神~Loader大神~
更多相关文章
- android中读取联系人和通话记录
- android 不使用布局文件,完全由代码控制布局实例
- 2010.12.19——— android 设置组件的高度
- android开发杂记(持续更新中)
- Android(安卓)API 实验记录(一)
- Android:控件GridView的使用实例
- android:weight的使用
- Android中获取屏幕相关信息(屏幕大小,状态栏、标题栏高度)
- Android:漫画APP开发笔记之ListView中图片按屏幕宽度缩放