搜索項/篩選佈局

》導讀:

自定義ViewGroup實現展示搜索條目或篩選
這裏寫圖片描述

》控件:

/**
 * Created by Kvin on 2017/2/5.
 */
public class ChoiceLayout extends ViewGroup {

    private TextView tv;
    private final int TYPE_TITLE = 1;
    private int marginLeft = 20;
    private final int marginTop = 20;
    private final Rect childRect = new Rect();
    private DisplayMetrics mMetrics;
    private int lineNum;

    private OnChoiceClickListener mOnChoiceClickListener;


    //attr
    private int verSpace;
    private int horSpace;
    private float txtSize;
    private int choiceTheme;

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

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

    /**
     * init attr
     */
    private void initAttr(Context context, AttributeSet attrs) {

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ChoiceLayout);
        verSpace = typedArray.getDimensionPixelSize(R.styleable.ChoiceLayout_clVerSpace, 10);
        horSpace = typedArray.getDimensionPixelSize(R.styleable.ChoiceLayout_clHorSpace, 5);
        txtSize = typedArray.getDimension(R.styleable.ChoiceLayout_clTxtSize, 5);
        choiceTheme = typedArray.getInt(R.styleable.ChoiceLayout_clChoiceTheme, Theme.RED.value);

        typedArray.recycle();

    }

    public ChoiceLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public ChoiceLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    /**
     * add children and init
     */
    public void init(Context context, ArrayList<String> data) {
        if (context == null || ListUtils.isEmpty(data)) return;
        mMetrics = MetricsUtils.winMetrics(context);
        for (String item : data) {
            tv = new TextView(context);
            setTheme(choiceTheme, tv);
            tv.setText(item);
            tv.setGravity(Gravity.CENTER);
            tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, txtSize);
            addView(tv);
        }

        postInvalidate();

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        measureChildren(widthMeasureSpec, heightMeasureSpec);//don`t forget
        setMeasuredDimension(widthMeasureSpec, childRect.bottom + 40);//set last child`s bottom as total height

//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        View child = null;
        boolean is = changed;
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            child = getChildAt(i);
            child.setTag(i);
            child.setOnClickListener(mOnClickListener);
            if (i == 0) {
                calculateMarginLeft(i);
                childRect.left = marginLeft;
                childRect.top = marginTop;
                childRect.right = marginLeft + child.getMeasuredWidth();
                childRect.bottom = marginTop + child.getMeasuredHeight();

            } else if (childRect.right + horSpace + child.getMeasuredWidth() <= getWidth()) {
                //layout right
                childRect.left = childRect.right + horSpace;
                childRect.right = childRect.left + child.getMeasuredWidth();
                childRect.bottom = childRect.top + child.getMeasuredHeight();
            } else {
                //line feed
                calculateMarginLeft(i);
                childRect.left = marginLeft;
                childRect.top = childRect.bottom + verSpace;
                childRect.right = marginLeft + child.getMeasuredWidth();
                childRect.bottom = childRect.top + child.getMeasuredHeight();
                lineNum++;
            }
            chooseTheme(lineNum / 2);
            setTheme(choiceTheme, (TextView) child);
            //layout child
            child.layout(childRect.left, childRect.top, childRect.right, childRect.bottom);
        }
    }

    /**
     * choose a direct theme
     *
     * @param index
     */
    private void chooseTheme(int index) {
        choiceTheme = index;
    }

    /**
     * @return a random num (<=3)
     */
    private int setTheme() {
        int ran = (int) (Math.random() * 10 / 3);
        return ran;
    }


    /**
     * calculate marginLeft
     *
     * @param position
     */
    private void calculateMarginLeft(int position) {
        int i = 0;
        int count = getChildCount();
        int totalW = getTotalWidth(position, i);
        while (totalW <= getWidth()) {
            i++;
            if (i >= count - position) break;
            totalW = getTotalWidth(position, i + 1);
        }
        marginLeft = (getWidth() - getTotalWidth(position, i)) / 2;
    }

    /**
     * measure child total w
     *
     * @param position
     * @param n
     * @return
     */
    private int getTotalWidth(int position, int n) {
        int w = getChildAt(position).getMeasuredWidth();
        for (int i = 1; i < n; i++) {
            w += horSpace + getChildAt(position + i).getMeasuredWidth();
        }
        return w;
    }


    /**
     * title layout params
     */
    public LayoutParams getTitleLayoutParams() {
        LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
        return params;
    }

    /**
     * choice layout params
     */
    public LayoutParams getChoiceLayoutParams() {
        LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        return params;
    }

    /**
     * child view click
     */
    private OnClickListener mOnClickListener = new OnClickListener() {
        @Override
        public void onClick(View view) {
            if (mOnChoiceClickListener != null)
                mOnChoiceClickListener.onChoiceClick(view, (Integer) view.getTag());
        }
    };

    /**
     * set on item click listener
     */

    public void setOnChoiceClickListener(OnChoiceClickListener mOnChoiceClickListener) {
        this.mOnChoiceClickListener = mOnChoiceClickListener;
    }

    /**
     * set theme for textViews
     * you can define by yourself
     */
    private void setTheme(int theme, TextView tv) {
        switch (theme) {
            case 0:
                tv.setBackgroundResource(R.drawable.choice_red_bg);
                tv.setTextColor(getResources().getColor(R.color.choice_red_bg));
                break;
            case 1:
                tv.setBackgroundResource(R.drawable.choice_yellow_bg);
                tv.setTextColor(getResources().getColor(R.color.choice_yellow_bg));
                break;
            case 2:
                tv.setBackgroundResource(R.drawable.choice_green_bg);
                tv.setTextColor(getResources().getColor(R.color.choice_green_bg));
                break;
            case 3:
                tv.setBackgroundResource(R.drawable.choice_blue_bg);
                tv.setTextColor(getResources().getColor(R.color.choice_blue_bg));
                break;

        }

    }

    public void setTheme(Theme theme, TextView tv) {
        setTheme(theme.value, tv);
    }

    public enum Theme {
        RED(0), YELLOW(1), GREEN(2), BLUE(3);

        private int value;

        Theme(int value) {
            this.value = value;
        }
    }

    /**
     * choice click listener
     */
    public interface OnChoiceClickListener {
        void onChoiceClick(View view, int position);
    }
}

》屬性:

 <!--Choice layout -->
    <declare-styleable name="ChoiceLayout">
        <attr name="clVerSpace" format="dimension" />
        <attr name="clHorSpace" format="dimension" />
        <attr name="clTxtSize" format="dimension" />
        <attr name="clChoiceTheme">
            <enum name="themeRed" value="0" />
            <enum name="themeYellow" value="1" />
            <enum name="themeGreen" value="2" />
            <enum name="themeBlue" value="3" />
        </attr>
    </declare-styleable>

》使用式樣:

1.在xml中

 <com.kvin.toolkit.widget.ChoiceLayout
        android:id="@+id/history_cl"
        app:clHorSpace="5dp"
        app:clVerSpace="10dp"
        app:clTxtSize="16sp"
        android:layout_below="@+id/history_tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

2.在java代碼中

 this.historyCl = (ChoiceLayout) findViewById(R.id.history_cl);
 this.historyCl.init(this, hisItems);//hisItems爲歷史字段集合
 his.historyCl.setOnChoiceClickListener(mHistoryChoiceClickListener);//監聽

》討論:

有什麼想法,請大家留言;一起學習,一起進步。

發佈了37 篇原創文章 · 獲贊 3 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章