2015-10-07 56 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更新UI的地方。這就是爲什麼你的屏幕變黑。

你可以閱讀更多關於此這裏: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(); 
    } 
}