找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3531|回复: 0
打印 上一主题 下一主题
收起左侧

商城开发笔记-11-自定义组合控件以及使用

[复制链接]
跳转到指定楼层
楼主
ID:109770 发表于 2016-3-22 17:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
一、自定义组合控件介绍


       开发中,为了使用的方便,经常把一些控件组合成一个控件,那样就成为了我们的自定义组合控件,严格意义来说,自定义组合控件并不属于“自定义控件”。


二、自定义组合控件步骤
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>


2java代码中的使用:
这里我设置文字变化的监听。

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的背景颜色换了一下。好了,今天的笔记就到这里~\(≧▽≦)/~啦啦啦。


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表