购物车商品数量的增加与减少与可以设置消息条数的TextView

用于简单的购物车商品数量的增加与减少

布局如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/bg_button_number"
        android:orientation="horizontal"
        android:weightSum="4">

        <TextView
            android:id="@+id/button_sub"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/bg_button_left"
            android:gravity="center"
            android:text="—"
            android:textColor="#000"
            android:minWidth="30dp"
            android:textSize="18sp"/>

        <EditText
            android:id="@+id/text_count"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="2"
            android:background="@null"
            android:cursorVisible="true"
            android:digits="0123456789"
            android:gravity="center"
            android:singleLine="true"
            android:inputType="number"
            android:minWidth="60dp"
            android:paddingBottom="3dp"
            android:paddingLeft="5dp"
            android:paddingRight="5dp"
            android:paddingTop="3dp"
            android:text="555"
            android:textColor="#000"
            android:textCursorDrawable="@null"
            android:focusable="false"/>

        <TextView
            android:id="@+id/button_add"
            android:layout_width="0dp"
            android:minWidth="30dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/bg_button_right"
            android:gravity="center"
            android:text="+"
            android:textColor="#000"
            android:textSize="18sp"/>
    </LinearLayout>

</LinearLayout>

整个布局背景: bg_button_number.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <stroke android:width="1dp" android:color="#999"/>
    <solid android:color="#ffffff"/>
    <corners android:radius="3dp"/>
</shape>

左边"—"的背景

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <solid android:color="#ffffff"/>
    <stroke android:width="1dp" android:color="#999"/>
    <corners android:topLeftRadius="3dp" android:bottomLeftRadius="3dp"/>
</shape>

右边"+"的背景

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <solid android:color="#ffffff"/>
    <stroke android:width="1dp" android:color="#999"/>
    <corners android:topRightRadius="3dp" android:bottomRightRadius="3dp"/>
</shape>

效果图:

可以设置消息条数的TextView并且可以用于需要圆角矩形框背景的TextView的情况,减少直接使用TextView时引入的shape资源文件

1.可设置背景为弧形矩形、圆形、可设置消息条数与显示消息红点的TextView

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.StateListDrawable;
import android.os.Build;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

/** 用于需要圆角矩形框背景的TextView的情况,减少直接使用TextView时引入的shape资源文件 */
public class MsgView extends TextView {
    private Context context;
    private GradientDrawable gd_background = new GradientDrawable();
    private int backgroundColor;
    private int cornerRadius;
    private int strokeWidth;
    private int strokeColor;
    private boolean isRadiusHalfHeight;
    private boolean isWidthHeightEqual;

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

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

    public MsgView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        obtainAttributes(context, attrs);
    }

    private void obtainAttributes(Context context, AttributeSet attrs) {
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MsgView);
        backgroundColor = ta.getColor(R.styleable.MsgView_mv_backgroundColor, Color.TRANSPARENT);
        cornerRadius = ta.getDimensionPixelSize(R.styleable.MsgView_mv_cornerRadius, 0);
        strokeWidth = ta.getDimensionPixelSize(R.styleable.MsgView_mv_strokeWidth, 0);
        strokeColor = ta.getColor(R.styleable.MsgView_mv_strokeColor, Color.TRANSPARENT);
        isRadiusHalfHeight = ta.getBoolean(R.styleable.MsgView_mv_isRadiusHalfHeight, false);
        isWidthHeightEqual = ta.getBoolean(R.styleable.MsgView_mv_isWidthHeightEqual, false);

        ta.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (isWidthHeightEqual() && getWidth() > 0 && getHeight() > 0) {
            int max = Math.max(getWidth(), getHeight());
            int measureSpec = MeasureSpec.makeMeasureSpec(max, MeasureSpec.EXACTLY);
            super.onMeasure(measureSpec, measureSpec);
            return;
        }

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        if (isRadiusHalfHeight()) {
            setCornerRadius(getHeight() / 2);
        } else {
            setBgSelector();
        }
    }


    public void setBackgroundColor(int backgroundColor) {
        this.backgroundColor = backgroundColor;
        setBgSelector();
    }

    public void setCornerRadius(int cornerRadius) {
        this.cornerRadius = dp2px(cornerRadius);
        setBgSelector();
    }

    public void setStrokeWidth(int strokeWidth) {
        this.strokeWidth = dp2px(strokeWidth);
        setBgSelector();
    }

    public void setStrokeColor(int strokeColor) {
        this.strokeColor = strokeColor;
        setBgSelector();
    }

    public void setIsRadiusHalfHeight(boolean isRadiusHalfHeight) {
        this.isRadiusHalfHeight = isRadiusHalfHeight;
        setBgSelector();
    }

    public void setIsWidthHeightEqual(boolean isWidthHeightEqual) {
        this.isWidthHeightEqual = isWidthHeightEqual;
        setBgSelector();
    }

    public int getBackgroundColor() {
        return backgroundColor;
    }

    public int getCornerRadius() {
        return cornerRadius;
    }

    public int getStrokeWidth() {
        return strokeWidth;
    }

    public int getStrokeColor() {
        return strokeColor;
    }

    public boolean isRadiusHalfHeight() {
        return isRadiusHalfHeight;
    }

    public boolean isWidthHeightEqual() {
        return isWidthHeightEqual;
    }

    protected int dp2px(float dp) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dp * scale + 0.5f);
    }

    protected int sp2px(float sp) {
        final float scale = this.context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (sp * scale + 0.5f);
    }

    private void setDrawable(GradientDrawable gd, int color, int strokeColor) {
        gd.setColor(color);
        gd.setCornerRadius(cornerRadius);
        gd.setStroke(strokeWidth, strokeColor);
    }

    public void setBgSelector() {
        StateListDrawable bg = new StateListDrawable();

        setDrawable(gd_background, backgroundColor, strokeColor);
        bg.addState(new int[]{-android.R.attr.state_pressed}, gd_background);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {//16
            setBackground(bg);
        } else {
            //noinspection deprecation
            setBackgroundDrawable(bg);
        }
    }

    /**
     * 设置消息条数
     * @param num
     */
    public void show(int num) {
        ViewGroup.LayoutParams lp = this.getLayoutParams();
        DisplayMetrics dm = this.getResources().getDisplayMetrics();
        this.setVisibility(View.VISIBLE);
        if (num <= 0) {// 圆点,设置默认宽高
            this.setStrokeWidth(0);
            this.setText("");

            lp.width = (int) (5 * dm.density);
            lp.height = (int) (5 * dm.density);
            this.setLayoutParams(lp);
        } else {
            lp.height = (int) (18 * dm.density);
            if (num > 0 && num < 10) {//
                lp.width = (int) (18 * dm.density);
                //this.setPadding((int) (5 * dm.density), 0, (int) (5 * dm.density), 0);
                this.setPadding(0, 0, 0, 0);
                this.setText(num + "");
            } else if (num > 9 && num < 100) {// 圆角矩形,圆角是高度的一半,设置默认padding
                lp.width = ViewGroup.LayoutParams.WRAP_CONTENT;
                this.setPadding((int) (6 * dm.density), 0, (int) (6 * dm.density), 0);
                this.setText(num + "");
            } else {// 数字超过两位,显示99+
                lp.width = ViewGroup.LayoutParams.WRAP_CONTENT;
                this.setPadding((int) (6 * dm.density), 0, (int) (6 * dm.density), 0);
                this.setText("99+");
            }
            this.setLayoutParams(lp);
        }
    }

}
View Code

2.自定义属性值

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- 用于需要圆角矩形框背景的TextView的情况,减少直接使用TextView时引入的shape资源文件 -->
    <declare-styleable name="MsgView">
        <!-- 圆角背景色 -->
        <attr name="mv_backgroundColor" format="color" />
        <!-- 圆角弧度,单位dp -->
        <attr name="mv_cornerRadius" format="dimension" />
        <!-- 圆角边框弧度,单位dp -->
        <attr name="mv_strokeWidth" format="dimension" />
        <!-- 圆角边框颜色 -->
        <attr name="mv_strokeColor" format="color" />
        <!-- 圆角弧度是高度的一半 -->
        <attr name="mv_isRadiusHalfHeight" format="boolean" />
        <!-- 圆角矩形宽高相等,取较宽高中大值-->
        <attr name="mv_isWidthHeightEqual" format="boolean" />
    </declare-styleable>
</resources>

使用-布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffcccc"
    android:orientation="vertical"
    android:gravity="center"
    tools:context="com.robusttest.MainActivity">

    <com.robusttest.MsgView
        xmlns:mv="http://schemas.android.com/apk/res-auto"
        android:id="@+id/msg1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textColor="#ffffff"
        android:textSize="13sp"
        android:padding="8dp"
        android:text="我是可以设置消息条数的TextView"
        mv:mv_backgroundColor="#FD481F"
        mv:mv_isRadiusHalfHeight="false"
        mv:mv_isWidthHeightEqual="true"
        mv:mv_cornerRadius="20dp"
        mv:mv_strokeColor="#ffffff"
        mv:mv_strokeWidth="1dp" />

    <com.robusttest.MsgView
        xmlns:mv="http://schemas.android.com/apk/res-auto"
        android:id="@+id/msg2"
        android:layout_marginTop="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textColor="#ffffff"
        android:textSize="13sp"
        android:padding="8dp"
        android:text="我是可以设置消息条数的TextView"
        mv:mv_backgroundColor="#FD481F"
        mv:mv_isRadiusHalfHeight="true"
        mv:mv_isWidthHeightEqual="true"
        mv:mv_cornerRadius="20dp"
        mv:mv_strokeColor="#ffffff"
        mv:mv_strokeWidth="1dp" />

    <com.robusttest.MsgView
        xmlns:mv="http://schemas.android.com/apk/res-auto"
        android:id="@+id/msg3"
        android:layout_marginTop="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textColor="#ffffff"
        android:textSize="13sp"
        android:padding="8dp"
        android:text="我是可以设置消息条数的TextView"
        mv:mv_backgroundColor="#FD481F"
        mv:mv_isRadiusHalfHeight="false"
        mv:mv_isWidthHeightEqual="false"
        mv:mv_cornerRadius="20dp"
        mv:mv_strokeColor="#ffffff"
        mv:mv_strokeWidth="1dp" />

</LinearLayout>

效果图:

 设置消息条数:

msgView1 = (MsgView) findViewById(R.id.msg1);
        msgView2 = (MsgView) findViewById(R.id.msg2);
        msgView3 = (MsgView) findViewById(R.id.msg3);
        //设置消息条数
        msgView1.show(0);
        msgView2.show(5);
        msgView3.show(55);

效果图:分别对应着消息条数为0(未读消息),一位,两位数,三位数时的效果

 

posted @ 2017-06-14 15:11  ts-android  阅读(481)  评论(0)    收藏  举报