流式布局FlowLayout的动态添加删除

前言

flow layout, 流式布局, 这个概念在移动端或者前端开发中很常见,想淘宝,京东都有,之前公司项目有用到一个流布局显示关键词并动态添加的效果,于是科补并实现了一下。


展示

因为软键盘的问题,本来是想上静态图的,但是强迫症上来了,还是搞了个动态图,就是有点失真,抱歉抱歉,另外求推荐一款截屏软件啊!!!

里面写死了是textview、当然有需求的小伙伴们可以自己改一下,比较简单。

分析

我们来看看他需要些什么,不难看出
1. 左右间距,行间距
2. 子view的点击事件,长按事件
3. 点击的同事判断是否是最后一个添加按钮,
4. 计算每个子view的高度,取最高的,
5. 计算每个子view的宽度,叠加超过控件宽度则需要换行
6. 点击事件的回调,1:点击添加按钮的回调,2:点击其他按钮的回调返回当前选中的list字符串集合,便于通知服务器
7. 长按事件点击确定删除标签的回调,便于通知服务器


接下来就只是上代码了,因为你们搬砖我也是个初窥,所以注释比较全,就不多做解释了


XCFlowLayout.java

public class XCFlowLayout extends ViewGroup implements View.OnClickListener, View.OnLongClickListener {
    /**
     * 存储所有子View,每行每行的储存
     */
    private ArrayList> mAllChildViews = new ArrayList<>();
    /**
     * 存储所有选择的子View,
     */
    private ArrayList BackViews = new ArrayList<>();
    /**
     * 存储所有选择的item,
     */
    private ArrayList Backitem = new ArrayList<>();
    /**
     * 记录每个子view的选中情况
     */
    private Map MapBack = new HashMap<>();
    /**
     * 孩子的数量,复制
     */
    public ArrayList listChild;
    /**
     * 每一个孩子的左右的间距  默认值 12,单位是px
     */
    int mHSpace = 12;
    /**
     * 每一行的上下的间距
     */
    int mVSpace = 16;
    /**
     * 每一行的高度
     */
    private ArrayList mLineHeight = new ArrayList<>();
    /**
     * 嵌套  ScrollView 的子view的高度,重新计算的
     */
    public int viewHeight = 0;
    /**
     * 用来计算子View占据的高度
     */
    public int childHeight;
    private MarginLayoutParams lp;
    private Context context;

    private boolean isCheck;
    private addViewListener OnaddListener;
    // 显示隐藏键盘用的
    InputMethodManager m;

    public XCFlowLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public XCFlowLayout(Context context) {
        this(context, null);
    }

    public XCFlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.XCFlowLayout, defStyleAttr, 0);
        //获取横纵向的间距
        mHSpace = a.getDimensionPixelSize(R.styleable.XCFlowLayout_h_space, dpToPx(6));
        mVSpace = a.getDimensionPixelSize(R.styleable.XCFlowLayout_v_space, dpToPx(8));

    }

    /**
     * 设置间距
     * @param hSpace
     */
    public void setHSpace(int hSpace) {
        this.mHSpace = hSpace;
    }

    /**
     * 设置上下间距
     * @param vSpace
     */
    public void setVSpace(int vSpace) {
        this.mVSpace = vSpace;
    }

    public void setAddView(addViewListener OnaddListener) {
        this.OnaddListener = OnaddListener;
    }

    @SuppressWarnings("ResourceType")
    public void setChildView(ArrayList listChild, Context context) {
        this.listChild = listChild;
        this.context = context;
        lp = new MarginLayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        lp.leftMargin = mHSpace/2;
        lp.rightMargin = mHSpace/2;
        lp.topMargin = mVSpace/2;
        lp.bottomMargin = mVSpace/2;
        for (int i = 0; i < listChild.size(); i++) {
            TextView view = new TextView(context);
            view.setText(listChild.get(i));
            view.setTextColor(Color.WHITE);
            view.setTag(listChild.get(i));//当做点击事件用
            view.setBackgroundDrawable(getResources().getDrawable(
                    R.drawable.textview_bg));
            view.setLayoutParams(lp);
            addView(view);
            view.setOnClickListener(this);
            view.setOnLongClickListener(this);
            MapBack.put(view.getTag().toString(), false);
        }
        TextView view = new TextView(context);
        view.setText(UiUtils.getString(R.string.addView));
        view.setTextColor(Color.GREEN);
        view.setTag(UiUtils.getString(R.string.addView));//当做点击事件用
        view.setBackgroundDrawable(getResources().getDrawable(R.drawable.textview_bg));
        view.setLayoutParams(lp);
        addView(view);
        view.setOnClickListener(this);
        // 实例化显示隐藏键盘用的,当前显示则隐藏,当前隐藏则显示
        m = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
    }

    public void setChildView(String[] listChild, Context context) {
        for (int i = 0; i < listChild.length; i++) {
            this.listChild.add(listChild[i]);
        }
        setChildView(this.listChild, context);
    }

    public void addView(String str) {
        TextView view = new TextView(context);
        view.setText(str);
        view.setTextColor(Color.WHITE);
        view.setTag(str);//当做点击事件用
        view.setBackgroundDrawable(getResources().getDrawable(R.drawable.textview_bg));
        view.setLayoutParams(lp);
        addView(view, listChild.size());
        view.setOnClickListener(this);
        view.setOnLongClickListener(this);
        MapBack.put(view.getTag().toString(), false);
        listChild.add(listChild.size(), str);
    }

    private void OnremoveView(View v,String tag) {
        removeView(v);
        MapBack.remove(tag);
        listChild.remove(tag);
        if (OnaddListener!=null)
            OnaddListener.Onremove(tag);
    }

    @Override
    public void onClick(View v) {
        if (v.getTag() != null) {
            String id = v.getTag().toString();
            if (id.equals(UiUtils.getString(R.string.addView))) {
                // 点击添加按钮的代码
                // 显示隐藏键盘用的,当前显示则隐藏,当前隐藏则显示
                m.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
                // 点击添加按钮的代码
                if (OnaddListener != null) {
                    // 获取焦点
                    // 显示光标、
                    OnaddListener.addView();
                }
            } else {
                setBackground(v,id);
            }
        }
    }

    @Override
    public boolean onLongClick(View v) {
        final String id = v.getTag().toString();
        if (!id.equals(UiUtils.getString(R.string.addView))) {
            ShowDialog(v.getContext(), v,id);
        }
        return true;
        // setOnLongClickListener中return的值决定是否在长按后再加一个短按动作
        // true为不加短按,false为加入短按
    }

    /**
     * 因为我们自定义view对于属性为wrap_content这种情况,如果不做处理其实是与match_parent是一样效果的。
     *
     * @param widthMeasureSpec
     * @param heightMeasureSpec 拿到父容器推荐的宽和高以及计算模式
     */
     @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
        int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
        int measureWidthMode = MeasureSpec.getMode(widthMeasureSpec);
        int measureHeightMode = MeasureSpec.getMode(heightMeasureSpec);
        //根据自身的宽度约束子控件宽度,测量孩子的大小 计算模式
        //measureChildren(widthMeasureSpec, heightMeasureSpec);
        int width = 0;// 自己测量的 宽度
        int height = 0;// 自己测量的高度
        // 记录每一行的宽度和高度
        int lineWidth = 0;
        int lineHeight = 0;
        // 获取子view的个数
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = getChildAt(i);
            // 测量子View的宽和高
            measureChild(child, widthMeasureSpec, heightMeasureSpec);
            // 得到LayoutParams
            MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
            // 子View占据的宽度
            int childWidth = child.getMeasuredWidth() + lp.leftMargin
                    + lp.rightMargin;
            // 子View占据的高度
            int childHeight = child.getMeasuredHeight() + lp.topMargin
                    + lp.bottomMargin;
            // 换行时候  当前行宽加即将添加的行宽小于(=)父控件行宽时,即不换行
            if (lineWidth + childWidth < sizeWidth) {
                // 叠加行宽
                lineWidth += childWidth;
                // 得到最大行高
                lineHeight = Math.max(lineHeight, childHeight);
            } else {//换行情况
                // 对比得到最大的宽度
                width = Math.max(width, lineWidth);
                // 开始新的一行行宽即是childWidth
                lineWidth = childWidth;
                // 记录行高
                height += lineHeight;
                // 开始新的一行行高即是childHeight
                lineHeight = childHeight;
            }
        }
        //漏掉了最后一行未加
        height += lineHeight;

        setMeasuredDimension((measureWidthMode == MeasureSpec.EXACTLY) ? sizeWidth : width, (measureHeightMode == MeasureSpec.EXACTLY) ? sizeHeight : height + 10);
    }


    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        mAllChildViews.clear();
        mLineHeight.clear();
        // 获取当前ViewGroup的宽度
        int width = getWidth();
        int lineWidth = 0;//行宽
        int lineHeight = 0;//行高
        // 记录当前行的view
        ArrayList lineViews = new ArrayList<>();
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = getChildAt(i);
            MarginLayoutParams lp = (MarginLayoutParams) child
                    .getLayoutParams();
            int childWidth = child.getMeasuredWidth();
            int childHeight = child.getMeasuredHeight();

            // 如果需要换行,当前计算的宽加上即将加上的宽和间距
            if (childWidth + lineWidth + lp.leftMargin + lp.rightMargin > width) {
                // 记录LineHeight
                mLineHeight.add(lineHeight);
                // 记录当前行的Views
                mAllChildViews.add(lineViews);
                // 重置行的宽高
                lineWidth = 0;
                lineHeight = childHeight + lp.topMargin + lp.bottomMargin;
                // 重置view的集合
                lineViews = new ArrayList();
            }
            lineWidth += childWidth + lp.leftMargin + lp.rightMargin;
            lineHeight = Math.max(lineHeight, childHeight + lp.topMargin
                    + lp.bottomMargin);
            lineViews.add(child);
        }
        // 处理最后一行
        mLineHeight.add(lineHeight);
        mAllChildViews.add(lineViews);

        // 设置子View的位置
        int left = 0;
        int top = 0;
        // 获取行数
        int lineCount = mAllChildViews.size();
        for (int i = 0; i < lineCount; i++) {
            // 当前行的views和高度
            lineViews = mAllChildViews.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 cLeft = left + lp.leftMargin;
                int cTop = top + lp.topMargin;
                int cRight = cLeft + child.getMeasuredWidth();
                int cBottom = cTop + child.getMeasuredHeight();
                // 进行子View进行布局
                child.layout(cLeft, cTop, cRight, cBottom);
                left += child.getMeasuredWidth() + lp.leftMargin
                        + lp.rightMargin;
            }
            left = 0;
            top += lineHeight;
        }
    }

    /**
     * 与当前ViewGroup对应的LayoutParams
     */
    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new MarginLayoutParams(getContext(), attrs);
    }

    private void setBackground(View v,String tag) {
        //根据tag看是否
        if (!MapBack.get(tag)) {
            BackViews.add(v);
            Backitem.add(tag);
            MapBack.put(tag, true);
            v.setBackgroundDrawable(getResources().getDrawable(R.drawable.textview_bg02));
        } else {
            BackViews.remove(v);
            Backitem.remove(tag);
            MapBack.put(tag, false);
            v.setBackgroundDrawable(getResources().getDrawable(R.drawable.textview_bg));
        }
        if (OnaddListener!=null)
            OnaddListener.BackTag(Backitem);

    }

    private void ShowDialog(final Context context, final View v,final String tag) {
        BaseDialog.Builder customBuilder = new
                BaseDialog.Builder(context)
                .setTitle("确定删除")
                .setMessage("点击确定即删除该排除条件,确定删除?")
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();

                    }
                })
                .setPositiveButton("确定",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                OnremoveView(v,tag);
                                dialog.dismiss();

                            }
                        }).setImage(-1);
        BaseDialog dialog = null;
        if (dialog == null) {
            dialog = customBuilder.create();
        }
        dialog.show();
    }

    /**
     * dp的单位转换为px的
     *
     * @param dps
     * @return
     */
    private int dpToPx(int dps) {
        return Math.round(getResources().getDisplayMetrics().density * dps);
    }

    public interface addViewListener {
        /**
         * 点击添加按钮,弹出布局添加的
         */
        void addView();
        /**
         * 返回选中的list字符串集合
         */
        void BackTag(ArrayList list);
        /**
         * 点击删除的,返回点击的当前字符串
         */
        void Onremove(String tag);
    }
}

注释全在代码中了,提一下,这里区分点击事件用的的是settag的方法。还有就是ShowDialog方法是之前博客里面封装的一个自定义弹出框,

下面的是xml


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:clipToPadding="true"
    android:fillViewport="true"
    android:fitsSystemWindows="true" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        <include
            android:id="@+id/title_bar"
            layout="@layout/header_titlebar" />

        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" >

            <ScrollView
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:background="#ffffff" >

                <LinearLayout
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:orientation="vertical" >

                    <LinearLayout
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="12dp"
                        android:orientation="horizontal"
                        android:paddingLeft="10dp"
                        android:paddingRight="8dp" >

                        <TextView
                            android:layout_width="fill_parent"
                            android:layout_height="wrap_content"
                            android:layout_weight="1"
                            android:singleLine="true"
                            android:text="国内排除条件"
                            android:textColor="#000000"
                            android:textSize="25sp"
                            android:textStyle="bold" />

                        <LinearLayout
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_gravity="bottom"
                            android:orientation="horizontal" >

                            <TextView
                                android:id="@+id/anmyte_Select"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_marginRight="8dp"
                                android:background="@drawable/custom_viewgroup_qx"
                                android:text="全选"
                                android:textSize="16sp" />

                            <TextView
                                android:id="@+id/anmyte_Open"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:background="@drawable/custom_viewgroup_zk"
                                android:text="展开"
                                android:textSize="16sp" />
                        LinearLayout>
                    LinearLayout>

                    <TextView
                        android:layout_width="fill_parent"
                        android:layout_height="0.5dp"
                        android:layout_marginLeft="6dp"
                        android:layout_marginRight="8dp"
                        android:layout_marginTop="4dp"
                        android:background="#E3E3E3" />

                    <RadioButton
                        android:id="@+id/anmyte_you_xiang"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginLeft="15dp"
                        android:layout_marginTop="8dp"
                        android:text="邮箱"
                        android:textColor="#000000"
                        android:textSize="20sp"
                        android:checked="false" />
                    

                    <TextView
                        android:layout_width="fill_parent"
                        android:layout_height="0.5dp"
                        android:layout_marginBottom="8dp"
                        android:layout_marginLeft="15dp"
                        android:layout_marginRight="15dp"
                        android:background="#E3E3E3" />

                    <com.topeasychian_fengs.widgets.XCFlowLayout
                        android:id="@+id/flowlayout"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:layout_marginLeft="15dp"
                        android:layout_marginRight="15dp"
                        android:visibility="gone" >
                    com.topeasychian_fengs.widgets.XCFlowLayout>

                    <TextView
                        android:id="@+id/amyying_c_x"
                        android:layout_width="fill_parent"
                        android:layout_height="0.5dp"
                        android:layout_marginLeft="15dp"
                        android:layout_marginRight="15dp"
                        android:background="#E3E3E3"
                        android:visibility="gone" />
                    

                    <RadioButton
                        android:id="@+id/anmyte_dian_hua"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginLeft="15dp"
                        android:layout_marginTop="8dp"
                        android:text="电话"
                        android:textColor="#000000"
                        android:textSize="20sp" />

                    

                    <TextView
                        android:layout_width="fill_parent"
                        android:layout_height="0.5dp"
                        android:layout_marginBottom="8dp"
                        android:layout_marginLeft="15dp"
                        android:layout_marginRight="15dp"
                        android:background="#E3E3E3" />

                    <com.topeasychian_fengs.widgets.XCFlowLayout
                        android:id="@+id/flowlayout_2"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:layout_marginLeft="15dp"
                        android:layout_marginRight="15dp"
                        android:visibility="gone" >
                    com.topeasychian_fengs.widgets.XCFlowLayout>

                    <TextView
                        android:id="@+id/amyying_c_x_2"
                        android:layout_width="fill_parent"
                        android:layout_height="0.5dp"
                        android:layout_marginLeft="15dp"
                        android:layout_marginRight="15dp"
                        android:background="#E3E3E3"
                        android:visibility="gone" />
                    

                    <RadioButton
                        android:id="@+id/anmyte_B2B"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginLeft="15dp"
                        android:layout_marginTop="8dp"
                        android:text="B2B平台"
                        android:textColor="#000000"
                        android:textSize="20sp" />

                    

                    <TextView
                        android:layout_width="fill_parent"
                        android:layout_height="0.5dp"
                        android:layout_marginBottom="8dp"
                        android:layout_marginLeft="15dp"
                        android:layout_marginRight="15dp"
                        android:background="#E3E3E3" />

                    <com.topeasychian_fengs.widgets.XCFlowLayout
                        android:id="@+id/flowlayout_3"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:layout_marginLeft="15dp"
                        android:layout_marginRight="15dp"
                        android:visibility="gone" >
                    com.topeasychian_fengs.widgets.XCFlowLayout>

                    <TextView
                        android:id="@+id/amyying_c_x_3"
                        android:layout_width="fill_parent"
                        android:layout_height="0.5dp"
                        android:layout_marginLeft="15dp"
                        android:layout_marginRight="15dp"
                        android:background="#E3E3E3"
                        android:visibility="gone" />
                    

                    <RadioButton
                        android:id="@+id/anmyte_B2C"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginLeft="15dp"
                        android:layout_marginTop="8dp"
                        android:text="B2C平台"
                        android:textColor="#000000"
                        android:textSize="20sp" />

                    


                    

                    <TextView
                        android:layout_width="fill_parent"
                        android:layout_height="0.5dp"
                        android:layout_marginBottom="8dp"
                        android:layout_marginLeft="15dp"
                        android:layout_marginRight="15dp"
                        android:background="#E3E3E3" />

                    <com.topeasychian_fengs.widgets.XCFlowLayout
                        android:id="@+id/flowlayout_4"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:layout_marginLeft="15dp"
                        android:layout_marginRight="15dp"
                        android:visibility="gone" >
                    com.topeasychian_fengs.widgets.XCFlowLayout>

                    <TextView
                        android:id="@+id/amyying_c_x_4"
                        android:layout_width="fill_parent"
                        android:layout_height="0.5dp"
                        android:layout_marginLeft="15dp"
                        android:layout_marginRight="15dp"
                        android:background="#E3E3E3"
                        android:visibility="gone" />
                    


                    

                    <LinearLayout
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="25dp"
                        android:orientation="horizontal"
                        android:paddingLeft="10dp"
                        android:paddingRight="8dp" >

                        <TextView
                            android:layout_width="fill_parent"
                            android:layout_height="wrap_content"
                            android:layout_weight="1"
                            android:text="国外排除条件"
                            android:textColor="#000000"
                            android:textSize="25sp"
                            android:textStyle="bold" />

                        <LinearLayout
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_gravity="bottom"
                            android:orientation="horizontal" >

                            <TextView
                                android:id="@+id/awmyte_Select"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_marginRight="8dp"
                                android:background="@drawable/custom_viewgroup_qx"
                                android:text="全选"
                                android:textSize="16sp" />

                            <TextView
                                android:id="@+id/awmyte_Open"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:background="@drawable/custom_viewgroup_zk"
                                android:text="展开"
                                android:textSize="16sp" />
                        LinearLayout>
                    LinearLayout>

                    <TextView
                        android:layout_width="fill_parent"
                        android:layout_height="0.5dp"
                        android:layout_marginLeft="6dp"
                        android:layout_marginRight="8dp"
                        android:layout_marginTop="4dp"
                        android:background="#E3E3E3" />

                    <RadioButton
                        android:id="@+id/awmyte_you_xiang"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginLeft="15dp"
                        android:layout_marginTop="8dp"
                        android:text="邮箱"
                        android:textColor="#000000"
                        android:textSize="20sp" />
                    

                    <TextView
                        android:layout_width="fill_parent"
                        android:layout_height="0.5dp"
                        android:layout_marginBottom="8dp"
                        android:layout_marginLeft="15dp"
                        android:layout_marginRight="15dp"
                        android:background="#E3E3E3" />

                    <com.topeasychian_fengs.widgets.XCFlowLayout
                        android:id="@+id/flowlayout_5"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:layout_marginLeft="15dp"
                        android:layout_marginRight="15dp"
                        android:visibility="gone" >
                    com.topeasychian_fengs.widgets.XCFlowLayout>

                    <TextView
                        android:id="@+id/amyying_c_x_5"
                        android:layout_width="fill_parent"
                        android:layout_height="0.5dp"
                        android:layout_marginLeft="15dp"
                        android:layout_marginRight="15dp"
                        android:background="#E3E3E3"
                        android:visibility="gone" />
                    

                    <RadioButton
                        android:id="@+id/awmyte_dian_hua"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginLeft="15dp"
                        android:layout_marginTop="8dp"
                        android:text="电话"
                        android:textColor="#000000"
                        android:textSize="20sp" />

                    

                    <TextView
                        android:layout_width="fill_parent"
                        android:layout_height="0.5dp"
                        android:layout_marginBottom="8dp"
                        android:layout_marginLeft="15dp"
                        android:layout_marginRight="15dp"
                        android:background="#E3E3E3" />

                    <com.topeasychian_fengs.widgets.XCFlowLayout
                        android:id="@+id/flowlayout_6"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:layout_marginLeft="15dp"
                        android:layout_marginRight="15dp"
                        android:visibility="gone" >
                    com.topeasychian_fengs.widgets.XCFlowLayout>

                    <TextView
                        android:id="@+id/amyying_c_x_6"
                        android:layout_width="fill_parent"
                        android:layout_height="0.5dp"
                        android:layout_marginLeft="15dp"
                        android:layout_marginRight="15dp"
                        android:background="#E3E3E3"
                        android:visibility="gone" />
                    

                    <RadioButton
                        android:id="@+id/awmyte_B2B"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginLeft="15dp"
                        android:layout_marginTop="8dp"
                        android:text="B2B平台"
                        android:textColor="#000000"
                        android:textSize="20sp" />

                    

                    <TextView
                        android:layout_width="fill_parent"
                        android:layout_height="0.5dp"
                        android:layout_marginBottom="8dp"
                        android:layout_marginLeft="15dp"
                        android:layout_marginRight="15dp"
                        android:background="#E3E3E3" />

                    <com.topeasychian_fengs.widgets.XCFlowLayout
                        android:id="@+id/flowlayout_7"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:layout_marginLeft="15dp"
                        android:layout_marginRight="15dp"
                        android:visibility="gone" >
                    com.topeasychian_fengs.widgets.XCFlowLayout>

                    <TextView
                        android:id="@+id/amyying_c_x_7"
                        android:layout_width="fill_parent"
                        android:layout_height="0.5dp"
                        android:layout_marginLeft="15dp"
                        android:layout_marginRight="15dp"
                        android:background="#E3E3E3"
                        android:visibility="gone" />
                    

                    <Button
                        android:id="@+id/amybtn_tijiao"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginLeft="30dp"
                        android:layout_marginRight="30dp"
                        android:layout_marginTop="40dp"
                        android:text="提 交" />
                LinearLayout>
            ScrollView>

            <LinearLayout
                android:id="@+id/amylin_fa_song"
                android:layout_width="fill_parent"
                android:layout_height="40dp"
                android:layout_alignParentBottom="true"
                android:layout_marginBottom="3dp"
                android:layout_marginLeft="8dp"
                android:layout_marginRight="8dp"
                android:orientation="horizontal"
                android:visibility="gone" >

                <EditText
                    android:id="@+id/amyEdit_tian_jia"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:layout_marginRight="8dp"
                    android:layout_weight="1"
                    android:background="@drawable/details_set_a"
                    android:gravity="center_vertical"
                    android:paddingLeft="8dp"
                    android:textCursorDrawable="@drawable/color_cursor" />
                
                

                <TextView
                    android:id="@+id/amyText_tian_jia"
                    android:layout_width="wrap_content"
                    android:layout_height="fill_parent"
                    android:background="@drawable/collection_bg02"
                    android:gravity="center"
                    android:text="添加" />
            LinearLayout>
        RelativeLayout>
    LinearLayout>
RelativeLayout>

自定义属性

 <declare-styleable name="XCFlowLayout">
        
        <attr name="h_space" format="dimension" />
        <attr name="v_space" format="dimension" />
    declare-styleable>

到这里代码段就结束了

忘记activity里面的代码了我去

XCFlowLayoutActivity.java

public class XCFlowLayoutActivity extends MyBaseActivity implements OnLayoutChangeListener {
    @BindView(R.id.mXCFlowLayout)
    XCFlowLayout mXCFlowLayout;
    ArrayList list;
    ArrayList BackList;
    @BindView(R.id.edit_01)
    EditText edit01;
    @BindView(R.id.lin_01)
    LinearLayout lin01;
    @BindView(R.id.tv_01)
    TextView tv01;
    @BindView(R.id.title)
    TextView title;
    // 屏幕高度
    private int screenHeight = 0;
    // 软件盘弹起后所占高度阀值
    private int keyHeight = 0;
    InputMethodManager m;
    @Override
    protected void onCreate() {
        initView();
    }

    @Override
    protected int getLayout() {
        return R.layout.activity_xcflowlayout;
    }

    private void initView() {
        title.setText("XCFlowLayout");
        list = new ArrayList<>();
        list.add("asdasdas");
        list.add("sdasdsa");
        list.add("ghfghfgg");
        list.add("ghjkhjkh");
        list.add("lioiioui");
        list.add("weqbnmjk");
        list.add("ikhnghn");
        list.add("yterwwe");
        list.add("olpszaq");
        list.add("aqvgju");
        list.add("rgyswdr");
        list.add("qxbhuil");
        BackList = new ArrayList<>();

        m = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
        // 获取屏幕高度
        screenHeight = this.getWindowManager().getDefaultDisplay().getHeight();
        // 阀值设置为屏幕高度的1/3
        keyHeight = screenHeight / 3;

        mXCFlowLayout.setChildView(list, this);
        mXCFlowLayout.setAddView(new XCFlowLayout.addViewListener() {
            @Override
            public void addView() {
                lin01.setVisibility(View.VISIBLE);
            }

            @Override
            public void BackTag(ArrayList list) {
                BackList.clear();
                BackList.addAll(list);
                APP.mToast("" + BackList.size());
            }

            @Override
            public void Onremove(String tag) {
                APP.mToast(tag);
            }
        });
    }

    // 监听软键盘弹出收起的
    @Override
    public void onLayoutChange(View v, int left, int top, int right,
                               int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
        // old是改变前的左上右下坐标点值,没有old的是改变后的左上右下坐标点值
        // 现在认为只要控件将Activity向上推的高度超过了1/3屏幕高,就认为软键盘弹起
        if (oldBottom != 0 && bottom != 0 && (oldBottom - bottom > keyHeight)) {
            lin01.setVisibility(View.VISIBLE);
            LogUtils.e("onLayoutChange","软键盘弹起");
            // 获取焦点
            edit01.setFocusable(true);
            edit01.setFocusableInTouchMode(true);
            // 显示光标、
            edit01.requestFocus();// 获取焦点 光标出现
        } else if (oldBottom != 0 && bottom != 0
                && (bottom - oldBottom > keyHeight)) {
            lin01.setVisibility(View.GONE);
            LogUtils.e("onLayoutChange","软键盘隐藏");
            edit01.setFocusable(false);
            edit01.setFocusableInTouchMode(false);
            edit01.setText("");
            // 监听到软件盘关闭
        }
    }

    @OnClick(R.id.tv_01)
    public void onViewClicked() {
        String text = edit01.getText().toString();
        if (!TextUtil.isEmpty(text)) {
            APP.mToast(text);
            mXCFlowLayout.addView(text);
            m.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        // 添加layout大小发生改变监听器
        lin01.addOnLayoutChangeListener(this);
    }
}

由于今天突发琐事较多,再加上编辑器卡,瞬间把想好咋写的就给我整没了,一股生无可恋的赶脚涌了上来!!!,那就先这些了,另外有个学习讨论的群!大家一起讨论哈哈!一起开车,与君共勉!。群号:188089649!转载请注明出处!谢谢! 本来按照国际惯例是有个Demo的,但是下班了,电脑编辑器卡了,来不及上,等闲暇时间在补,当然也可以加群找我要哦《搬砖小能手》


应一个小伙伴的要求写了个demo,于是顺便上传一下!,让你们久等了,FlowLayoutDemo


修改了下onMeasure的代码,修改后的demo(下载了原来demo小伙伴注意一下):FlowLayoutDemo

你可能感兴趣的:(widget)