Флажки, показывающие один и тот же текст после смены ориентации - PullRequest
4 голосов
/ 15 мая 2011

Редактировать: см. Принятый ответ. Урок. Иногда представления сохраняют и восстанавливают свое состояние автоматически. Это происходит ПОСЛЕ создания. Это может привести к перезаписи материала, который вы сделали в onCreate. Если у вас нет уникальных идентификаторов, все представления определенного вида (в моем случае текстовые поля) могут быть перезаписаны с одинаковым сохраненным состоянием. (ps: всем спасибо за помощь!)

Итак, у меня есть простой линейный макет, и я хочу добавить несколько видов, которые имеют флажки с изображениями. Все работает нормально, пока я не переключу ориентацию моего телефона Android. Когда я это делаю, он возвращается через onCreate, но на этот раз все флажки заканчиваются одинаковым текстом. Странно, изображения выглядят нормально.

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

В случае, если это не имеет смысла, вот пример: (Edit: оказывается, он всегда показывает текст последнего элемента)

Что я вижу сначала

[] a *a's image*
[] b *b's image*
[] c *c's image*
[] d *d's image*

Затем, после вращения моего телефона, он перерисовывает

[] d *a's image*
[] d *b's image*
[] d *c's image*
[] d *d's image*

Мой оригинальный код довольно сложный, но я построил следующее, демонстрирующее проблему.

Main.java:

public class Main extends Activity {

ArrayList<AnswerView> answers = new ArrayList<AnswerView>();

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    TextView title = (TextView)findViewById(R.id.questionText);
    title.setText("This is a test");
    HashMap<String, Drawable> answerInfo = new HashMap<String, Drawable>();
    Resources res = getResources();
    answerInfo.put("a", res.getDrawable(R.drawable.flower_orange));
    answerInfo.put("b", res.getDrawable(R.drawable.flower_white));
    answerInfo.put("c", res.getDrawable(R.drawable.leaf));
    answerInfo.put("d", res.getDrawable(R.drawable.flower_yellow));
    setBoxes(answerInfo);
}

private void setBoxes(HashMap<String, Drawable> answerInfo) {
    LinearLayout answerList = (LinearLayout)findViewById(R.id.answerlist);
    AnswerView cb = null;

    //Remove all existing answer views
    answerList.removeAllViews();
    answers.clear();

    //For each possible answer create a answer views
    for (String s : answerInfo.keySet()) {
        cb = new AnswerView(this, s, answerInfo.get(s));
        answers.add(cb);
        String text = cb.getText();
        answerList.addView(cb);
    }
}
}

AnswerView.java

 public class AnswerView extends RelativeLayout  {

private CheckBox m_checkbox;
private ImageView m_image;
//private Context m_context;

public AnswerView(Context context, String answer, Drawable d) {
    super(context);
    LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(R.layout.image_checkbox, this, true);
    m_checkbox = (CheckBox) view.findViewById(R.id.image_checkbox_cb);
    m_image = (ImageView) view.findViewById(R.id.image_checkbox_img);
    //m_context = context;
    m_checkbox.setText(answer);
    m_image.setImageDrawable(d);
    m_image.setVisibility(VISIBLE);

}

public void setChecked(boolean checked) {
    m_checkbox.setChecked(checked);
}

public boolean isChecked() {
    return m_checkbox.isChecked();
}

public String getText() {
    return m_checkbox.getText().toString();
}

}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
     xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
        android:layout_height="wrap_content">
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:orientation="vertical" 
  android:padding="5dip">

  <TextView android:orientation="vertical" 
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/questionText"
    android:textSize="18sp"/>

  <LinearLayout android:orientation="vertical" 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/answerlist"/>
  <LinearLayout android:orientation="horizontal" 
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center">
    <Button  
    android:layout_width="200dip" 
    android:layout_height="wrap_content" 
    android:text="Enter"
    android:id="@+id/buttonAnswerEnter"/>
    />
    </LinearLayout>

</LinearLayout>
</ScrollView>

image_checkbox.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:orientation="horizontal">
  <CheckBox
   android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:id="@+id/image_checkbox_cb"></CheckBox>
  <ImageView
  android:id="@+id/image_checkbox_img"
  android:layout_width="100dip" 
  android:layout_height="100dip" 
  android:visibility="gone"></ImageView>
    </LinearLayout>

Ответы [ 3 ]

0 голосов
/ 15 мая 2011

Решает ли ваша проблема установка уникального идентификатора для каждого AnswerView? Вы можете достичь этого следующим образом:

private void setBoxes(HashMap<String, Drawable> answerInfo) {
    LinearLayout answerList = (LinearLayout)findViewById(R.id.answerlist);
    AnswerView cb = null;

    //Remove all existing answer views
    answerList.removeAllViews();
    answers.clear();

    //For each possible answer create a answer views
    // BEGIN modified code
    int counter = 0;
    // END modified code
    for (String s : answerInfo.keySet()) {
        cb = new AnswerView(this, s, answerInfo.get(s));
        // BEGIN modified code
        cb.setId(counter);
        counter++;
        // END modified code
        answers.add(cb);
        String text = cb.getText();
        answerList.addView(cb);
    }
}
0 голосов
/ 15 мая 2011

Как ни старайся, я не могу придумать причины, почему это происходит (и я с радостью поддержу любого, кто может это объяснить), но вот решение.По какой-то причине Android недоволен тем, что вы настраиваете раздувную разметку XML так близко к фактической инфляции в setContentView().Решение состоит в том, чтобы сделать динамическую часть процесса верстки либо в onPostCreate(), либо в onResume(), в зависимости от ваших потребностей.

Я бы порекомендовал onResume(), если вы можете себе это позволить, поскольку onPostCreate()обычно не рекомендуется для переопределения ... однако onResume() может вызываться часто и может испортить ваш макет.Вот ваш пример, модифицированный для использования onPostCreate().

public class Main extends Activity {

    ArrayList<AnswerView> answers = new ArrayList<AnswerView>();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        TextView title = (TextView)findViewById(R.id.questionText);
        title.setText("This is a test");
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);

        HashMap<String, Drawable> answerInfo = new HashMap<String, Drawable>();
        Resources res = getResources();
        answerInfo.put("a", res.getDrawable(R.drawable.flower_orange));
        answerInfo.put("b", res.getDrawable(R.drawable.flower_white));
        answerInfo.put("c", res.getDrawable(R.drawable.leaf));
        answerInfo.put("d", res.getDrawable(R.drawable.flower_yellow));
        setBoxes(answerInfo);
    }

    private void setBoxes(HashMap<String, Drawable> answerInfo) {
        LinearLayout answerList = (LinearLayout)findViewById(R.id.answerlist);
        AnswerView cb = null;

        //Remove all existing answer views
        answerList.removeAllViews();
        answers.clear();

        //For each possible answer create a answer views
        for (String s : answerInfo.keySet()) {
            cb = new AnswerView(this, s, answerInfo.get(s));
            answers.add(cb);
            String text = cb.getText();
            answerList.addView(cb);
        }
    }
}

Две другие вещи, которые я заметил, могут не повлиять на вас, но я решил упомянуть:

  1. Есливы хотите, чтобы ваши товары всегда возвращались в одном и том же порядке, HashMap.keySet() - плохой выбор.Этот метод возвращает эти значения в разных порядках в разных реализациях.Я бы порекомендовал LinkedHashMap или List, если вы хотите, чтобы порядок всегда был одинаковым.
  2. По крайней мере, в этом примере не имеет смысла очищать ваши коллекции перед установкой их снова.... так как это делается только тогда, когда Деятельность реконструируется в любом случае.Однако в более широкой реализации, возможно, это имеет более широкое назначение.

Надеюсь, что это поможет!Не стесняйтесь игнорировать все, что не было полезным:)

0 голосов
/ 15 мая 2011

Реализация

onSaveInstanceState ()
onRestoreInstanceState ()

в пользовательском макете AnswerView.

...