Android組件式開發(2)——實現網格布局的RadioButton矩陣

來源:互聯網
上載者:User

Android組件式開發(2)——實現網格布局的RadioButton矩陣

**

前言

**
在Android中,我們一般通過RadioGroup來管理一組RadioButton 來達到 選項按鈕的互斥效果。但是,有些需求中,需要完成N行N列這樣的RadioButton組成的矩陣,但是我們的RadioGroup是一個耿直的LinearLayout,無法完成網格布局╮(╯▽╰)╭。所以,下面我就像大家來介紹一種實現網格布局的RadioButton的思路。
無圖無真相, 先上一下~

**<喎?http://www.bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxoMiBpZD0="思路">思路

**
提到網格布局,最簡單的就是使用系統的GridView來實現,我們需要做的就是 將RadioButton加入GridView中,然後自己來實現RadioButton之間的互斥。
1. 自訂RadioButton:
自訂一個RadioButton ,命名為IconRadioButton

/** * Created by jk on 2016/1/20. * 自訂 RadioButton */public class IconRadioButton extends LinearLayout  {    private Context mContext;    private Resources mResources;    private boolean mIsCheck;    private View mContentView;    private ImageView mRadio;    private TextView mTextView;    private ColorStateList mTextColor;    public IconRadioButton(Context context) {        this(context, null);    }    public IconRadioButton(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public IconRadioButton(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context);    }    private void init(Context context) {        mContext = context;        mResources = context.getResources();        mContentView = LayoutInflater.from(context).inflate(R.layout.btn_icon_radio, this);        mRadio = (ImageView) mContentView.findViewById(R.id.radio);        mTextView = (TextView) mContentView.findViewById(R.id.text);    }    public void setChecked(boolean isChecked) {        mIsCheck = isChecked;        changeUIByChecked(isChecked);    }    public boolean isChecked() {        return mIsCheck;    }    private void changeUIByChecked(boolean isChecked) {        if (mRadio.getVisibility() != GONE) {            mRadio.setImageResource(isChecked ? R.drawable.radio_selected                    : R.drawable.radio_unselected);        }        mTextView.setEnabled(isChecked);    }    public void setTextColor(ColorStateList color){        mTextColor = color;        mTextView.setTextColor(color);    }    public void setText(CharSequence text) {        mTextView.setText(text);    }    public void setText(int resId) {        mTextView.setText(resId);    }    public void hiddenRadio(boolean isHidden) {        mRadio.setVisibility(isHidden ? GONE : VISIBLE);    }}

這個IconRadioButton很簡單 就是一個LinearLayout,內部封裝了根據是否選中來改變文字和按鈕樣式的方法。

btn_icon_radio.xml

<code class=" hljs xml"><!--{cke_protected}{C}%3C!%2D%2D%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%2D%2D%3E--><linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="left" android:paddingbottom="5dp" android:paddingtop="5dp">    <imageview android:id="@+id/radio" android:layout_width="42dp" android:layout_height="match_parent" android:layout_gravity="center_vertical" android:gravity="center" android:src="@drawable/radio_selected" android:textcolor="#FF1CBFA6">    <textview android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="center_vertical" android:gravity="center" android:textcolor="#FF999999" android:textsize="14dp"></textview></imageview></linearlayout></code>

布局檔案很簡單 就是一個LinearLayout裡面放了一個ImageView和一個TextView

2 . 定義資料模型

/** * Created by admin on 2016/1/20. */public class RadioItemModel {    public String text; //RadioButton的文字    public boolean isChecked;//是否選中    public boolean hiddenRadio;//是否需要隱藏radio    public ColorStateList textColor;//文字的不同狀態的顏色    public RadioItemModel(String text, boolean isChecked, boolean hiddenRadio, ColorStateList textColor) {        this.text = text;        this.isChecked = isChecked;        this.hiddenRadio = hiddenRadio;        this.textColor = textColor;    }    public RadioItemModel(String text) {        this.isChecked = false;        this.hiddenRadio = false;        this.textColor = null;        this.text = text;    }    public void setText(String text) {        this.text = text;    }    public String getText() {        return text;    }    public boolean isChecked() {        return isChecked;    }}

我們定義了一個資料模型來存放RadioButton的各種屬性。其中ColorStateList是用來控制TextView在不同狀態下的顏色的 比如:state_pressed等。

3. 定義Adapter:
既然是使用GridView 那就需要定義我們的Adapter,我們的互斥邏輯也是在Adapter中實現的。

/** * Created by jk on 2016/1/20. * function: 單選矩陣的適配器 * purpose: 系統的RadioGroup是個耿直的LinearLayout╮(╯▽╰)╭  只能線性排列,無法完成 * N行N列的布局。So 為了實現選項按鈕的網格布局 ,重定義 */public class GridRadioAdapter extends BaseAdapter {    private List mList;    private Context mContext;    private Resources mResources;    private OnItemCheckedListener mListener;    //RadioButton選中時的回呼函數    public interface OnItemCheckedListener {        void onItemChecked(RadioItemModel model, int position);    }    public void setOnItemCheckedListener(OnItemCheckedListener listener) {        this.mListener = listener;    }    public GridRadioAdapter(Context context, List list) {        mContext = context;        mList = list;        check();    }    private void check() {        if (mList.size()>=0 && mList!=null) {            checkDefaultChecked();            checkMutex();        }    }    /**     * 檢查互斥事件   預設只能選中一個 如果有多個選擇,就選中最後一個     */    private void checkMutex() {        int checkCount = 0;        for (RadioItemModel item : mList) {            if (item.isChecked) {                checkCount++;            }        }        if (checkCount >= 2) {            setOtherUnChecked(checkCount - 1);        }    }    private void setOtherUnChecked(int position) {        for (int i = 0; i < mList.size(); i++) {            if (i != position) {                RadioItemModel item = mList.get(i);                item.isChecked = false;            } else {                mList.get(position).isChecked = true;            }        }    }    public RadioItemModel getItemChecked() {        for (int i = 0; i < mList.size(); i++) {            RadioItemModel item = mList.get(i);            if (item.isChecked)                return item;        }        return null;    }    /**     * 檢查是否有預設選中的按鈕  如果沒有 預設第一個選中     */    private void checkDefaultChecked() {        for (RadioItemModel item : mList) {            if (item.isChecked)                return;        }        mList.get(0).isChecked = true;    }    @Override    public int getCount() {        return mList == null ? 0 : mList.size();    }    @Override    public Object getItem(int position) {        if (mList != null && mList.size() > position)            return mList.get(position);        return null;    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public View getView(final int position, View convertView, ViewGroup parent) {        IconRadioButton iconBean = null;        iconBean = new IconRadioButton(mContext);        final RadioItemModel model = mList.get(position);        if (!TextUtils.isEmpty(model.text)) {            iconBean.setText(model.text);        }        iconBean.setChecked(model.isChecked);        if (model.textColor != null) {            iconBean.setTextColor(model.textColor);        }        iconBean.hiddenRadio(model.hiddenRadio);        final IconRadioButton finalIconBean = iconBean;        iconBean.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                if (!finalIconBean.isChecked()) {                    setOtherUnChecked(position);                    if (mListener != null) {                        mListener.onItemChecked(model, position);                    }                    notifyDataSetChanged();                }            }        });        return iconBean;    }    public void addAll(List list){        mList.clear();        if(list.size()>=0 && list!=null){            mList.addAll(list);            check();            notifyDataSetChanged();        }    }}

在建構函式中,我們調用了check方法來實現預設選中檢查和 互斥檢查。
(1)checkDefaultChecked函數用來實現預設選中功能,如果傳遞給我們的資料中沒有按鈕是預設選中的 ,那我們就讓第一個按鈕預設選中。
(2)checkMutex函數是用來檢查互斥事件的,如果有多個按鈕同時被選中,我們就設定被選中的最後一個按鈕為選中狀態,其他置為非選中狀態。比如 按鈕1,3,5同時被選中,那麼我們就讓5置為選中狀態,1和3為非選中狀態。
(3)OnItemCheckedListener是當按鈕被選中時的回調方法。

4.使用方式

使用方式就非常簡單粗暴了~

public class MainActivity extends Activity {    private GridView mGridLayout;    private GridRadioAdapter mAdapter;    private List mItemList;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        }    private void initData() {        mItemList = new ArrayList();        ColorStateList csl = getResources().getColorStateList(R.color.ddt_color_tab_text);        mItemList.add(new RadioItemModel("全部", false, true, csl));        mItemList.add(new RadioItemModel("早餐前", false, true, csl));        mItemList.add(new RadioItemModel("午餐前", false, true, csl));        mItemList.add(new RadioItemModel("晚餐前", false, true, csl));        mItemList.add(new RadioItemModel("早餐後", false, true, csl));        mItemList.add(new RadioItemModel("午餐後", false, true, csl));        mItemList.add(new RadioItemModel("晚餐後", false, true, csl));        mItemList.add(new RadioItemModel("睡前", false, true, csl));        mAdapter.notifyDataSetChanged();    }    }

PS: 如果設定hiddenRadio這個屬性為true,我們就可以實現下面這種效果了。所以這個東西也是可以用來做切換Fragment的選項卡的哦~~~ O(∩_∩)O

以上。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.