项目中遇到动态添加view的需求来展示视频画面,整理一下供大家参考import android.annotation.SuppressLint;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Point;import android.graphics.Rect;import android.os.Build;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.view.WindowManager;import android.widget.LinearLayout;import android.widget.TextView;import com.cloudroom.cloudroomvideosdk.model.UsrVideoId;import com.example.chenhe.s.sxlivevideo.R;import com.example.chenhe.s.sxlivevideo.common.Constants;import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.List;/** * @author:chenhe * @date:2019/4/1 11:44 */public class FlowTagLayout extends ViewGroup {    private Context context;    private Rect[] childrenBounds;//    private List tagList;    private ArrayList tagWatchableVideos;    ArrayList WatchVideos = new ArrayList();//所有视频流    private OnTagClickListener onTagClickListener;    private int defaultColor = Color.parseColor("#666666");    private float defaultTextSize = Utils.spToPx(16);    /****************** 自定义的Attribute *************************/    private int leftMargin;    private int rightMargin;    private int topMargin;    private int bottomMargin;    private int leftPadding;    private int rightPadding;    private int topPadding;    private int bottomPadding;    private int background;    private int textColor;    private float textSize;    public static int devd_w = 2;    public static int devd_h = 1;    private int screenWidth;    private int screenHeight;    public FlowTagLayout(Context context) {        super(context);        this.context = context;    }    public FlowTagLayout(Context context, AttributeSet attrs) {        super(context, attrs);        this.context = context;        init(attrs);        getScreenSize();    }    public FlowTagLayout(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        this.context = context;        init(attrs);        getScreenSize();    }    private void init(AttributeSet attrs) {        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.FlowTagLayout);        leftMargin = (int) typedArray.getDimension(R.styleable.FlowTagLayout_item_leftMargin, 0);        rightMargin = (int) typedArray.getDimension(R.styleable.FlowTagLayout_item_rightMargin, 0);        topMargin = (int) typedArray.getDimension(R.styleable.FlowTagLayout_item_topMargin, 0);        bottomMargin = (int) typedArray.getDimension(R.styleable.FlowTagLayout_item_bottomMargin, 0);        leftPadding = (int) typedArray.getDimension(R.styleable.FlowTagLayout_item_leftPadding, 0);        rightPadding = (int) typedArray.getDimension(R.styleable.FlowTagLayout_item_rightPadding, 0);        topPadding = (int) typedArray.getDimension(R.styleable.FlowTagLayout_item_topPadding, 0);        bottomPadding = (int) typedArray.getDimension(R.styleable.FlowTagLayout_item_bottomPadding, 0);        background = typedArray.getResourceId(R.styleable.FlowTagLayout_item_background, -1);        textColor = typedArray.getColor(R.styleable.FlowTagLayout_item_textColor, defaultColor);        textSize = typedArray.getDimension(R.styleable.FlowTagLayout_item_textSize, defaultTextSize);        typedArray.recycle();    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        Log.e("onMeasure", "----------------------onMeasure----------------------");        // 已用宽度        int widthUsed = getPaddingLeft();        // 已用高度        int heightUsed = getPaddingTop();        // 当前行高度        int lineHeight = 0;        // 当前行宽度        int lineWidth = 0;        // 本身的宽度        int parentWidth = 0;        // 本身的高度        int parentHeight = 0;        int specWidth = MeasureSpec.getSize(widthMeasureSpec);        int specWidthMode = MeasureSpec.getMode(widthMeasureSpec);        int specHeight = MeasureSpec.getSize(heightMeasureSpec);        int specHeightMode = MeasureSpec.getMode(heightMeasureSpec);        int childCount = getChildCount();        if (childrenBounds == null) {            childrenBounds = new Rect[childCount];        } else if (childrenBounds.length < childCount) {            childrenBounds = Arrays.copyOf(childrenBounds, childCount);        }        // 遍历测量子view        for (int i = 0; i < childCount; i++) {            View child = getChildAt(i);            // 测量子view            measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);            MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();            // 判断是否换行(1.不是非限制  2.已用宽度+当前添加的child宽度+左右的padding 是否大于 父view自身测量的宽度)            int paddingRight = getPaddingRight();            Log.e("20000", paddingRight + ":padding");            Log.e("20000", lp.leftMargin + ":margin");            Log.e("20000", child.getMeasuredWidth() + ":width");            widthUsed = widthUsed + leftMargin;            if (specWidthMode != MeasureSpec.UNSPECIFIED &&                    widthUsed + child.getMeasuredWidth() + rightMargin + getPaddingRight() > specWidth) {                parentWidth = specWidth;                widthUsed = getPaddingLeft() + leftMargin;                // 已用高度 = 之前已用高度 + 当前行的高度                heightUsed = heightUsed + lineHeight;                measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);                measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);            }            Rect childBounds = childrenBounds[i];            if (childBounds == null) {                childBounds = childrenBounds[i] = new Rect();            }            lineHeight = child.getMeasuredHeight() + topMargin + bottomMargin;            // 保存child的位置            childBounds.set(widthUsed, heightUsed + topMargin,                    widthUsed + child.getMeasuredWidth(), heightUsed + lineHeight - bottomMargin);            // 当前行已用的宽度            widthUsed = widthUsed + child.getMeasuredWidth() + rightMargin;        }        // 因为换行parentWidth会被赋值,所以需要对比是否换行过赋值后的parentWidth        parentWidth = Math.max(parentWidth, widthUsed + getPaddingRight());        // 父view的高度 = 已用高度 + 当前行高度 + padding        parentHeight = heightUsed + lineHeight + getPaddingBottom();        setMeasuredDimension(resolveSizeAndState(parentWidth, widthMeasureSpec, 0),                resolveSizeAndState(parentHeight, heightMeasureSpec, 0));    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        for (int i = 0; i < getChildCount(); i++) {            View view = getChildAt(i);            Rect childRect = childrenBounds[i];            view.layout(childRect.left, childRect.top, childRect.right, childRect.bottom);        }    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);    }    /**     * 必须重写这个方法,不然measure的时候child.getLayoutParams()的margin是为0的     *     * @param attrs     * @return     */    @Override    public LayoutParams generateLayoutParams(AttributeSet attrs) {        return new MarginLayoutParams(getContext(), attrs);    }    @Override    protected LayoutParams generateDefaultLayoutParams() {        return new MarginLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));    }    /**     * 添加tags列表     *     * @param watchableVideos     */    public void addTags(ArrayList watchableVideos) {        Log.e("调试方法","--------addTags"+watchableVideos.toString());        if (tagWatchableVideos == null) {            tagWatchableVideos = new ArrayList<>();        } else {            tagWatchableVideos.clear();        }//        tagWatchableVideos.addAll(watchableVideos);        tagWatchableVideos = watchableVideos;        setDevid(tagWatchableVideos.size());        loadTagView();    }    /**     * 添加控件数量     *     * @param num     */    public void addTags(int num) {        Log.e("视频","addTags(int num)");        setDevid(num);        for (int i = 0; i < num; i++) {            setTagContent(i);        }    }    /**     * 初始化tags     */    private void setDevid(int num) {        switch (num) {            case 0:            case 1:                devd_w = 1;                devd_h = 1;                break;            case 2:                devd_w = 2;                devd_h = 1;                break;            case 3:                devd_w = 2;                devd_h = 2;                break;            case 4:                devd_w = 2;                devd_h = 2;                break;            case 5:                devd_w = 3;                devd_h = 2;                break;            case 6:                devd_w = 3;                devd_h = 2;                break;            case 7:                devd_w = 4;                devd_h = 2;                break;            case 8:                devd_w = 4;                devd_h = 2;                break;            case 9:                devd_w = 3;                devd_h = 3;                break;            default:                devd_w = 2;                devd_h = 2;                break;        }    }    /**     * 初始化tags     */    private void loadTagView() {        removeAllViews();        Log.e("调试方法","--------loadTagView");        for (int i = 0; i < tagWatchableVideos.size(); i++) {            setTagContent(i);        }    }    /**     * 添加到尾部     *     * @param label     */    public void addTag(UsrVideoId label) {        Log.e("调试方法","--------addTaglabel");        if (tagWatchableVideos == null) {            tagWatchableVideos = new ArrayList<>();        }        tagWatchableVideos.add(label);        setDevid(tagWatchableVideos.size());        setTagContent(tagWatchableVideos.size() - 1);    }    /**     * 添加到尾部     *     * @param videolist     */    public void addTag( ArrayList videolist,int pos) {        Log.e("视频","周到这李addtag");        WatchVideos.add(videolist.get(pos));        setDevid(WatchVideos.size());        setTagContent(WatchVideos.size() - 1);//        int childCount = getChildCount();//        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);//        int screenWidth = wm.getDefaultDisplay().getWidth();//        int screenHeight = wm.getDefaultDisplay().getHeight();////        // 遍历测量子view//        for (int i = 0; i < childCount; i++) {//            View child = getChildAt(i);//            VideoView videoView = child.findViewById(R.id.item_videoview);////            LinearLayout.LayoutParams Params = (LinearLayout.LayoutParams) videoView.getLayoutParams();//            Params.height = (int) screenHeight / devd_h;//            Params.width = (int) screenWidth / devd_w;//            videoView.setLayoutParams(Params);////            if (i<=WatchVideos.size()){//                videoView.setUsrVideoId(WatchVideos.get(i));//            }////        }    }    /**     * 添加tag到index位置     *     * @param index     * @param label     */    public void addTagOfIndex(int index, UsrVideoId label) {        if (tagWatchableVideos == null) {            tagWatchableVideos = new ArrayList<>();        }        tagWatchableVideos.add(index, label);        setTagOfIndex(index);    }    /**     * 初始化item     *     * @param i     */    @SuppressLint("NewApi")    private void setTagContent(int i) {        Log.e("调试方法","--------setTagContent"+i);        LayoutInflater.from(context).inflate(R.layout.item_videoview, this);        // 这里用是getChildAt(index)获取子view,不能直接拿上面inflate的view        VideoView videoView = getChildAt(i).findViewById(R.id.item_videoview);        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);        lp.setMargins(leftPadding, topPadding, rightPadding, bottomPadding);        lp.height = (int) screenHeight / devd_h;        lp.width = (int) screenWidth / devd_w;        videoView.setLayoutParams(lp);        Log.e("调试方法","--------setTagContent"+tagWatchableVideos.get(i).toString());        videoView.setUsrVideoId(tagWatchableVideos.get(i));//        textView.setText(tagList.get(i));//        textView.setTextColor(textColor);//        textView.setTextSize(Utils.pxToSp(textSize));        refreshTag(tagWatchableVideos.size());        final int finalI = i;        if (background == -1) {            getChildAt(i).setBackground(null);        } else {            getChildAt(i).setBackground(getResources().getDrawable(background));        }        getChildAt(i).setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                if (onTagClickListener != null) {                    onTagClickListener.tagClick(finalI);                }            }        });    }    /**     * 添加到index位置,使用的是addView(view ,index),最后需要把点击事件重置     *     * @param i     */    @SuppressLint("NewApi")    private void setTagOfIndex(int i) {        View view = LayoutInflater.from(context).inflate(R.layout.item_tag, null, false);        addView(view, i);        // 这里用是getChildAt(index)获取子view,不能直接拿上面inflate的view//        TextView textView = getChildAt(i).findViewById(R.id.item_text);        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);        lp.setMargins(leftPadding, topPadding, rightPadding, bottomPadding);//        textView.setLayoutParams(lp);//        textView.setText(tagList.get(i));//        textView.setTextColor(textColor);//        textView.setTextSize(Utils.pxToSp(textSize));        if (background == -1) {            getChildAt(i).setBackground(null);        } else {            getChildAt(i).setBackground(getResources().getDrawable(background));        }        for (int j = 0; j < getChildCount(); j++) {            // 去掉点击事件            getChildAt(j).setOnClickListener(null);            final int finalJ = j;            // 重新绑定点击监听            getChildAt(j).setOnClickListener(new OnClickListener() {                @Override                public void onClick(View v) {                    if (onTagClickListener != null) {                        onTagClickListener.tagClick(finalJ);                    }                }            });        }    }    /**     * 移除最后一个tag     */    public void removeTag(int s) {//        getChildAt(tagList.size() - 1).setOnClickListener(null);//        removeViewAt(tagList.size() - 1);//        tagList.remove(tagList.size() - 1);        getChildAt(s).setOnClickListener(null);        removeViewAt(s);        tagWatchableVideos.remove(s);    }    /**     * 更新布局     */    public void refreshTag(int num) {        Log.e("调试方法","refreshTag----->"+num);        setDevid(num);//        this.devd = devd;        int childCount = getChildCount();        int randomnum = (int) (Math.random() * 10) + 1;//0到10随机数        // 遍历测量子view        for (int i = 0; i < childCount; i++) {            View child = getChildAt(i);            VideoView videoView = child.findViewById(R.id.item_videoview);            LinearLayout.LayoutParams Params = (LinearLayout.LayoutParams) videoView.getLayoutParams();            Params.height = (int) screenHeight / devd_h;            Params.width = (int) screenWidth / devd_w;            videoView.setLayoutParams(Params);        }    }    /**     * 更新布局     */    public void refreshTag( ArrayList watchableVideos ) {        setDevid(watchableVideos.size());//        this.devd = devd;        int childCount = getChildCount();        // 遍历测量子view        for (int i = 0; i < childCount; i++) {            View child = getChildAt(i);            VideoView videoView = child.findViewById(R.id.item_videoview);            LinearLayout.LayoutParams Params = (LinearLayout.LayoutParams) videoView.getLayoutParams();            Params.height = (int) screenHeight / devd_h;            Params.width = (int) screenWidth / devd_w;            videoView.setLayoutParams(Params);            if (i<=watchableVideos.size()){                videoView.setUsrVideoId(watchableVideos.get(i));            }        }    }    /**     * 移除index位置的tag     *     * @param usrVideoId     */    public void removeTagOfIndex(UsrVideoId usrVideoId) {        int index = 0;        for (int i = 0;i= Build.VERSION_CODES.JELLY_BEAN_MR1) {//获取真实高度 包括导航栏 状态栏            WindowManager wmManager=(WindowManager) context.getSystemService(Context.WINDOW_SERVICE);            wmManager.getDefaultDisplay().getRealMetrics(dm);            screenHeight = dm.heightPixels;        }    }}

 

 

//新增flowTagLayout.addTag(new_otherWatchVideos.get(i));

//移除

flowTagLayout.removeTagOfIndex(old_otherWatchVideos.get(j));

//删除所有

flowTagLayout.removeAllViews();

 

demo

https://download.csdn.net/download/csdndouniwan/11081839

更多相关文章

  1. Android文件递归遍历
  2. 2010.12.19——— android 设置组件的高度
  3. Android:漫画APP开发笔记之ListView中图片按屏幕宽度缩放
  4. Android中获取屏幕相关信息(屏幕大小,状态栏、标题栏高度)
  5. Android 获取状态栏的高度
  6. android 中超出屏幕宽度的字符 省略号显示
  7. Android 使用 TableLayout 布局拉伸宽度

随机推荐

  1. android布局基础及范例:人人android九宫格
  2. Android底部弹出iOS7风格对话选项框
  3. Android用户看过来,免ROOT和顽固后台拜拜
  4. 让 Android(安卓)可以识别BMP图片文件,且
  5. 第一行代码笔记1
  6. Android(安卓)5.1.1 源码目录结构
  7. Android(安卓)碎屏效果 (Crack Screen,击
  8. android socket通信
  9. {转}实现谷歌Android摄像头拍照 2010-06-
  10. Android使用XML全攻略(1)