2017-01-30 7 views
2

У меня есть линейный макет и вы хотите динамически добавлять переменное количество элементов списка. (Он не может быть просмотром ресайклеров, потому что этот список уже находится в представлении recycler и считается небольшим списком.) Но по какой-то причине он не сохраняет текст, который я установил, за исключением последнего элемента. Если я добавлю другой элемент с другим заголовком, появится последний добавленный, а остальные скажут «default». Кто-нибудь знает что происходит? Это действительно странно. Благодаря!Добавление представлений в LinearLayout программным способом, не устанавливая текст для всех, кроме одного

Вот код:

settings_item.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal"> 

    <TextView 
     style="?android:listSeparatorTextViewStyle" 
     android:id="@+id/title" 
     android:layout_width="wrap_content" 
     android:layout_height="match_parent" 
     android:background="#00000000" 
     android:text="Default" 
     android:layout_weight="1"/> 

    <CheckBox 
     android:id="@+id/checkbox" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:gravity="end|center_vertical" 
     android:layout_weight="0"/> 

</LinearLayout> 

root_settings_view.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:layout_marginEnd="5dp"> 
</LinearLayout> 

SettingsView.java:

public class SettingsView extends LinearLayout { 

    //Views 
    private View view; 

    /** 
    * Constructor for android tools to use. 
    */ 
    public SettingsView(Context context) { 
     super(context); 
    } 

    /** 
    * 
    * @param parent 
    */ 
    public SettingsView(ViewGroup parent) { 
     super(parent.getContext()); 

     //Get the inflated layout 
     LinearLayout view = (LinearLayout) LayoutInflater.from(getContext()).inflate(R.layout.root_settings_view, parent, false); 


     View itemView = LinearLayout.inflate(parent.getContext(), R.layout.settings_item, view); 
     ((TextView) itemView.findViewById(R.id.title)).setText("Hi"); 
     ((CheckBox) itemView.findViewById(R.id.checkbox)).setChecked(true); 


     View itemView2 = LinearLayout.inflate(parent.getContext(), R.layout.settings_item, view); 
     ((TextView) itemView2.findViewById(R.id.title)).setText("Hello"); 
     ((CheckBox) itemView2.findViewById(R.id.checkbox)).setChecked(false); 

     View itemView3 = LinearLayout.inflate(parent.getContext(), R.layout.settings_item, view); 
     ((TextView) itemView3.findViewById(R.id.title)).setText("Bye"); 
     ((CheckBox) itemView3.findViewById(R.id.checkbox)).setChecked(true); 

     View itemView4 = LinearLayout.inflate(parent.getContext(), R.layout.settings_item, view); 
     ((TextView) itemView4.findViewById(R.id.title)).setText("Test"); 
     ((CheckBox) itemView4.findViewById(R.id.checkbox)).setChecked(false); 

     addView(view); 
    } 

Result

+1

Вы не можете иметь тот же идентификатор, когда вы раздувая его для каждого элемента, то, что вы хотите, вместо того, чтобы раздувать его, вам нужно «добавить» элемент списка в родительский 'view' –

ответ

1

Спасибо @Rod_Algonquin за ваш комментарий, который убедил меня, что я должен сделать виджет для этого. К счастью, раньше я делал виджеты, поэтому я знал, как это сделать. Я просто пытался избежать этого, но, я думаю, у него есть проблемы с дублирующимися идентификаторами, если мы не используем виджеты.

Следующий код сделал это работает:

Добавлен новый класс, SettingItemView.java:

/** 
* A item view with the title and a checkbox. 
*/ 
public class SettingItemView extends LinearLayout { 

    private TextView mTitle; 
    private CheckBox mCheckBox; 

    public SettingItemView(Context context) { 
     super(context); 
     inflate(context, R.layout.settings_item, this); 
     mTitle = (TextView) findViewById(R.id.title); 
     mCheckBox = (CheckBox) findViewById(R.id.checkbox); 
    } 

    public void setTitle(String title) { 
     mTitle.setText(title); 
    } 

    public void setCheckbox(boolean checked) { 
     mCheckBox.setChecked(checked); 
    } 
} 

Изменено этот метод конструктора:

/** 
* 
* @param parent 
*/ 
public SettingsView(ViewGroup parent) { 
     super(parent.getContext()); 

     //Get the inflated layout. 
     LinearLayout view = LayoutInflater.from(getContext()).inflate(R.layout.root_settings_view, parent, false); 


     SettingItemView itemView = new SettingItemView(parent.getContext()); 
     itemView.setTitle("Hi"); 
     itemView.setCheckbox(true); 
     view.addView(itemView); 

     SettingItemView itemView2 = new SettingItemView(parent.getContext()); 
     itemView2.setTitle("Hello"); 
     itemView2.setCheckbox(true); 
     view.addView(itemView2); 

     SettingItemView itemView3 = new SettingItemView(parent.getContext()); 
     itemView3.setTitle("Bye"); 
     itemView3.setCheckbox(true); 
     view.addView(itemView3); 

     addView(view); 
    } 
1

Вы, в основном работает над ним и добавляя только последний, этот код должен работать:

общественного SettingsView (ViewGroup родитель) { супер (parent.getContext());

//Get the inflated layout 
    LinearLayout view = (LinearLayout) LayoutInflater.from(getContext()).inflate(R.layout.root_settings_view, parent, false); 


    View itemView = LinearLayout.inflate(parent.getContext(), R.layout.settings_item, view); 
    ((TextView) itemView.findViewById(R.id.title)).setText("Hi"); 
    ((CheckBox) itemView.findViewById(R.id.checkbox)).setChecked(true); 
    addView(view); 
    View itemView2 = LinearLayout.inflate(parent.getContext(), R.layout.settings_item, view); 
    ((TextView) itemView2.findViewById(R.id.title)).setText("Hello"); 
    ((CheckBox) itemView2.findViewById(R.id.checkbox)).setChecked(false); 
    addView(view); 
    View itemView3 = LinearLayout.inflate(parent.getContext(), R.layout.settings_item, view); 
    ((TextView) itemView3.findViewById(R.id.title)).setText("Bye"); 
    ((CheckBox) itemView3.findViewById(R.id.checkbox)).setChecked(true); 
    addView(view); 
    View itemView4 = LinearLayout.inflate(parent.getContext(), R.layout.settings_item, view); 
    ((TextView) itemView4.findViewById(R.id.title)).setText("Test"); 
    ((CheckBox) itemView4.findViewById(R.id.checkbox)).setChecked(false); 

    addView(view); 
+0

Это дало мне бесконечную рекурсию в LogCat, показывающую эта строка снова и снова: 'at android.view.ViewGroup.resetResolvedLayoutDirection (ViewGroup.java:6713)' –

+0

Я думал то же самое, кроме 'addView (itemView)' и т. д. Однако это не объясняет, почему что-то отображается вообще - как я вижу, в 'ViewGroup' добавляется только' root_settings_view'. – Micha

+0

Я думаю, что yanivtwin неправильно понял мой код, потому что я фактически добавляю корневой вид (где я раздул 4 представления элементов) родительскому LinearLayout, не добавляя никаких элементов. Они были добавлены только методом инфляции. Когда я попытался добавить элементы вручную, это дало мне проблему рекурсии. –