Программно добавленные RadioButtons отказываются подчиняться весам LayoutParams - PullRequest
18 голосов
/ 22 января 2012

Я пытаюсь создать RadioGroup в макете Android, где дочерние элементы RadioButton растягиваются, чтобы равномерно заполнить всю ширину RadioGroup. Однако я столкнулся с неожиданным поведением при попытке сделать это с RadioButton s, которые были добавлены программно из кода. Сначала немного предыстории ...

Что делает работает

Я начал с простого макета, основанного на RelativeLayout, который содержит большой TextView и RadioGroup внизу.

Файл макета main.xml выглядит следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <TextView android:text="Some text"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:layout_alignParentTop="true"
        android:layout_above="@+id/radio_group"
        android:gravity="center"
        android:background="@android:color/holo_green_dark"
        />      
    <RadioGroup android:id="@+id/radio_group"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal"
        android:background="@android:color/holo_blue_dark">         
        <RadioButton android:text="Option 1"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:layout_weight="1"
            android:background="@android:color/darker_gray"
            android:button="@android:color/transparent"
            android:padding="10dp"
            android:gravity="center"
            android:layout_margin="2dp"/>   
        <RadioButton android:text="Option 2"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:layout_weight="1"
            android:background="@android:color/darker_gray"
            android:button="@android:color/transparent"
            android:padding="10dp"
            android:gravity="center"
            android:layout_margin="2dp"/> 
    </RadioGroup>       
</RelativeLayout>

, который создает следующий макет во время выполнения:

Evenly distributed radio buttons

Вы можете видеть, что использование android:layout_width="wrap_content" и android:layout_weight="1" в обоих RadioButton s растягивает их, чтобы равномерно заполнить половину вмещающего RadioGroup каждого. Пока все хорошо.

Что не работает

Однако у меня есть требование динамически создавать RadioButton в этом макете во время выполнения на основе бизнес-логики, а не всегда использовать два статически включенных в макет - иногда мне могут понадобиться две кнопки, иногда четыре и т. Д.

Чтобы реализовать это, я удалил RadioButton s из моего main.xml layout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <TextView android:text="Some text"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:layout_alignParentTop="true"
        android:layout_above="@+id/radio_group"
        android:gravity="center"
        android:background="@android:color/holo_green_dark"
        />      
    <RadioGroup android:id="@+id/radio_group"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal"
        android:background="@android:color/holo_blue_dark"/>
</RelativeLayout>

... и создал отдельный макет _radio_button.xml_ для моего RadioButton:

<?xml version="1.0" encoding="utf-8"?>
<RadioButton xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="2dp"
    android:layout_weight="1"
    android:background="@android:color/darker_gray"
    android:button="@android:color/transparent"
    android:gravity="center"
    android:padding="10dp" />

В своей деятельности я теперь добавляю RadioButton программно:

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

        // Create an inflater to inflate our buttons            
        LayoutInflater inflater = 
            (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        // Create the layout params for our buttons
        LinearLayout.LayoutParams layoutParams = new LayoutParams(
            LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f);

        RadioGroup group = (RadioGroup) findViewById(R.id.radio_group);

        // Add button one
        RadioButton button = (RadioButton) inflater.inflate(R.layout.radio_button, null);
        button.setText("Option 1");
        group.addView(button, layoutParams);

        // Add button two
        button = (RadioButton) inflater.inflate(R.layout.radio_button, null);
        button.setText("Option 2");
        group.addView(button, layoutParams);

    }
}

Обратите внимание, как и файл _radio_button.xml_, и действие определяют ширину макета WRAP_CONTENT и вес макета 1 для равномерного распределения кнопок, как в исходном main.xml .

Тем не менее, кажется, что макет отображается без учета веса макета с кнопками, расположенными слева от группы радиостанций:

Radio buttons not being evenly distributed

Как было предложено в другом месте, я также пытался установить ширину RadioButton s в 0 в LayoutParams (очевидно, это может привести к тому, что вес макета будет интерпретироваться немного по-другому), но это вызывает RadioButton даже не подлежит визуализации:

Radio buttons missing completely

Может ли кто-нибудь посоветовать, как получить RadioButton s, чтобы равномерно заполнить всю ширину содержащего RadioGroup при программном добавлении? Есть ли что-то очевидное, что мне не хватает?

Ответы [ 3 ]

17 голосов
/ 22 января 2012

Когда вы устанавливаете вес макета, вы должны использовать fill_parent в качестве ширины макета. Тогда вам не следует использовать LinearLayout.LayoutParams, а RadioGroup.LayoutParams, поскольку вы добавляете радиокнопки в RadioGroup, а не в простой LinearLayout.

Наконец, когда вы используете inflater для «сборки» переключателя, в файле XML переключателя уже есть параметры макета, выбранные из файла XML, поэтому я думаю, что вам нужно просто вызвать метод addView, который принимает только добавьте в качестве параметра (то есть addView(View v)) и измените layout_width на fill_parent.

Обратите внимание, что если вам нужно сослаться на переменную "кнопка" в коде, то есть добавить прослушиватель щелчков, вы добавите прослушиватель только к последней созданной кнопке. Вам нужно будет создать объект RadioButton для каждого RadioButton, который вы добавите в RadioGroup (button, button1, button2 и т. Д.).

9 голосов
/ 09 февраля 2013

К вашему сведению, чтобы сделать это вообще без xml

    RadioGroup rgrp = new RadioGroup(context);
    rgrp.setLayoutParams(new RadioGroup.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT));
    rgrp.setOrientation(LinearLayout.HORIZONTAL);

        mAccent = new RadioButton(context);
        mAccent.setText("Accent");
        mAccent.setLayoutParams(new RadioGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));
        rgrp.addView(mAccent);

        mGhost = new RadioButton(context);
        mGhost.setText( "Ghost");
        mGhost.setLayoutParams(new RadioGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));
        rgrp.addView(mGhost);

        mFlam = new RadioButton(context);
        mFlam.setText( "Flam");
        mFlam.setLayoutParams(new RadioGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));
        rgrp.addView(mFlam);

    layout.addView(rgrp);
1 голос
/ 14 декабря 2015

Я тоже столкнулся с этой проблемой, я использовал RadioGroup.LayoutParams с определенным весом.Однако я также обнаружил, что однажды я создал программно кнопки, которые не реагировали на прикосновения, поэтому установите clickable и enabled на true, и это исправит ситуацию.

  private RadioButton createMyTypeRadioButton(MyType type){

    //create using this constructor to use some of the style definitions
    RadioButton radio = new RadioButton(this, null, R.style.MyRadioStyle);

    RadioGroup.LayoutParams layoutParams = new RadioGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1f);
    radio.setLayoutParams(layoutParams);
    radio.setGravity(Gravity.CENTER);

    //tag used by the setOnCheckedChangeListener to link the radio button with mytype object
    radio.setTag(type.getId());

    //enforce enabled and clickable status otherwise they ignore clicks
    radio.setClickable(true);
    radio.setEnabled(true);

    radio.setText(type.getTitle());


    return radio;
}

private void updateMyTypesUi() {

    //populate RadioGroup with permitted my types
    for (int i = 0; i < myTypes.size(); i++) {
        MyType type = myTypes.get(i);           
        RadioButton radioButton = createSwapTypeRadioButton(type);
        myRadioGrp.addView(radioButton);

    }

    myRadioGrp.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            RadioButton checkedType = (RadioButton) group.findViewById(checkedId);              
            String idOfMyTypeChecked = (String) checkedType.getTag();
            //do something with idOfMyTypeChecked
        }
    });
}
...