代码已经整理好,这里要说一下,因为手动和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; } @Override public 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); // 记录Id strId = 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); // 记录Id strId = 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);	}	@Override	protected ViewGroup.LayoutParams generateLayoutParams(			ViewGroup.LayoutParams p)	{		return new MarginLayoutParams(p);	}	@Override	public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs)	{		return new MarginLayoutParams(getContext(), attrs);	}	@Override	protected ViewGroup.LayoutParams generateDefaultLayoutParams()	{		return new MarginLayoutParams(LayoutParams.MATCH_PARENT,				LayoutParams.MATCH_PARENT);	}	/**	 * 负责设置子控件的测量模式和大小 根据所有子控件设置自己的宽和高	 */	@Override	protected 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的lp			MarginLayoutParams 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
(); @Override protected 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; // 存储每一行所有的childView List
 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保存下一行的childView mAllViews.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++) { // 每一行的所有的views lineViews = mAllViews.get(i); // 当前行的最大高度 lineHeight = mLineHeight.get(i); Log.e(TAG, "第" + i + "行 :" + lineViews.size() + " , " + lineViews); Log.e(TAG, "第" + i + "行, :" + lineHeight); // 遍历当前行所有的View for (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,bottom int 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; } }}

    最后感谢 大神~大神~