2013-02-12 3 views
2

Я пытаюсь добавить несколько текстовых просмотров в уже раздутый макет. Отображаемая информация извлекается из базы данных с одним текстовым представлением, созданным для каждой строки в базе данных. Поскольку база данных может быть чрезвычайно большой, я создаю каждый текстовый файл по одному в фоновом потоке и добавляю его на передний план.Добавление представления из фоновой темы

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

private TextView temp; 
private void addClickableEvent(ReviewHistoryEvent e){ 
    if(e == null){ 
     Log.e(tag,"Attempted to add a null event to review history"); 
     return; 
    } 
    TextView t = new TextView(getBaseContext()); 
    t.setTag(e); 
    t.setText(e.getTime()+" "+e.getEvent()); 
    t.setClickable(true); 
    t.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); 
    t.setTextAppearance(getBaseContext(), R.style.Information_RegularText); 
    t.setGravity(Gravity.CENTER); 
    t.setOnClickListener(this); 

    temp = t; 
    runOnUiThread(new Runnable() { 
     public void run() { 
      LinearLayout display = (LinearLayout) findViewById(R.id.reviewHistory_display); 
      display.addView(temp); 
     } 
    }); 
} 

Эта функция выполняется один раз успешно, и появится первый TextView. Однако, когда он вызывается второй раз, он не работает на дисплее .addView (temp); строка со следующей ошибкой:

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the childs's parent first. 

Я не уверен, почему моя TextView уже имеет родителя, если он якобы вновь инстанцирован. Также я использую temp textview, чтобы обойти мой runnable, не имея возможности ссылаться на местный textview t. Это верно? Любая помощь будет оценена по достоинству.

+2

Вы, возможно, придется играть с ним немного. Что делать, если вы используете 'final TextView t' и' addView (t) 'вместо использования переменной-члена? Кроме того, попробуйте удалить все вызовы '.set *()' и посмотреть, не портится ли он. – Eric

+0

Я согласен с Эриком, попробуйте использовать последнюю переменную TextView. Также попробуйте установить уникальный идентификатор для каждого представления ('setId (int)'). – Leandros

+0

@ Эрик Я бы высказал свой ответ, я бы все равно его поддержал. Я почти уверен, что это действительно проблема. «Runnable's» находятся в очереди и, вероятно, выполняются несколько подряд, все с той же ссылкой на «temp», которая является той же переменной, указывает на тот же объект. Использование 'final TextView t' исправляет это. Совпадает с наблюдаемым поведением. – kabuko

ответ

3

Вместо того, чтобы использовать переменную-член (который может быть изменен, и который не является локальным, конечно), используйте вместо final TextView:

final TextView t = new TextView(getBaseContext()); 
// ... 

temp = t; // Remove this 
runOnUiThread(new Runnable() { 
    public void run() { 
     // ... 
     display.addView(t); 
    } 
});