實(shí)現(xiàn)多行多列的RadioButton

由于最近的項(xiàng)目中多處需要用到多行多列的RadioButton船逮,而google原生的RadioGroup又不能實(shí)現(xiàn)畴嘶!因此就要自己動(dòng)手實(shí)現(xiàn)了~

本文首發(fā): MyBlog

注意:這里所說(shuō)的RadioButton都是在代碼中動(dòng)態(tài)添加的!

看下效果圖:


實(shí)現(xiàn)多行多列的RadioButton

行列對(duì)齊RadioButton

1、開(kāi)始造輪子: 分為四步

  • 重寫RadioGroup-->目的是使 RadioButton可以自動(dòng)換行

  • 布局中引用MyRadioGroupAuto

  • 代碼中根據(jù)數(shù)據(jù)動(dòng)態(tài)添加RadioButton,然后MyRadioGroup通過(guò)addView把RadioButton加進(jìn)去

  • 這里需要講下RadioButton的幾個(gè)屬性

  • radioButton.setPadding(20, 0, screenWidth / 6, 0);// 設(shè)置文字距離按鈕圖片四周的距離

  • radioButton.setButtonDrawable(R.drawable.transfer_radiobutton_drawable); //點(diǎn)擊效果

  • radioButton.setTag(loanAndFeeList.get(i)); // 設(shè)置tag,可以存一些數(shù)據(jù)

  • radioButton.setTextSize(13); //默認(rèn)單位是 sp

  • radioButton.setHeight(50); //默認(rèn)單位是px

  • RadioButton clickRadioButton = (RadioButton) radioGroup.findViewById(checkedId); //通過(guò)RadioGroup對(duì)象獲取點(diǎn)擊的RadioButton組件

  • 設(shè)置RadioGroup點(diǎn)擊事件

2饭入、下面直接上代碼: 三步

  • 自定義MyRadioGroupAuto
/**
 * Author: 0027008122 [yang.jianan@zte.com.cn]
 * Time: 2016-08-02 11:33
 * Version: 1.0
 * TaskId:
 * Description:
 */
 public class MyRadioGroupAuto extends RadioGroup {
    public MyRadioGroupAuto(Context context) {
        super(context);
    }

    public MyRadioGroupAuto(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //獲取最大寬度
        int maxWidth = MeasureSpec.getSize(widthMeasureSpec);
        //獲取Group中的Child數(shù)量
        int childCount = getChildCount();
        //設(shè)置Group的左邊距耗式,下面也會(huì)使用x計(jì)算每行所占的寬度
        int x = 0;
        //設(shè)置Group的上邊距,下面也會(huì)使用y計(jì)算Group所占的高度
        int y = 30;
        //設(shè)置Group的行數(shù)
        int row = 0;
        for (int index = 0; index < childCount; index++) {
            final View child = getChildAt(index);
            if (child.getVisibility() != View.GONE) {
                child.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
                //重新計(jì)算child的寬高
                int width = child.getMeasuredWidth();
                int height = child.getMeasuredHeight();
                //添加到X中筹吐,(width+10) 設(shè)置child左邊距
                x += (width + 10);
                //行數(shù)*child高度+這次child高度=現(xiàn)在Group的高度,(height + 10)設(shè)置child上邊距
                y = row * (height + 10) + (height + 10);
                //當(dāng)前行寬X大于Group的最大寬度時(shí),進(jìn)行換行
                if (x > maxWidth) {
                    //當(dāng)index不為0時(shí)秘遏,進(jìn)行row++丘薛,防止FirstChild出現(xiàn)大于maxWidth時(shí),提前進(jìn)行row++
                    if (index != 0)
                        row++;
                    //child的width大于maxWidth時(shí),重新設(shè)置child的width為最大寬度
                    if (width >= maxWidth) {
                        width = maxWidth - 30;
                    }
                    //重新設(shè)置當(dāng)前X
                    x = (width + 20);
                    //重新設(shè)置現(xiàn)在Group的高度
                    y = row * (height + 10) + (height + 10);
                }
            }
        }
        // 設(shè)置容器所需的寬度和高度
        setMeasuredDimension(maxWidth, y);
    }


    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int childCount = getChildCount();
        int maxWidth = r - l;
        int x = 10;
        int y = 0;
        int row = 0;
        for (int i = 0; i < childCount; i++) {
            final View child = this.getChildAt(i);
            if (child.getVisibility() != View.GONE) {
                int width = child.getMeasuredWidth();
                int height = child.getMeasuredHeight();
                x += (width + 10);
                y = row * (height + 10) + (height + 10);
                if (x > maxWidth) {
                    if (i != 0)
                        row++;
                    if (width >= maxWidth) {
                        width = maxWidth - 30;
                    }
                    x = (width + 20);
                    y = row * (height + 10) + (height + 10);
                }
                child.layout(x - width, y - height, x, y);
            }
        }
    }
}

  • 布局中引用MyRadioGroupAuto
<com.ztesoft.zsmart.datamall.app.widget.MyRadioGroupAuto
        android:id="@+id/my_radio_group_auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="33dp"
        android:layout_marginLeft="22dp"
        android:layout_marginRight="22dp"
        android:layout_marginTop="16dp">
</com.ztesoft.zsmart.datamall.app.widget.MyRadioGroupAuto>
  • 代碼中動(dòng)態(tài)添加RadioButton
public class CheckboxRadiobuttonDemo extends Activity {
    /**
     * Called when the activity is first created.
     */
    private RadioGroupAuto rgp;
    private RadioGroup yuansheng;

    private String[] loanList;
    private String[] loanFeeList;
    private List<String> loanAndFeeList;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        //獲取屏幕信息
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        int screenWidth = dm.widthPixels;

        loanAndFeeList = new ArrayList<>();
        loanList = "800,1000,1600,200,300,500,700".split(",");
        loanFeeList = "50,80,100,20,30,50,70".split(",");
        
        //求最大最小值 (為了保持RadioButton文字長(zhǎng)度一致,跟最長(zhǎng)的保持一致!)
        int max = Integer.parseInt(loanList[0]);
        int min = Integer.parseInt(loanList[0]);
        for (String i : loanList) {
            int j = Integer.parseInt(i);
            max = max > j ? max : j;
            min = min < j ? min : j;
        }
        
        String maxS = String.valueOf(max);
        int maxLen = maxS.length();

        for (int i = 0; i < loanList.length; i++) {
            loanAndFeeList.add( loanList[i] + "," + loanFeeList[i]);
        }


        rgp = (RadioGroupAuto) findViewById(R.id.RadioGroup01);

        int len = loanAndFeeList.size();

        for (int j = 0; j < len; j++) {

            RadioButton radioButton = new RadioButton(this);
            radioButton.setPadding(20, 0, screenWidth / 6, 0);  // 設(shè)置文字距離按鈕四周的距離
            radioButton.setButtonDrawable(R.drawable.transfer_radiobutton_drawable);

            String newLoanList = loanList[j];
            if (loanList[j].length() < maxLen) {
                newLoanList = newLoanList + appendLength(maxLen - loanList[j].length());

                // 實(shí)現(xiàn) TextView同時(shí)顯示兩種風(fēng)格文字 http://txlong-onz.iteye.com/blog/1142781
                SpannableStringBuilder sb = new SpannableStringBuilder(newLoanList);
                final ForegroundColorSpan fcs = new ForegroundColorSpan(Color.WHITE);
                sb.setSpan(fcs, loanList[j].length(), maxLen, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
                radioButton.setText(sb);
            } else {
                newLoanList = loanList[j];
                radioButton.setText(newLoanList);
            }
            
            radioButton.setId(j); //設(shè)置RadioButton的id
            radioButton.setTag(loanAndFeeList.get(j)); //tag用于存儲(chǔ)RadioButton的一些數(shù)據(jù)
            radioButton.setTextSize(13); //默認(rèn)單位是 sp
            radioButton.setHeight(50); //默認(rèn)單位是px
            rgp.addView(radioButton); //添加到RadioGroup中

        }

        rgp.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                RadioButton clickRadioButton = (RadioButton) group.findViewById(checkedId);

                String tipInfo = "id: " + clickRadioButton.getId() + " text: " + clickRadioButton.getText() +
                        /*"hint: " + clickRadioButton.getHint() +*/ " tag:" + clickRadioButton.getTag();
                System.out.println(tipInfo);

                Toast.makeText(CheckboxRadiobuttonDemo.this, tipInfo,
                        Toast.LENGTH_SHORT).show();
            }
        });

        //根據(jù)這個(gè)來(lái)設(shè)置默認(rèn)選中的項(xiàng), 注意,這個(gè)要設(shè)置在監(jiān)聽(tīng)之后!,否則默認(rèn)點(diǎn)擊監(jiān)聽(tīng)不到!雖然有選中效果
        //參考 http://blog.csdn.net/lzqjfly/article/details/16963645
        //以及http://stackoverflow.com/questions/9175635/how-to-set-radio-button-checked-as-default-in-radiogroup-with-android
        rgp.check(0);
    }

    /**
     * 補(bǔ)全長(zhǎng)度,保持最長(zhǎng)的長(zhǎng)度
     *
     * @param count 字符串長(zhǎng)度
     * @return 補(bǔ)全后的長(zhǎng)度
     * 這里長(zhǎng)度不夠的就用 "s" 占位, 賦值的時(shí)候?qū)⒆煮w設(shè)置白色!
     */
    public String appendLength(int count) {
        String st = "";
        if (count < 0) {
            count = 0;
        }
        for (int i = 0; i < count; i++) {
            st = st + "s";
        }
        return st;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末邦危,一起剝皮案震驚了整個(gè)濱河市榔袋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌铡俐,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件妥粟,死亡現(xiàn)場(chǎng)離奇詭異审丘,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)勾给,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門滩报,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人播急,你說(shuō)我怎么就攤上這事脓钾。” “怎么了桩警?”我有些...
    開(kāi)封第一講書人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵可训,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我捶枢,道長(zhǎng)握截,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任烂叔,我火速辦了婚禮谨胞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蒜鸡。我一直安慰自己胯努,他們只是感情好牢裳,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著叶沛,像睡著了一般蒲讯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上恬汁,一...
    開(kāi)封第一講書人閱讀 50,050評(píng)論 1 291
  • 那天伶椿,我揣著相機(jī)與錄音,去河邊找鬼氓侧。 笑死脊另,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的约巷。 我是一名探鬼主播偎痛,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼独郎!你這毒婦竟也來(lái)了踩麦?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤氓癌,失蹤者是張志新(化名)和其女友劉穎谓谦,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體贪婉,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡反粥,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了疲迂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片才顿。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖尤蒿,靈堂內(nèi)的尸體忽然破棺而出郑气,到底是詐尸還是另有隱情,我是刑警寧澤腰池,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布尾组,位于F島的核電站,受9級(jí)特大地震影響示弓,放射性物質(zhì)發(fā)生泄漏演怎。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一避乏、第九天 我趴在偏房一處隱蔽的房頂上張望爷耀。 院中可真熱鬧,春花似錦拍皮、人聲如沸歹叮。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)咆耿。三九已至德谅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間萨螺,已是汗流浹背窄做。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留慰技,地道東北人椭盏。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像吻商,于是被迫代替她去往敵國(guó)和親掏颊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容

  • 1 基本UI Zealer艾帐、CSDN乌叶、github StormZhang、 張弘揚(yáng)(Hyman):http:/...
    征程_Journey閱讀 11,984評(píng)論 0 4
  • ¥開(kāi)啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開(kāi)一個(gè)線程柒爸,因...
    小菜c閱讀 6,376評(píng)論 0 17
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,862評(píng)論 25 707
  • 對(duì)了准浴,姐姐家還有一只叫Q仔的貓也是“男的”! 每天一屋子的女人就圍著這三個(gè)“男人”轉(zhuǎn)捎稚。Q仔上竄下跳什么...
    LRJ69閱讀 679評(píng)論 0 0
  • by/一只小蟬 內(nèi)幕資料數(shù)據(jù)乐横,謝絕觀看!Q粼濉!
    一只小蟬閱讀 87評(píng)論 0 1