自定义View(通过ViewGroup实现,Textview长度根据字数的多少而定的)

xiaoxiao2021-02-28  114

一、布局

1.1、Drawable文件布局 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#5522ff"/> <corners android:radius="10dp"/> <padding android:left="5dp" android:right="5dp" android:top="5dp" android:bottom="5dp" /> </shape> 1.2、Main文件布局 <com.baway.www.custom_viewdemo.FlowLayout android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/flowlayot"> </com.baway.www.custom_viewdemo.FlowLayout> 二、帮助类

public class FlowLayout extends ViewGroup {

//存储所有子View private List<List<View>> mlistView = new ArrayList<>(); //每一行的高度 private List<Integer> mlistHigth = new ArrayList<>(); public FlowLayout(Context context) { this(context,null); } public FlowLayout(Context context, AttributeSet attrs) { this(context, attrs,0); } public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //如果当前ViewGroup的宽高为wrap_content的情况 ,自己测量的宽高 int width = 0; int hight = 0; //每一行线的宽度 int linWidth = 0; int linHight = 0; //父控件传进来的宽度和高度以及对应的测量模式 int modeWidth = MeasureSpec.getMode(widthMeasureSpec); int sizeWidth = MeasureSpec.getSize(widthMeasureSpec); int modeHight = MeasureSpec.getMode(heightMeasureSpec); int sizeHight = MeasureSpec.getSize(heightMeasureSpec); //获取子View的个数 int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View child = getChildAt(i); //测量子view的宽高 measureChild(child,widthMeasureSpec,heightMeasureSpec); MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); //子view占得宽度 int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; //子VIew的高度 int childHight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; //换行判断 if ((linWidth + childWidth) > sizeWidth){ //对比得到最大的宽度 width = Math.max(width,linWidth); linWidth = childWidth; //记录行高 hight += linHight; linHight = childHight; }else{ //不换行的情况 linWidth += childWidth; //得到最大行高 linHight = Math.max(linHight,childHight); } //处理最后一个子View的情况 if (i == childCount -1){ width = Math.max(width,linWidth); hight += linHight; } } setMeasuredDimension(modeWidth == MeasureSpec.EXACTLY ? sizeWidth : width , modeHight == MeasureSpec.EXACTLY ? sizeHight : hight); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { mlistView.clear(); mlistHigth.clear(); //获取当前ViewGroup的宽度 int width = getWidth(); int linWidth = 0; int linHight = 0; //记录当前行的view List<View> lineViews = new ArrayList<View>(); int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View child = getChildAt(i); MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); int childWidth = child.getMeasuredWidth(); int childHight = child.getMeasuredHeight(); //需要换行 if (childWidth + linWidth + lp.leftMargin + lp.rightMargin > width){ //记录LineHeight mlistHigth.add(linHight); //记录当前的Views mlistView.add(lineViews); linWidth = 0; linHight = childHight + lp.topMargin + lp.bottomMargin; lineViews = new ArrayList(); } linWidth += childWidth + lp.leftMargin + lp.rightMargin; linHight = Math.max(linHight,childHight + lp.topMargin + lp.bottomMargin); lineViews.add(child); } //处理最后一行 mlistHigth.add(linHight); mlistView.add(lineViews); //设置VIew的位置 int left = 0; int top = 0; //获取行数 int lineCount = mlistView.size(); for (int i = 0; i < lineCount; i++) { lineViews = mlistView.get(i); linHight = mlistHigth.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 cLeft = left + lp.leftMargin; int cTop = top + lp.topMargin; int cRight = cLeft + child.getMeasuredWidth(); int cBottom = cTop + child.getMeasuredHeight(); child.layout(cLeft,cTop,cRight,cBottom); left += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; } left = 0; top += linHight; } } // @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new MarginLayoutParams(getContext(), attrs); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); }

}

三、主方法MainActivity

public class MainActivity extends AppCompatActivity {

//设置数据的个数 private String mName[] = {"xListView","XUtils","PullToRefresh","ImageLoader","RecycleView","自定义View","ViewGroup","TextView","Button","ImageButton", "ImageView","ProgressBar","SeekBar","Model","View","Presenter","大磨叽","艳艳"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initChildViews(); } private void initChildViews() { FlowLayout mFlowLayout = (FlowLayout) findViewById(R.id.flowlayot); int wrapContent = LayoutParams.WRAP_CONTENT; MarginLayoutParams lp = new MarginLayoutParams(wrapContent,wrapContent); lp.leftMargin = 5; lp.rightMargin = 5; lp.topMargin = 5; lp.bottomMargin = 5; for (int i = 0; i < mName.length; i++) { TextView view = new TextView(this); view.setText(mName[i]); view.setTextColor(Color.WHITE); //view.setBackgroundDrawable(getResources().getDrawable(R.drawable.textview_bg)); view.setBackgroundDrawable(getResources().getDrawable(R.drawable.twos)); mFlowLayout.addView(view,lp); } }

}

“`

转载请注明原文地址: https://www.6miu.com/read-48149.html

最新回复(0)