2015-10-07 4 views
0

У меня есть метод, который считывает данные из файла csv, а затем создает объект, содержащий эти данные. Затем данные используются для раздувания пользовательского представления строки с помощью настраиваемого адаптера для заполнения списка. Первая строка должна быть отображена, а затем короткая задержка перед добавлением следующей строки в список.Listview не заметно заполняется

Проблема заключается в том, что при вызове метода экран становится черным для общего времени задержки (если время задержки составляет 1 секунду с 5 сообщениями = 5 секунд черноты), тогда ListView отображается со всеми строками, а не показывая, что он заселен по одному за раз.

playChat Метод:

public void playChat(){ 
    View row = null; 
    int delay = 1000; 

    try{ 
     InputStream is = this.getAssets().open("chat.csv"); 
     BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 
     String line; 

     while((line = reader.readLine())!= null){ 
      String[] rowData = line.split(","); 
      ChatText current = new ChatText(); 

      current.setUser(rowData[0]); 
      current.setChatText(rowData[1]); 

      chatTexts.add(current); 

      playView.invalidateViews(); 
      try { 
       Thread.sleep(delay); 
      } catch(InterruptedException ex) { 
       Thread.currentThread().interrupt(); 
      } 
     } 
    }catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

Мой заказ адаптер:

public ChatAdapter(Context context, ArrayList<ChatText> chatTexts){ 
    super(context, R.layout.chat_layout_left,chatTexts); 
    this.ctx = context; 
} 

public View getView(final int pos, View convertView, final ViewGroup parent) { 
    View row = convertView; 

    String user = getItem(pos).getUser(); 

    if (null == row){ 
     LayoutInflater inflater = ((Activity)ctx).getLayoutInflater(); 

     holder = new DetailHolder(); 
     holder.imgIcon = (ImageView)row.findViewById(R.id.imgIcon); 

     holder.txtUser = (TextView)row.findViewById(R.id.txtUser); 

     holder.txtChatText = (TextView)row.findViewById(R.id.txtChatText); 

     row.setTag(holder); 
    } 
    else{ 
     holder = (DetailHolder)row.getTag(); 
    } 

    holder.imgIcon.setImageResource(R.drawable.icon_one); 
    holder.txtUser.setText(getItem(pos).getUser()); 
    holder.txtChatText.setText(getItem(pos).getChatText()); 

    return row; 
} 

Помощь будут оценены

ответ

1

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

Вы хотите что-то вроде этого (мой синтаксис может быть немного прочь, но это должно быть близко):

public synchronized void playChat(){ 
    InputStream is = this.getAssets().open("chat.csv"); 
    final BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 
    new Thread(new Runnable() { 
     View row = null; 
     int delay = 1000; 
     Handler handler = new Handler(Looper.getMainLooper()); 
     @Override 
     public synchronized void run() { 
      try{ 
       String line; 
       while((line = reader.readLine())!= null){ 
        String[] rowData = line.split(","); 
        ChatText current = new ChatText(); 

        current.setUser(rowData[0]); 
        current.setChatText(rowData[1]); 

        addChatText(current); 
        try { 
         Thread.sleep(delay); 
        } catch(InterruptedException ex) { 
         Thread.currentThread().interrupt(); 
        } 
       } 
      }catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 

     private synchronized void addChatText(final ChatText current){ 
      handler.post(new Runnable() { 
       @Override 
       public void run() { 
        chatTexts.add(current); 
        playView.invalidateViews(); 
       } 
      }); 
     } 
    }).start(); 
} 

Кроме того, не забудьте закрыть все после :)

+1

Рад, что это помогло! Отметьте это правильно, если бы вы :). – wblaschko

0

проблема в том, что вы никогда не должны ставить «блокирующий код» в основной поток. Например, код Thread.sleep(delay) остановит основной поток за этот промежуток времени. Основной поток - это то, где Android обновляет пользовательский интерфейс. Вот почему ваш экран становится черным.

Вы можете прочитать об этом здесь: http://developer.android.com/training/articles/perf-anr.html

способ достижения того, что вы хотите сделать, это с помощью класса AssyncTask. Вот как я думаю, ваш код может быть:

import android.os.AsyncTask; 
import android.widget.ListView; 

public class UpdateListTask extends AsyncTask<Void, Void, Void> { 
    private ListView mListView; 

    public UpdateListTask(ListView listView) { 
     mListView = listView; 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void aVoid) { 
     super.onPostExecute(aVoid); 

     mListView.invalidateViews(); 
    } 
} 
Смежные вопросы