自定义RadioButton ,单选按钮

来源:互联网 发布:淄博网络推广 编辑:程序博客网 时间:2024/05/22 06:07

最近在做支付的项目,但是看到美团的支付选择做的比较好,上图,于是我就想照着做出来,可是简单的做,还真没那么容易,于是自己重写了RadioGroup 和 RadioButton,实现效果对比。

美团:我做出的效果:

虽然还是有差距,但是自己做的已经能够自定义布局来展示了,就算再复杂的布局,只需修改部分代码即可了。

下面上一下代码:

1、这是自定义的RadioButton类:

package com.jj.radio;import android.content.Context;import android.content.res.TypedArray;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.view.LayoutInflater;import android.widget.Checkable;import android.widget.ImageView;import android.widget.RadioButton;import android.widget.RelativeLayout;import android.widget.TextView;public class PayRadioPurified extends RelativeLayout implements Checkable {private ImageView payLogo;private TextView payTitle;private TextView payDesc;private RadioButton payChecked;private boolean mChecked;////状态是否选中    private boolean mBroadcasting;private int id;    private OnCheckedChangeListener mOnCheckedChangeWidgetListener;public PayRadioPurified(Context context, AttributeSet attrs) {super(context, attrs);LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);inflater.inflate(R.layout.payment_list_item,this);payLogo = (ImageView) findViewById(R.id.pay_icon);payTitle = (TextView) findViewById(R.id.pay_name);payDesc = (TextView) findViewById(R.id.pay_desc);payChecked = (RadioButton) findViewById(R.id.pay_check);TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.PayRidioButton);Drawable d = array.getDrawable(R.styleable.PayRidioButton_radio);if (d != null) {payChecked.setButtonDrawable(d);}String title = array.getString(R.styleable.PayRidioButton_title);if (title != null) {setTextTitle(title);}String str = array.getString(R.styleable.PayRidioButton_desc);if (str != null) {setTextDesc(str);}Drawable logo = array.getDrawable(R.styleable.PayRidioButton_logo);if (logo != null) {setDrawableLogo(logo);}boolean checked = array.getBoolean(R.styleable.PayRidioButton_checked, false);payChecked.setChecked(checked);array.recycle();setClickable(true);id = getId();}@Overridepublic boolean isChecked() {// TODO Auto-generated method stubreturn mChecked;}@Overridepublic void setChecked(boolean checked) {// TODO Auto-generated method stubif (mChecked != checked) {            mChecked = checked;            payChecked.refreshDrawableState();            // Avoid infinite recursions if setChecked() is called from a listener            if (mBroadcasting) {                return;            }            mBroadcasting = true;            if (mOnCheckedChangeWidgetListener != null) {                mOnCheckedChangeWidgetListener.onCheckedChanged(this, mChecked);            }            mBroadcasting = false;                    }}@Overridepublic void toggle() {// TODO Auto-generated method stubif (!isChecked()) {setChecked(!mChecked);}}@Overridepublic boolean performClick() {// TODO Auto-generated method stub/*         * XXX: These are tiny, need some surrounding 'expanded touch area',         * which will need to be implemented in Button if we only override         * performClick()         */        /* When clicked, toggle the state */        toggle();return super.performClick();}    /**     * Register a callback to be invoked when the checked state of this button     * changes. This callback is used for internal purpose only.     *     * @param listener the callback to call on checked state change     * @hide     */    void setOnCheckedChangeWidgetListener(OnCheckedChangeListener listener) {        mOnCheckedChangeWidgetListener = listener;    }        /**     * Interface definition for a callback to be invoked when the checked state     * of a compound button changed.     */    public static interface OnCheckedChangeListener {        /**         * Called when the checked state of a compound button has changed.         *         * @param buttonView The compound button view whose state has changed.         * @param isChecked  The new checked state of buttonView.         */        void onCheckedChanged(PayRadioPurified buttonView, boolean isChecked);    }        public void setTextDesc(String s) {    if (s != null) {    payDesc.setText(s);        }    }        public void setTextTitle(String s) {if (s != null) {payTitle.setText(s);}}        public String getTextTitle() {    String s = payTitle.getText().toString();return s == null ? "" : s;}        public void setDrawableLogo (Drawable d) {    if (d != null) {    payLogo.setImageDrawable(d);    }    }        public void setChangeImg(int checkedId) {    System.out.println(">>" + checkedId);    System.out.println(">>" + id);if (checkedId == id) {payChecked.setChecked(true);} else {payChecked.setChecked(false);}}}

关键点:

(1)把父布局,具有点击事件setClickable(true);

(2)还是用RadioButton来监听部分点击的变化处理,也就是payChecked

(3)toggle()方法的处理

(4)performClick()事件,必须添加!

(5)在改变RadioButton按钮背景的时候,我用了getId()的处理,这里不好,但是自己技术有限,还没能找到更好的处理办法,

(6)缺陷:复用性不好!仅作demo。


2、关于RadioGroup的代码改动的比较少,自己修改下就行了,改动的地方也就是关联的PayRadioPurified上代码,

如果不懂的可以下载源码。

3、Activity代码:

PayRadioGroup group = (PayRadioGroup) findViewById(R.id.genderGroup);group.setOnCheckedChangeListener(new OnCheckedChangeListener() {@Overridepublic void onCheckedChanged(PayRadioGroup group, int checkedId) {// TODO Auto-generated method stubint radioButtonId = group.getCheckedRadioButtonId();//PayRadioButton rb = (PayRadioButton)MainActivity.this.findViewById(radioButtonId);//Toast.makeText(MainActivity.this, rb.getText(), Toast.LENGTH_SHORT).show();PayRadioPurified rl = (PayRadioPurified)MainActivity.this.findViewById(radioButtonId);for (int i = 0; i < group.getChildCount(); i++) {((PayRadioPurified)group.getChildAt(i)).setChangeImg(checkedId);}Toast.makeText(MainActivity.this, rl.getTextTitle(), Toast.LENGTH_SHORT).show();}});

注:在此Demo实现的时候,改动了最基础的RadioButton,进行研究,所以源码中有三个参考类,都是自实现RadioButton的测试代码。

希望帮到大家:

传送门:项目源码