最近在做支付的項目,但是看到美團的支付選擇做的比較好,上圖,於是我就想照着做出來,可是簡單的做,還真沒那麼容易,於是自己重寫了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();
}
@Override
public boolean isChecked() {
// TODO Auto-generated method stub
return mChecked;
}
@Override
public void setChecked(boolean checked) {
// TODO Auto-generated method stub
if (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;
}
}
@Override
public void toggle() {
// TODO Auto-generated method stub
if (!isChecked()) {
setChecked(!mChecked);
}
}
@Override
public 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() {
@Override
public void onCheckedChanged(PayRadioGroup group, int checkedId) {
// TODO Auto-generated method stub
int 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的測試代碼。
希望幫到大家:
傳送門:項目源碼