2014-09-26 2 views
1

Я использую GridView для отображения списка слов в таблице из четырех столбцов. Метод getView моего пользовательского адаптера проверяет ширину слова и сжимает его, если он не подходит. Он делает это с помощью рекурсивной проверки, которая сохраняет масштабирование текста до до.Android: обновление пользовательского интерфейса от адаптера внутри цикла while

private void shrinkText(final TextView wv, final String word) { 
    wv.setTextSize(defaultTextSize); 
    new Thread(new Runnable() { 
     @Override 
     public void run() { 
      while (wv.getWidth()>0 && wv.getPaint().measureText(word) > wv.getWidth()) { 
       Logg.d("word too big. Shrink from " + wv.getTextSize()/density + " to " + (wv.getTextSize()/density-1.0f)); 
       wv.setTextSize(wv.getTextSize()/density - 1.0f); 
      } 
     } 
    }).start(); 
} 

Так как я использую в то время цикл, я использую новую нить для защиты от НР в маловероятном случае, бесконечный цикл. Вот что странно: иногда отлично работает. А потом иногда я получаю следующее сообщение об ошибке:

09-26 14:25:31.389 6427-7765/com.myapp.debug E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-7789 
    Process: com.myapp.debug, PID: 6427 
    android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 

Я попытался положить setTextSize в заявлении runOnUiThread, но я не могу заставить его работать внутри адаптера. В конечном итоге я просто хочу, чтобы это сработало. Я думаю, что мои варианты:

  1. Держите время цикла в потоке пользовательского интерфейса и каким-то образом защитить его (как?)
  2. Перемещение setTextSize вызов в потоке пользовательского интерфейса
  3. Что-то еще (как?)?

Благодарим за помощь!

ОБНОВЛЕНИЕ: на основании ответа Рустама я использовал wv.post для записи в пользовательский интерфейс. Однако необходимость использования цикла while означала, что setTextSize должен выполняться в том же потоке, что и условие while. Я переключился с оценки TextView.getTextSize на Paint.getTextSize, так как я мог установить размер текста Paint без влияния на пользовательский интерфейс и, следовательно, в потоке ответвления. Джерри сфальсифицирован, но, похоже, он работает.

private void shrinkText(final TextView wv, final String word) { 
    wv.setTextSize(defaultTextSize); 
    final Paint mPaint = new Paint(wv.getPaint()); 
    new Thread(new Runnable() { 
     @Override 
     public void run() { 
      while (wv.getWidth()>0 && mPaint.measureText(word) > wv.getWidth()) { 
       Logg.d("word too big. Shrink from " + mPaint.getTextSize()/density + " to " + (mPaint.getTextSize()/density-1.0f)); 
       mPaint.setTextSize(mPaint.getTextSize() - 1.0f); 
      } 
      if (wv.getWidth()>0 && wv.getPaint().measureText(word) > wv.getWidth()) { 
       wv.post(new Runnable() { 
        @Override 
        public void run() { 
         Logg.d(word + " final size=" + mPaint.getTextSize()/density); 
         wv.setTextSize(mPaint.getTextSize()/density); 
        } 
       }); 
      } 
     } 
    }).start(); 
} 

ответ

0

попытка обновить так:

private void shrinkText(final TextView wv, final String word) { 
    wv.setTextSize(defaultTextSize); 
    new Thread(new Runnable() { 
     @Override 
     public void run() { 
       while (wv.getWidth()>0 && wv.getPaint().measureText(word) > wv.getWidth()) { 
       Logg.d("word too big. Shrink from " + wv.getTextSize()/density + " to " + (wv.getTextSize()/density-1.0f)); 
       wv.post(new Runnable() { 
        public void run() { 
         wv.setTextSize(wv.getTextSize()/density - 1.0f); 
        } 
       }); 
     } 
    }).start(); 
} 
+0

Просто пробовал ... Кажется, что setTextSize должен быть в том же потоке, что и условия в то время. Он прекратил рушиться, но он также не выполняет итерацию - просто продолжает переизбираться с 14 на 13, а затем по какой-то причине вообще исчезает с экрана. – Scott

+0

это может быть проблемой расчета. – Rustam

+0

Я думаю, что я решил проблему. Конечно, я не могу использовать метод wv.post внутри цикла while, так как условие while влияет на setTextSize. То, что я закончил, это сделать копию объекта Paint в TextView и оценить это - мне не потребовалось писать в пользовательский интерфейс. Затем после завершения цикла while я использовал этот объект Paint, чтобы установить свойство TextSize TextView внутри метода post. – Scott

Смежные вопросы