一、自定义组合控件介绍
开发中,为了使用的方便,经常把一些控件组合成一个控件,那样就成为了我们的自定义组合控件,严格意义来说,自定义组合控件并不属于“自定义控件”。
二、自定义组合控件步骤 1、创建一个java类,继承View(或者View的子类),改写构造函数。如下所示,NumberAddSubView是我们的自定义组合控件的名字。通过构造函数的改造,使得一个调用另外一个,最终我们只要修改的是参数最多的那个就可以了。
public NumberAddSubView(Context context) { this(context, null); } public NumberAddSubView(Contextcontext, AttributeSet attrs) { this(context, attrs, 0); } public NumberAddSubView(Contextcontext, AttributeSet attrs, intdefStyleAttr) { super(context, attrs, defStyleAttr); }
2、为这个自定义组合控件创建一个布局:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/shape_number_view_bg" android:gravity="center" android:orientation="horizontal" android:padding="5dp"> <Button android:id="@+id/btn_sub" style="@style/NumberAddSubDefStyle" android:gravity="center" android:text="-"/> <EditText android:id="@+id/et_num" style="@style/TextDefStyle" /> <Button android:id="@+id/btn_add" style="@style/NumberAddSubDefStyle" android:gravity="center" android:text="+"/> </LinearLayout>
3、加载布局,通过ID找到所有控件。
private void initView(Context context) { View view = LayoutInflater.from(context).inflate(R.layout.number_add_sub_view, this, true); btn_add = (Button) view.findViewById(R.id.btn_add); btn_sub = (Button) view.findViewById(R.id.btn_sub); et_num = (EditText) view.findViewById(R.id.et_num); btn_add.setOnClickListener(this); btn_sub.setOnClickListener(this); et_num.addTextChangedListener(this); } 4、自定义属性:在value文件夹创建attrs.xml文件,并且添加自定义属性: <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="NumberAddSubView"> <attr name="value" format="integer|reference"/> <attr name="maxValue" format="integer|reference"/> <attr name="minValue" format="integer|reference"/> <attr name="btnDrawable" format="reference"/> </declare-styleable> </resources> 5、最后,在自定义控件里面做一切你想做的事情,例如按钮点击回调,文字变化回调等。 下面是菜鸟商城项目中的需求: 自定义数字加减控件 1.输入框只能是数字,且不能通过键盘输入 2.通过加减按钮操作数字 3.监听加减按钮 4.数字有最小值和最大值的限制 5.自定义属性 下面给出完整的java代码: import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; import android.support.v7.widget.TintTypedArray; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.LinearLayout; /** * 自定义数字加减控件 */ public class NumberAddSubView extendsLinearLayout implements View.OnClickListener, TextWatcher { private int maxValue; private int minValue; private int value; private Button btn_add; private Button btn_sub; private EditText et_num; public NumberAddSubView(Contextcontext) { this(context, null); } public NumberAddSubView(Contextcontext, AttributeSet attrs) { this(context, attrs, 0); } public NumberAddSubView(Contextcontext, AttributeSet attrs, intdefStyleAttr) { super(context, attrs, defStyleAttr); //初始化布局 initView(context); //读取自定义属性的值并且设置 TintTypedArray a = TintTypedArray.obtainStyledAttributes(context, attrs, R.styleable.NumberAddSubView, defStyleAttr, 0); value = a.getInt(R.styleable.NumberAddSubView_value, 1); maxValue = a.getInt(R.styleable.NumberAddSubView_maxValue, 1); minValue = a.getInt(R.styleable.NumberAddSubView_minValue, 1); Drawable btnBg = a.getDrawable(R.styleable.NumberAddSubView_btnDrawable); if (btnBg != null) { btn_add.setBackgroundDrawable(btnBg); btn_sub.setBackgroundDrawable(btnBg); } a.recycle(); } private void initView(Context context) { View view = LayoutInflater.from(context).inflate(R.layout.number_add_sub_view, this, true); btn_add = (Button) view.findViewById(R.id.btn_add); btn_sub = (Button) view.findViewById(R.id.btn_sub); et_num = (EditText) view.findViewById(R.id.et_num); btn_add.setOnClickListener(this); btn_sub.setOnClickListener(this); et_num.addTextChangedListener(this); } /** * 数字变化的监听 */ public interface OnNumberChangeListener { void onChange(int value, boolean isInRange); } private OnNumberChangeListener mListener; public void setOnNumberChangeListener(OnNumberChangeListener listener) { this.mListener = listener; } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if (mListener != null) { if (!TextUtils.isEmpty(s)) { int val = Integer.parseInt(s.toString()); if (val <= maxValue && val >= minValue) { mListener.onChange(val, true); } else { mListener.onChange(val, false); } } } } @Override public void afterTextChanged(Editable s) { } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_add: valueAdd(); break; case R.id.btn_sub: valueSub(); break; } } public void valueAdd() { if (!TextUtils.isEmpty(et_num.getText())) { int val = Integer.parseInt(et_num.getText().toString()); if (val < maxValue) { val++; } setValue(val); } } public void valueSub() { if (!TextUtils.isEmpty(et_num.getText())) { int val = Integer.parseInt(et_num.getText().toString()); if (val > minValue) { val--; } setValue(val); } } public int getMaxValue() { return maxValue; } public void setMaxValue(int maxValue) { this.maxValue = maxValue; } public int getMinValue() { return minValue; } public void setMinValue(int minValue) { this.minValue = minValue; } public int getValue() { return value; } public void setValue(int value) { this.value = value; et_num.setText(value + ""); } public void setRange(int minValue, int maxValue) { this.minValue = minValue; this.maxValue = maxValue; } }
三、自定义组合控件的使用 根据自己如何定义,使用的方法都不一样。例如我在自定义控件里面添加了文字变化的回调,那么我们就可以进行监听。
不过大体来说,跟基本控件以及“自定义控件”的使用一模一样。
1、在布局文件中放置自定义组合控件:
需要注意的是,命名空间需要自定义一个,随便写“app”即可,至于写什么没有要求,但是它的值需要使用res-auto。
注意添加上我们自定义的属性。
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/holo_green_light"> <com.nan.numaddsubview.NumberAddSubView android:id="@+id/num_view" android:layout_width="wrap_content" android:layout_height="wrap_content" app:maxValue="5" app:minValue="1" app:value="1"/> </RelativeLayout>
2、java代码中的使用:
这里我设置文字变化的监听。
public class MainActivity extendsAppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); NumberAddSubView numberAddSubView = (NumberAddSubView) findViewById(R.id.num_view); // numberAddSubView.setMaxValue(10); numberAddSubView.setOnNumberChangeListener(new NumberAddSubView.OnNumberChangeListener() { @Override public void onChange(int value, boolean isInRange) { Toast.makeText(MainActivity.this, value + "" + isInRange, Toast.LENGTH_SHORT).show(); } }); } }
四、效果 为了方便看,我把activity的背景颜色换了一下。好了,今天的笔记就到这里~\(≧▽≦)/~啦啦啦。
|