博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自定义Viewgroup实现流式布局(3):条件换行的自定义ViewGroup
阅读量:4058 次
发布时间:2019-05-25

本文共 5985 字,大约阅读时间需要 19 分钟。

上篇已经实现了条件换行的自定义VIew,最后也说到onLayout来设置换行显示,这里用ViewGroup来实现,无非canvas.drawText控制文字换行换成onLayout来控制textview的换行。

既然是ViewGroup,那里面装的就是View了,这里使用上篇自定义的textview,因为系统的Textview是有行距的。

首先,onMeasure还是会首先执行,你可以使用自定义View时候的方法来计算宽高(文字大小+padding)+viewgroup的padding,也可以直接得到子View的宽高,然后加上padding。
得到子view的个数: int hadChildCount = getChildCount();
得到子view的实例:   View child = getChildAt(i);
计算子view的宽高等: measureChild(child, widthMeasureSpec, heightMeasureSpec);
得到子view的宽高:int childMeasuredHeight = child.getMeasuredHeight();
onMeasure已经得到了当前viewgroup的所有view,现在需要对子view的位置进行排布
使用View.layout(left,top,right,bottom)设置位置即可:四个点确定一个矩形范围
 

效果图:

 

实例代码如下:

public class MyTextview_Viewgroup extends ViewGroup {    public MyTextview_Viewgroup(Context context) {        super(context);    }    public MyTextview_Viewgroup(Context context, AttributeSet attrs) {        super(context, attrs);        initAtters(context, attrs);    }    public MyTextview_Viewgroup(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initAtters(context, attrs);    }    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)    public MyTextview_Viewgroup(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {        super(context, attrs, defStyleAttr, defStyleRes);        initAtters(context, attrs);    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        int startLeft = getPaddingLeft();        int startTop = getPaddingTop();        int startRight = getPaddingLeft();        int startBottom = getPaddingTop();        for (int i = 0; i < childs.size(); i++) {            View child = childs.get(i);            startRight = startRight + child.getMeasuredWidth();            startBottom = startBottom + child.getMeasuredHeight();            //left top right bottom            child.layout(startLeft, startTop, startRight, startBottom);            startTop = startTop + child.getMeasuredHeight();        }    }    String text = "需要显示的文字";    private void initAtters(Context context, @Nullable AttributeSet attrs) {        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.MyTextview);        text = array.getString(R.styleable.MyTextview_texcontent);    }    private void initView(int widthSize) {        //因为onmeasure会执行多次        this.removeAllViews();        //首先还是判断能不能一行放下        Paint paint = null;        Rect rect = null;        if (paint == null) {            paint = new Paint();            paint.setTextSize(SizeUtil.sp2px(getContext(), 20.0f));            paint.setColor(Color.parseColor("#000000"));            paint.setAntiAlias(true);            paint.setFilterBitmap(true);//位图过滤            ;        }        if (rect == null) {            rect = new Rect();        }        paint.getTextBounds(text, 0, text.length(), rect);        //        if (widthSize - getPaddingLeft() - getPaddingRight() >= rect.width()) {            //一行容纳            MyTextview textView = new MyTextview(getContext());            textView.setPadding(0, 0, 0, 0);            ViewGroup.LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);            textView.setLayoutParams(layoutParams);            textView.setText(text);            this.addView(textView);            return;        }        List
rowStrings = new ArrayList<>(); double rows = text.length() / 7.0; int lineNum = (int) Math.ceil(rows); //一行文字所包含的文字数 //0开始,依次加然后判断 for (int i = 0; i < lineNum; i++) { String rowText = ""; if (i == lineNum - 1) { rowStrings.add(text.substring(i * 7, text.length())); rowText = text.substring(i * 7, text.length()); } else { rowStrings.add(text.substring(i * 7, (i + 1) * 7)); rowText = text.substring(i * 7, (i + 1) * 7); } MyTextview textView = new MyTextview(getContext()); textView.setPadding(0, 0, 0, 0); ViewGroup.LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); textView.setLayoutParams(layoutParams); textView.setText(rowText); this.addView(textView); } } List
childs; @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); childs = new ArrayList<>(); // Log.e("MyViewgroup+onMeasure", "现在有多少个子view" + getChildCount()); int widthMode = MeasureSpec.getMode(widthMeasureSpec); //获取宽的模式 int heightMode = MeasureSpec.getMode(heightMeasureSpec); //获取高的模式 int widthSize = MeasureSpec.getSize(widthMeasureSpec); //获取宽的尺寸 int heightSize = MeasureSpec.getSize(heightMeasureSpec); //获取高的尺寸 initView(widthSize); //测量子view的宽高,然后得到整个的宽高 int width = 0; int height = 0; int hadChildCount = getChildCount(); for (int i = 0; i < hadChildCount; i++) { View child = getChildAt(i); childs.add(child); //测量下子view的大小 measureChild(child, widthMeasureSpec, heightMeasureSpec); int childMeasuredHeight = child.getMeasuredHeight(); int childMeasuredWidth = child.getMeasuredWidth(); // Log.e("当前child的宽和高是", childMeasuredWidth + "-" + childMeasuredHeight); if (childMeasuredWidth > width) { width = childMeasuredWidth + getPaddingLeft() + getPaddingRight(); } height = height + childMeasuredHeight; } if (widthMode == MeasureSpec.EXACTLY) { width = widthSize; } else { } if (heightMode == MeasureSpec.EXACTLY) { height = heightSize; } //保存测量宽度和测量高度 setMeasuredDimension(width, height + getPaddingBottom() + getPaddingTop()); Log.e("计算出来viewgroup的高度是", height + getPaddingTop() + getPaddingBottom() + ""); }}

 

 

转载地址:http://scrci.baihongyu.com/

你可能感兴趣的文章
VC++ MFC SQL ADO数据库访问技术使用的基本步骤及方法
查看>>
VUE-Vue.js之$refs,父组件访问、修改子组件中 的数据
查看>>
Python自动化之pytest常用插件
查看>>
Python自动化之pytest框架使用详解
查看>>
【正则表达式】以个人的理解帮助大家认识正则表达式
查看>>
性能调优之iostat命令详解
查看>>
性能调优之iftop命令详解
查看>>
非关系型数据库(nosql)介绍
查看>>
移动端自动化测试-Windows-Android-Appium环境搭建
查看>>
Xpath使用方法
查看>>
移动端自动化测试-Mac-IOS-Appium环境搭建
查看>>
Selenium之前世今生
查看>>
Selenium-WebDriverApi接口详解
查看>>
Selenium-ActionChains Api接口详解
查看>>
Selenium-Switch与SelectApi接口详解
查看>>
Selenium-Css Selector使用方法
查看>>
Linux常用统计命令之wc
查看>>
测试必会之 Linux 三剑客之 sed
查看>>
Socket请求XML客户端程序
查看>>
Java中数字转大写货币(支持到千亿)
查看>>