2015-10-07 105 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(); 
    } 
}