Invalidate не перерисовывает экран. Android - PullRequest
2 голосов
/ 22 февраля 2011
BufferedReader hl  = new BufferedReader(new InputStreamReader(getResources().openRawResource(R.raw.lines)));
                while(hl.ready()){
                    showLines.append(hl.readLine()+"\n");
                    showLines.invalidate();
                    Thread.sleep(10);
                }

Это мой код, но он не перерисовывается, когда я говорю об этом.Он должен перерисовываться после каждой строки, добавляемой в textview, но он все еще перерисовывается только в конце?Может кто-нибудь, пожалуйста, помогите мне, я не могу понять это.

Ответы [ 2 ]

2 голосов
/ 22 февраля 2011

Это потому, что ваш invalidate () находится в потоке во время цикла и накапливается, так сказать, до тех пор, пока цикл не закончится, и только тогда, когда он отрисовывает ...

У меня была такая же проблема при использовании Thread.sleep () в цикле. Вы можете использовать метод с отложенной задержкой для рисования каждой линии, которая в данном случае составляет одну строку в секунду:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    BufferedReader hl  = new BufferedReader(new InputStreamReader(getResources().openRawResource(R.raw.text))); 
    TextView showLines = (TextView) findViewById(R.id.textView1);
    appendLines(hl, showLines);

}


public void appendLines(final BufferedReader br, final TextView tv){
    Handler handler = new Handler(); 
     handler.postDelayed(new Runnable() {           
         public void run() {                
             try {
                if(br.ready()){                     
                     try {
                        tv.append(br.readLine()+"\n");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }                     
                     tv.invalidate();                     
                     appendLines(br, tv);             
                     }
            } catch (IOException e) {
                e.printStackTrace();
            } 
         }
         }, 1000); 
     }
1 голос
/ 22 февраля 2011

Это мой код, но он не перерисовывается, когда я говорю об этом.

invalidate() не происходит сразу, когда вы звоните.invalidate(), как и append(), и все, что связано с пользовательским интерфейсом, помещает сообщение в очередь сообщений, которое будет обрабатываться основным потоком приложения, как только вы его разрешите.Поскольку вы тратите время пользователя на бессмысленные sleep() вызовы, а также выполняете флэш-ввод-вывод в цикле основного потока приложения, основной поток приложения не может обрабатывать сообщения в очереди сообщений.Он будет обрабатывать все ваши invalidate() и append() вызовы после завершения цикла, и вы возвращаете управление Android с любого обратного вызова.

Предполагается, что он будет перерисовываться после каждой строки,добавлен в текстовое представление

Нет, это не так.

но он все еще только перерисовывается в конце?

Исправить.

Простое решение - избавиться от invalidate() и Thread.sleep(10) и просто загрузить все содержимое файла в ваш TextView за один вызов.

Лучшее решение -чтобы вы могли прочитать весь файл через AsyncTask, а затем добавить текст к TextView за один вызов в onPostExecute().При необходимости используйте ProgressDialog или что-то еще, чтобы развлечь пользователя, пока это происходит.

...