Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> Android組件式開發(2)——實現網格布局的RadioButton矩陣

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

編輯:關於android開發

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
這裡寫圖片描述

以上。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved