android 4-3排列的流式布局(直接上代码,原创)

import android.content.Context;
import android.graphics.Color;
import android.support.annotation.DrawableRes;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.android.yazm.mylibrary.utils.UIUtils;
import com.android.yazm.yiaizhiming.bean.MyGroupCheckedBean;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by fanqibo on 2018/1/22.
 */

public class NoNameViewGroup extends ViewGroup implements View.OnClickListener {
    private ArrayList<MyGroupCheckedBean> arrayList = new ArrayList<>();
    private ArrayList<String> mList = new ArrayList<>();
    private ArrayList<MyGroupCheckedBean> addNewTagList = new ArrayList<>();

    //获取的默认间距;depadding是算出来的
    private int depadding = -1;
    private int depaddingHeight;
    //最好在dimens做下适配
    private int width = UIUtils.dp2px(getContext(), 64);
    private int height = UIUtils.dp2px(getContext(), 50) / 2;

    public NoNameViewGroup(Context context) {
        super(context);
    }

    public NoNameViewGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    private void getdpding(int gwidth, int childWidth, int cl, int cr) {
        int allwidth = gwidth - cl - cr;
        if (childWidth * 4 < allwidth) {
            depadding = (allwidth - childWidth * 4) / 3;
        }
        depaddingHeight = depadding / 2;
    }

    @IntDef({AddLocation.LOCATION_UP, AddLocation.LOCATION_DOWN})
    @Retention(RetentionPolicy.SOURCE)
    public @interface AddLocation {
        int LOCATION_UP = 1;
        int LOCATION_DOWN = 2;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        measureChildren(widthMeasureSpec, heightMeasureSpec);
        int mViewGroupWidth = getMeasuredWidth();
        int allwidth = mViewGroupWidth - getPaddingLeft() - getPaddingRight();
        if (depadding == -1) {
            depadding = (allwidth - width * 4) / 3;
        }
        int h = Math.max((getChildCount() / 7 + 1) * 2 * (depadding / 2 + height) + topMargin + bottomMargin, heightMeasureSpec);
        Log.e("getChildCount():" + getChildCount() + "/", "h:" + h + "/" + "depadding:" + depadding + "/" + " + height:" + height);
        setMeasuredDimension(widthMeasureSpec, h);
    }

    private void initView(String string, int pos, boolean select) {
        TextView textView = new TextView(getContext());
        textView.setGravity(Gravity.CENTER);
        textView.setWidth(width);
        textView.setHeight(height);
        textView.setText(string);
        textView.setTextSize(12);
        textView.setBackgroundResource(select ? R.drawable.lable_select : R.drawable.lable_normal);
        textView.setTextColor(Color.BLACK);
        textView.setOnClickListener(this);
        if (pos == -1) {
            addView(textView);
        } else {
            addView(textView, pos);
        }
    }

    public void addViews(@NonNull ArrayList<MyGroupCheckedBean> list) {
        for (int i = 0; i < list.size(); i++) {
            MyGroupCheckedBean bean = new MyGroupCheckedBean();
//            bean.setB(list.get(i).isB());
            bean.setString(list.get(i).getString());
            this.arrayList.add(bean);
            initView(bean.getString(), i, false);
        }
    }
    public void addTagView(String text){
        addTagView(AddLocation.LOCATION_UP,text,true);
    }
    public void addTagView(String text, boolean select){
        addTagView(AddLocation.LOCATION_UP,text,select);
    }
    public void addTagView(@AddLocation int addLocation, String text, boolean select) {
        if (isHadTag(text)) {
            Log.e("hadText", "hahaha");
            if (listener != null) {
                listener.isHad(true);
            }
        } else {
            if (select && canChecked()) {
                if (addLocation == AddLocation.LOCATION_UP) {
                    addNewTagList.add(new MyGroupCheckedBean(true, text,false));
                    arrayList.add(0, new MyGroupCheckedBean(true, text,false));
                    initView(text, 0, true);
                } else {
                    addNewTagList.add(new MyGroupCheckedBean(true, text,false));
                    arrayList.add(new MyGroupCheckedBean(true, text,false));
                    initView(text, -1, true);
                }

            } else if (!select) {
                if (addLocation == AddLocation.LOCATION_UP) {
                    addNewTagList.add(new MyGroupCheckedBean(false, text,false));
                    arrayList.add(0, new MyGroupCheckedBean(false, text,false));
                    initView(text, 0, false);
                } else {
                    addNewTagList.add(new MyGroupCheckedBean(false, text,false));
                    arrayList.add(new MyGroupCheckedBean(false, text,false));
                    initView(text, -1, false);
                }
            } else if (!canChecked()) {
                if (listener != null) {
                    listener.isMax(true);
                }
                if (addLocation == AddLocation.LOCATION_UP) {
                    addNewTagList.add(new MyGroupCheckedBean(false, text,false));
                    arrayList.add(0, new MyGroupCheckedBean(false, text,false));
                    initView(text, 0, false);
                } else {
                    addNewTagList.add(new MyGroupCheckedBean(false, text,false));
                    arrayList.add(new MyGroupCheckedBean(false, text,false));
                    initView(text, -1, false);
                }
            }
        }
    }


    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        Log.e("onlayout", "布局重绘制");
        hang = 1;
        int mViewGroupWidth = getMeasuredWidth();  //当前ViewGroup的总宽度
        int paddingLeft = getPaddingLeft();
        int paddingRight = getPaddingRight();

        int childCount = getChildCount();
        Log.e("childCount", childCount + "");

        for (int i = 0; i < childCount; i++) {
            View childView = getChildAt(i);
            getdpding(mViewGroupWidth, width, paddingLeft, paddingRight);
            initChild(childView, mViewGroupWidth, i + 1, l, t, r, b);
        }
    }

    private int hang = 1;
    private int doubleLeft;
    private int doubleRight;
    private int topMargin = 30;
    private int bottomMargin = 30;

    private void initChild(View cv, int dadw, int count, int l, int t, int r, int b) {
        t = 0;
        doubleRight = doubleLeft = (dadw - 3 * width - 2 * depadding) / 2;
        int zuo = 0;
        int shang = 0;
        int you = 0;
        int xia = 0;

        switch (count % 7) {
            case 1:
                zuo = l;
                you = zuo + width;
                if (count / 7 < 1) {
                    shang = topMargin + t;

                } else {
                    shang = t + topMargin + (depaddingHeight + height) * (hang - 1);
                }
                xia = shang + height;
                cv.layout(zuo + getPaddingLeft(), shang + getPaddingTop(), you + getPaddingLeft(), xia + getPaddingTop());
                break;
            case 2:
                zuo = l + depadding + width;
                you = l + depadding + 2 * width;
                if (count / 7 < 1) {
                    shang = topMargin + t;

                } else {
                    shang = t + topMargin + (depaddingHeight + height) * (hang - 1);
                }
                xia = shang + height;
                cv.layout(zuo + getPaddingLeft(), shang + getPaddingTop(), you + getPaddingLeft(), xia + getPaddingTop());
                break;
            case 3:
                zuo = l + 2 * depadding + 2 * width;
                you = l + 2 * depadding + 3 * width;
                if (count / 7 < 1) {
                    shang = topMargin + t;

                } else {
                    shang = t + topMargin + (depaddingHeight + height) * (hang - 1);
                }
                xia = shang + height;
                cv.layout(zuo + getPaddingLeft(), shang + getPaddingTop(), you + getPaddingLeft(), xia + getPaddingTop());
                break;

            case 4:
                zuo = l + 3 * depadding + 3 * width;
                you = l + 3 * depadding + 4 * width;
                if (count / 7 < 1) {
                    shang = topMargin + t;

                } else {
                    shang = t + topMargin + (depaddingHeight + height) * (hang - 1);
                }
                xia = shang + height;
                hang += 1;
                cv.layout(zuo + getPaddingLeft(), shang + getPaddingTop(), you + getPaddingLeft(), xia + getPaddingTop());
                break;
            case 5:
                zuo = l + doubleLeft;
                you = l + width + doubleLeft;
                shang = t + topMargin + (depaddingHeight + height) * (hang - 1);
                xia = shang + height;

                cv.layout(zuo, shang + getPaddingTop(), you, xia + getPaddingTop());
                break;
            case 6:
                zuo = l + width + doubleLeft + depadding;
                you = l + 2 * width + doubleLeft + depadding;
                shang = t + topMargin + (depaddingHeight + height) * (hang - 1);
                xia = shang + height;
                cv.layout(zuo, shang + getPaddingTop(), you, xia + getPaddingTop());
                break;
            case 0:
                zuo = l + 2 * width + doubleLeft + 2 * depadding;
                you = l + 3 * width + doubleLeft + 2 * depadding;
                shang = t + topMargin + (depaddingHeight + height) * (hang - 1);
                xia = shang + height;
                hang += 1;
                cv.layout(zuo, shang + getPaddingTop(), you, xia + getPaddingTop());
                break;
        }
    }

    int max = -1;

    private boolean canChecked() {
        return max == -1 || !arrayList.isEmpty() && getListSize() <= max;
    }

    private int getListSize() {
        int a = 0;
        for (MyGroupCheckedBean bean : arrayList) {
            if (bean.isB()) {
                a += 1;
            }
        }
        return a;
    }

    //是否有重复的标签
    private boolean isHadTag(String s) {
        for (MyGroupCheckedBean bean:arrayList){
            if (bean.getString().equals(s)){
                return true;
            }
        }
        return false;
    }

    //获取选中标签集合
    public ArrayList<String> getTagList() {

        for (MyGroupCheckedBean bean : arrayList) {
            if (bean.isB()) {
                mList.add(bean.getString());

            }
        }
        return mList;
    }
    //获取选中标签集合
    public ArrayList<MyGroupCheckedBean> getAllTagList() {
        for (MyGroupCheckedBean bean : arrayList) {
            if (!bean.isB()&&!bean.isBelongToDefault()) {
                arrayList.remove(bean.getString());
            }
        }
        return arrayList;
    }
    //设置最大标签限制
    public void setMaxChoose(int max) {
        if (max < arrayList.size()) {
            this.max = max;
        }
    }
    private int getPosition(String s){
       for (int i=0;i<arrayList.size();i++){
            if (arrayList.get(i).getString().equals(s)){
                return i;
            }
       }
       return -1;
    }
    @Override
    public void onClick(View v) {

        TextView textView = (TextView) v;
        int tag = getPosition(textView.getText().toString());
        if (tag==-1){
            return;
        }
        boolean b = arrayList.get(tag).isB();
        if (b) {
            textView.setBackgroundResource(mBg_u);
            arrayList.get(tag).setB(false);
            if (listener != null) {
                listener.isMax(false);
                listener.itemSelect(textView.getText().toString());
            }
        } else {
            if (listener != null) {
                listener.itemSelect(textView.getText().toString());
            }
            if (canChecked()) {
                textView.setBackgroundResource(mBg_s);
                arrayList.get(tag).setB(true);
            } else {
                if (listener != null) {
                    listener.isMax(true);
                }
            }
        }
    }

    private int mBg_s = R.drawable.lable_select;//选中

    public void setBackGroundSelect(@DrawableRes int res) {
        mBg_s = res;
    }

    private int mBg_u = R.drawable.lable_normal;//未选中

    public void setBackGroundUnSelect(@DrawableRes int res) {
        mBg_u = res;
    }

    private OnGroupSelectListener listener;

    public void setListener(OnGroupSelectListener listener) {
        this.listener = listener;
    }

    public interface OnGroupSelectListener {
        //每次点击得到的
        public void itemSelect(String text);

        //是否达到了最大值
        public void isMax(boolean b);

        //是否有同名的标签
        public void isHad(boolean b);

    }
}
支持套scrollview ,不支持在xml里写布局,支持padding,不支持吗,margin,
套scrollview 注意一点,android:fillViewport="true"
动态添加的时候方法如下
for (int i=0;i<200;i++){
    arrayList.add(new MyGroupCheckedBean(false,i+"",true));
}
NoNameViewGroup n=findViewById(R.id.group);
n.addViews(arrayList);
n.setMaxChoose(20);
n.setListener(this);
public class MyGroupCheckedBean {
    private boolean b;
    private String string;
    private boolean belongToDefault;//这个是防止原有标签和动态添加标签的时候做区分

    public MyGroupCheckedBean() {
    }

    public MyGroupCheckedBean(boolean b, String string,boolean belongToDefault) {
        this.b = b;
        this.string = string;
        this.belongToDefault=belongToDefault;
    }

    public boolean isB() {
        return b;
    }

    public void setB(boolean b) {
        this.b = b;
    }

    public String getString() {
        return string;
    }

    public void setString(String string) {
        this.string = string;
    }

    public boolean isBelongToDefault() {
        return belongToDefault;
    }

    public void setBelongToDefault(boolean belongToDefault) {
        this.belongToDefault = belongToDefault;
    }

如有问题请私信,或留言

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值