Android 自定义控件之购物车数量加减器

一、实现思路

整个控件其实是由两个Button和一个EditText组成,直接上代码进行分析。初始化控件,设置了自定义属性(这几个自定义属性的作用大概通过名字也能够知道了)和设置监听器

二.实践

layout文件夹下

1.number_add_sub_view.xml自定义控件的布局

[java] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="wrap_content"  
  4.     android:layout_height="wrap_content"  
  5.     android:focusable="true"  
  6.     android:divider="@drawable/divider"  
  7.     android:background="@drawable/bg_amount_layout"  
  8.     android:showDividers="middle"  
  9.     android:orientation="horizontal"  
  10.     >  
  11.     <Button  
  12.         android:id="@+id/btnDecrease"  
  13.         android:layout_width="0dp"  
  14.         android:layout_height="match_parent"  
  15.         android:layout_weight="1"  
  16.         android:gravity="center"  
  17.         android:background="@drawable/btn_amount"  
  18.         android:text="-"/>  
  19.   
  20.     <EditText  
  21.         android:id="@+id/etAmount"  
  22.         android:layout_width="0dp"  
  23.         android:layout_height="match_parent"  
  24.         android:minWidth="60dp"  
  25.         android:layout_weight="2"  
  26.         android:background="@null"  
  27.         android:inputType="number"  
  28.         android:gravity="center"  
  29.         android:text="1"/>  
  30.   
  31.     <Button  
  32.         android:id="@+id/btnIncrease"  
  33.         android:layout_width="0dp"  
  34.         android:layout_height="match_parent"  
  35.         android:layout_weight="1"  
  36.         android:gravity="center"  
  37.         android:background="@drawable/btn_amount"  
  38.         android:text="+"/>  
  39. </LinearLayout>  

2.activity_main.xml

[java] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:app="http://schemas.android.com/apk/res-auto"  
  4.     xmlns:tools="http://schemas.android.com/tools"  
  5.     android:layout_width="match_parent"  
  6.     android:layout_height="match_parent"  
  7.     android:focusable="true"  
  8.     android:focusableInTouchMode="true"  
  9.     tools:context="xxx.addsubdemo.MainActivity">  
  10. //写自己的控件路径!!!  
  11.     <com.***.AmountView  
  12.         android:id="@+id/amount_view"  
  13.         android:layout_width="wrap_content"  
  14.         android:layout_height="36dp"  
  15.         android:layout_centerInParent="true"  
  16.         android:layout_gravity="right"  
  17.         android:layout_marginRight="15dp"  
  18.         app:btnTextSize="14sp"  
  19.         app:btnWidth="36dp"  
  20.         app:tvWidth="50dp"/>  
  21. </RelativeLayout>  

drawable文件夹下

1.bg_amount_layout.xml

[java] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <shape xmlns:android="http://schemas.android.com/apk/res/android">  
  3.   
  4.     <solid android:color="#FFFFFF" />  
  5.     <stroke  
  6.         android:width="1dp"  
  7.         android:color="@color/divider" />  
  8.     <padding  
  9.         android:bottom="1dp"  
  10.         android:left="1dp"  
  11.         android:right="1dp"  
  12.         android:top="1dp" />  
  13. </shape>  
2.btn_amount.xml

[java] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">  
  3.   
  4.     <item android:state_pressed="true" android:drawable="@color/divider" />  
  5.     <item android:state_enabled="false" android:drawable="@color/divider" />  
  6.     <item android:drawable="@android:color/white" />  
  7. </selector>  
3.divider.xml
[java] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <shape xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:shape="rectangle">  
  4.     <size  
  5.         android:width="0.5dp"/>  
  6.     <solid android:color="@color/divider"/>  
  7. </shape>  

values文件夹

1.自定义属性attrs.xml

[java] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.     <declare-styleable name="AmountView">  
  4.         <!-- 左右2边+-按钮的宽度 -->  
  5.         <attr name="btnWidth" format="dimension" />  
  6.         <!-- 中间TextView的宽度 -->  
  7.         <attr name="tvWidth" format="dimension" />  
  8.         <!--<attr name="tvColor" format="color"/>-->  
  9.         <attr name="tvTextSize" format="dimension"/>  
  10.         <attr name="btnTextSize" format="dimension"/>  
  11.     </declare-styleable>  
  12.   
  13. </resources>  
2.colors.xml,就一个颜色
[java] view plain copy
  1. <color name="divider">#ffd2d2d2</color>  
JAVA类;

1.AmountView.class自定义view类:

[java] view plain copy
  1. import android.content.Context;  
  2. import android.content.res.TypedArray;  
  3. import android.text.Editable;  
  4. import android.text.TextWatcher;  
  5. import android.util.AttributeSet;  
  6. import android.util.Log;  
  7. import android.util.TypedValue;  
  8. import android.view.LayoutInflater;  
  9. import android.view.View;  
  10. import android.widget.Button;  
  11. import android.widget.EditText;  
  12. import android.widget.LinearLayout;  
  13.   
  14. /** 
  15.  * Created by xue on 2017-11-22. 
  16.  */  
  17.   
  18. public class AmountView  extends LinearLayout implements View.OnClickListener, TextWatcher {  
  19.   
  20.     private static final String TAG = "AmountView";  
  21.     private int amount = 1//购买数量  
  22.     private int goods_storage = 1//商品库存  
  23.   
  24.     private OnAmountChangeListener mListener;  
  25.   
  26.     private EditText etAmount;  
  27.     private Button btnDecrease;  
  28.     private Button btnIncrease;  
  29.   
  30.     public AmountView(Context context) {  
  31.         super(context);  
  32.     }  
  33.   
  34.     public AmountView(Context context, AttributeSet attrs) {  
  35.         super(context, attrs);  
  36.   
  37.         LayoutInflater.from(context).inflate(R.layout.number_add_sub_view, this);  
  38.         etAmount = (EditText) findViewById(R.id.etAmount);  
  39.         btnDecrease = (Button) findViewById(R.id.btnDecrease);  
  40.         btnIncrease = (Button) findViewById(R.id.btnIncrease);  
  41.   
  42.         btnDecrease.setOnClickListener(this);  
  43.         btnIncrease.setOnClickListener(this);  
  44.         etAmount.addTextChangedListener(this);  
  45.   
  46.         TypedArray obtainStyledAttributes = getContext().obtainStyledAttributes(attrs, R.styleable.AmountView);  
  47.         int btnWidth = obtainStyledAttributes.getDimensionPixelSize(R.styleable.AmountView_btnWidth, LayoutParams.WRAP_CONTENT);  
  48.         int tvWidth = obtainStyledAttributes.getDimensionPixelSize(R.styleable.AmountView_tvWidth, 80);  
  49.         int tvTextSize = obtainStyledAttributes.getDimensionPixelSize(R.styleable.AmountView_tvTextSize, 0);  
  50.         int btnTextSize = obtainStyledAttributes.getDimensionPixelSize(R.styleable.AmountView_btnTextSize, 0);  
  51.         obtainStyledAttributes.recycle();  
  52.   
  53.         LayoutParams btnParams = new LayoutParams(btnWidth, LayoutParams.MATCH_PARENT);  
  54.         btnDecrease.setLayoutParams(btnParams);  
  55.         btnIncrease.setLayoutParams(btnParams);  
  56.         if (btnTextSize != 0) {  
  57.             btnDecrease.setTextSize(TypedValue.COMPLEX_UNIT_PX, btnTextSize);  
  58.             btnIncrease.setTextSize(TypedValue.COMPLEX_UNIT_PX, btnTextSize);  
  59.         }  
  60.   
  61.         LayoutParams textParams = new LayoutParams(tvWidth, LayoutParams.MATCH_PARENT);  
  62.         etAmount.setLayoutParams(textParams);  
  63.         if (tvTextSize != 0) {  
  64.             etAmount.setTextSize(tvTextSize);  
  65.         }  
  66.     }  
  67.   
  68.     public void setOnAmountChangeListener(OnAmountChangeListener onAmountChangeListener) {  
  69.         this.mListener = onAmountChangeListener;  
  70.     }  
  71.   
  72.     public void setGoods_storage(int goods_storage) {  
  73.         this.goods_storage = goods_storage;  
  74.     }  
  75.   
  76.     @Override  
  77.     public void onClick(View v) {  
  78.         int i = v.getId();  
  79.         if (i == R.id.btnDecrease) {  
  80.             if (amount > 1) {  
  81.                 amount--;  
  82.                 Log.d(TAG, "onClick:===== "+amount);  
  83.                 etAmount.setText(amount + "");  
  84.             }  
  85.         } else if (i == R.id.btnIncrease) {  
  86.             if (amount < goods_storage) {  
  87.                 amount++;  
  88.                 etAmount.setText(amount + "");  
  89.             }  
  90.         }  
  91.         //清除焦点  
  92.         etAmount.clearFocus();  
  93.   
  94.         if (mListener != null) {  
  95.             mListener.onAmountChange(this, amount);  
  96.         }  
  97.     }  
  98.   
  99.     @Override  
  100.     public void beforeTextChanged(CharSequence s, int start, int count, int after) {  
  101.   
  102.     }  
  103.   
  104.     @Override  
  105.     public void onTextChanged(CharSequence s, int start, int before, int count) {  
  106.   
  107.     }  
  108.   
  109.     @Override  
  110.     public void afterTextChanged(Editable s) {  
  111.         if (s.toString().isEmpty())  
  112.             return;  
  113.         amount = Integer.valueOf(s.toString());  
  114.         if (amount > goods_storage) {  
  115.             etAmount.setText(goods_storage + "");  
  116.             return;  
  117.         }  
  118.   
  119.         if (mListener != null) {  
  120.             mListener.onAmountChange(this, amount);  
  121.         }  
  122.     }  
  123.   
  124.   
  125.     public interface OnAmountChangeListener {  
  126.         void onAmountChange(View view, int amount);  
  127.     }  
  128.   
  129. }  
2.MainActivity
[java] view plain copy
  1. import android.support.v7.app.AppCompatActivity;  
  2. import android.os.Bundle;  
  3. import android.view.View;  
  4. import android.widget.Toast;  
  5.   
  6. public class MainActivity extends AppCompatActivity {  
  7.     private AmountView mAmountView;  
  8.     @Override  
  9.     protected void onCreate(Bundle savedInstanceState) {  
  10.         super.onCreate(savedInstanceState);  
  11.         setContentView(R.layout.activity_main);  
  12.   
  13.   
  14.         mAmountView = (AmountView) findViewById(R.id.amount_view);  
  15.         mAmountView.setGoods_storage(50);  
  16.         mAmountView.setOnAmountChangeListener(new AmountView.OnAmountChangeListener() {  
  17.             @Override  
  18.             public void onAmountChange(View view, int amount) {  
  19.                 Toast.makeText(getApplicationContext(), "Amount=>  " + amount, Toast.LENGTH_SHORT).show();  
  20.             }  
  21.         });  
  22.     }  
  23. }  
作者的Github下载

相关文章:

  • 2021-08-16
  • 2022-12-23
  • 2022-12-23
  • 2021-08-26
  • 2021-05-24
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-07-17
  • 2022-12-23
  • 2022-12-23
  • 2021-06-29
  • 2021-06-25
  • 2022-12-23
相关资源
相似解决方案