Программно добавленные RadioButtons отказываются подчиняться LayoutParams weighting
Я пытаюсь создать RadioGroup
в макете Android, где дочерний элемент RadioButton
растянут, чтобы равномерно заполнить всю ширину RadioGroup
. Однако при попытке сделать это с помощью RadioButton
, которые были добавлены программно из кода, я столкнулся с каким-то неожиданным поведением. Сначала немного фона...
Что работает
Я начал с простой компоновки, основанной на 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
растягивает их, чтобы равномерно заполнить половину прилагаемого RadioGroup
каждого. Пока все хорошо.
Что не работает
Однако я должен динамически создавать RadioButton
в этом макете во время выполнения на основе бизнес-логики, а не всегда использовать два статически включенных в макет - иногда мне могут понадобиться две кнопки, иногда четыре и т.д.
Чтобы реализовать это, я удалил RadioButton
из моего макета 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"/>
</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
на 0 в LayoutParams
(по-видимому, это может привести к тому, что макет макета будет интерпретироваться несколько иначе), но это приводит к тому, что RadioButton
not даже для визуализации:
![Radio buttons missing completely]()
Можно ли сообщить, как получить RadioButton
, чтобы равномерно заполнить всю ширину содержащего RadioGroup
при добавлении программно? Есть ли что-то очевидное, что мне не хватает?
Ответы
Ответ 1
Когда вы устанавливаете вес макета, вы должны использовать fill_parent как ширину макета. Тогда вы не должны использовать LinearLayout.LayoutParams, но RadioGroup.LayoutParams, поскольку вы добавляете радиокнопки в RadioGroup, а не в простой LinearLayout. Наконец, когда вы используете надувной элемент для "создания" радиокнопки, в файле xml радиокнопки уже есть параметры макета, выбранные из xml файла, поэтому я думаю, вы должны просто вызвать метод addView, который принимает только представление для добавления в качестве параметра (это addView (View v)) и измените layout_width на fill_parent. Обратите внимание, что если вам нужно будет ссылаться на переменную "button" в коде, т.е. Добавить прослушиватель кликов, вы добавите слушателя только к последней созданной кнопке. Вам нужно будет создать объект RadioButton для каждого RadioButton, который вы добавите в RadioGroup (кнопка, кнопка1, кнопка2 и т.д.).
Ответ 2
FYI, чтобы сделать это без каких-либо 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);
Ответ 3
Я столкнулся с этой проблемой, я использовал 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
}
});
}