热门话题自动换行自定义控件
2015-08-24 15:44 一切尽在掌握 阅读(272) 评论(0) 编辑 收藏 举报实现根据textview的宽度实现自动换行的自定义控件:
import java.util.ArrayList; import java.util.List; import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; public class CusGroup extends ViewGroup { public CusGroup(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); // 记录宽和高 int width = 0; int height = 0; // 每行宽 int lineWidth = 0; // 每行高 int lineHeight = 0; int cCount = getChildCount(); for (int i = 0; i < cCount; i++) { View child = getChildAt(i); // 子VIew的宽和高 measureChild(child, widthMeasureSpec, heightMeasureSpec); MarginLayoutParams lp = (MarginLayoutParams) child .getLayoutParams(); // 子View所占宽高 int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; // 比较换行 if (lineWidth + childWidth > sizeWidth) { width = Math.max(lineWidth, childWidth); lineWidth = childWidth; // 新行 height += lineHeight; // 下一行的高度 lineHeight = childHeight; } else { 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<List<View>> mAllViews = new ArrayList<List<View>>(); // 记录每一行的最大高度 private List<Integer> mLineHeight = new ArrayList<Integer>(); @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<View> lineViews = new ArrayList<View>(); 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保存,然后new ArrayList保存下一行的childView mAllViews.add(lineViews); lineWidth = 0;// 重置行宽 lineViews = new ArrayList<View>(); } /** * 如果不需要换行,则累加 */ 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); for (int j = 0; j < lineViews.size(); j++) { View child = lineViews.get(j); if (child.getVisibility() == View.GONE) { continue; } MarginLayoutParams lp = (MarginLayoutParams) child .getLayoutParams(); int lc = left + lp.leftMargin; int tc = top + lp.topMargin; int rc = lc + child.getMeasuredWidth(); int bc = tc + child.getMeasuredHeight(); child.layout(lc, tc, rc, bc); left += child.getMeasuredWidth() + lp.rightMargin + lp.leftMargin; } left = 0; top += lineHeight; } } }
使用:
public class MainActivity extends Activity implements OnItemClickListener, OnClickListener { private CusGroup cg; private List<String> allTags; private Context context; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); context = this; initView(); } public void initView() { //从服务器动态获取 allTags = new ArrayList<String>(); allTags.add("暴走大事件hahahahahhahahahhahahahha"); allTags.add("暴走好声音"); allTags.add("王尼玛"); allTags.add("末日hehehehhehehehehhehehehheheheh"); allTags.add("越狱"); //自定义的view cg = (CusGroup) findViewById(R.id.cg); for(int i=0;i<allTags.size();i++){ //显示的内容 String newtag = allTags.get(i); // 创建TextView final TextView newTagTv = creatTagTextView(newtag, false); newTagTv.setTag(newtag); //向顶部自定义view加的末尾子view cg.addView(newTagTv,i); //给加的子View设置监听 newTagTv.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // changTagStyle((TextView)v, true); //直接给textview设置背景选择器 Toast.makeText(context, newTagTv.getText(), 0).show(); } }); } } /** * 在CusGroup中创建新的TextView */ private TextView creatTagTextView(String str, boolean flag) { TextView newTagTv = new TextView(context); newTagTv.setText(str); newTagTv.setSingleLine(true); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); lp.setMargins(8, 8, 8, 8); newTagTv.setPadding(10, 2, 10, 2); newTagTv.setLayoutParams(lp); newTagTv.setGravity(Gravity.CENTER); changTagStyle(newTagTv, flag); return newTagTv; } /** * 改变标签背景颜色 * * @param view * @param flag * true:选中 */ private void changTagStyle(TextView view, boolean flag) { if (flag) { //设置背景选择器即可 view.setBackgroundResource(R.drawable.kno_my_tag); view.setTextColor(Color.GREEN); } else { view.setBackgroundResource(R.drawable.kno_select_tag); view.setTextColor(Color.BLACK); } } @Override public void onClick(View v) { // TODO Auto-generated method stub } @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub } }
支持增加的删除