2013-11-10 21 views
2

我正在服务器中使用数据库MySQL实现聊天。现在,我想更新我在线程中的自定义Listview,但我不知道如何?使用线程自动更新列表视图

继承人我的代码:

chat_con_activity.java

import android.app.Activity; 
    import android.content.Context; 
    import android.os.AsyncTask; 
    import android.os.Bundle; 
    import android.os.StrictMode; 
    import android.os.SystemClock; 
    import android.view.View; 
    import android.view.View.OnClickListener; 
    import android.widget.ArrayAdapter; 
    import android.widget.BaseAdapter; 
    import android.widget.Button; 
    import android.widget.EditText; 
    import android.widget.ListAdapter; 
    import android.widget.ListView; 
    import android.widget.Toast; 

    import com.example.classes.IpUpdater; 
    import com.example.classes.Messages_con_adapter; 
    import com.example.classes.Send_Message; 
    import com.example.classes.View_Messages; 
    import com.example.tabs.user_online; 
    import com.example.wifivoip.R; 

    public class chat_con_activity extends Activity implements Runnable{ 
     private ListView list = null; 
     ArrayAdapter<String> la; 
     Button send_btn; 
     EditText chat_msg; 
     String user; 
     String cTo; 
     String[] names; 
     String[] namesfrm; 
     String[] msgs; 
     String[] datez; 
     int stop = 0; 
     Context cn = this; 
     Thread x; 
     int count; 
     Messages_con_adapter mca; 
     @Override 
     public void onCreate(Bundle savedInstanceState) { 
      StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder() 
      .permitAll().build(); 
    StrictMode.setThreadPolicy(policy); 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.send_chat); 
      send_btn = (Button) findViewById(R.id.chat_btn_send); 
      chat_msg = (EditText) findViewById(R.id.chat_text_send); 
      user = getIntent().getStringExtra("cFrom"); 
      cTo = getIntent().getStringExtra("cTo"); 



      list = (ListView) findViewById(R.id.chat_list_view); 

      Toast.makeText(getApplicationContext(), ""+user+" "+cTo, Toast.LENGTH_SHORT).show(); 
      display(); 

      x = new Thread(new Runnable() { 

       @Override 
       public void run() { 
        // TODO Auto-generated method stub 
        while(true){ 
         try{ 
          //Thread.sleep(1000); 

          View_Messages vm = new View_Messages(user, cTo); 
          int cnt = vm.getIfNew(); 
          System.err.println(""+cnt+" "+count); 
          if(cnt != count){ 
           System.err.println(""+cnt+" "+count); 


           names = vm.getAllNamesTo(); 
           namesfrm = vm.getAllNamesFrom(); 
           msgs = vm.getAllMsgs(); 
           datez = vm.getAllDates(); 
           count = vm.getIfNew(); 

           list.setAdapter(la); 
           list.setSelection(list.getAdapter().getCount() - 1); 

          } 
          if(stop == 1){ 
           break; 
          } 

         }catch (Exception e) { 
          // TODO: handle exception 
         } 
        } 
       } 
      });x.start(); 

      send_btn.setOnClickListener(new OnClickListener() { 

       @Override 
       public void onClick(View arg0) { 
        // TODO Auto-generated method stub 
        String msg = chat_msg.getText().toString().trim(); 
        if(!msg.equals("")){ 
         new Send_Message().sendMessage(user, cTo, msg); 
         display(); 
         chat_msg.setText(""); 
        }else{ 
         Toast.makeText(getApplicationContext(), "No message to send!!", Toast.LENGTH_SHORT).show(); 
        } 
       } 
      }); 

     } 


     @Override 
     public void onDestroy(){ 
      super.onDestroy(); 
      stop = 1; 
     } 



     public void display(){ 
      View_Messages vm = new View_Messages(user, cTo); 
      names = vm.getAllNamesTo(); 
      namesfrm = vm.getAllNamesFrom(); 
      msgs = vm.getAllMsgs(); 
      datez = vm.getAllDates(); 
      count = vm.getIfNew(); 

      list.setDivider(null); 

      la = new Messages_con_adapter(this, user, names, namesfrm,msgs,datez,cTo); 
      list.setAdapter(la); 
      list.setSelection(list.getAdapter().getCount() - 1); 
     } 

我的适配器是: Message_con_adapter.java

import android.content.Context; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ArrayAdapter; 
import android.widget.TextView; 

public class Messages_con_adapter extends ArrayAdapter<String>{ 
    String user; 
    String[] name; 
    String[] namefrm; 
    String[] msgs; 
    String[] dates; 
    Context context; 
    View rowView; 


    public Messages_con_adapter(Context context,String user, String[] name,String[] namefrm, String[] msgs,String[] dates,String To) { 
     super(context, R.layout.chat_con,name); 

     this.user = user; 
     this.context = context; 
     this.msgs = msgs; 
     this.name = name; 
     this.namefrm = namefrm; 
     this.dates = dates; 
     this.To = To; 

    } 


    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     LayoutInflater inflater = (LayoutInflater) context 
      .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 




     if(namefrm[position].equals(user)){ 
      rowView = inflater.inflate(R.layout.chat_con_home, parent, false); 
      TextView dateTimeHome = (TextView) rowView.findViewById(R.id.time_c_home); 
      TextView c_home = (TextView) rowView.findViewById(R.id.c_u_home); 
      TextView c_home_m = (TextView) rowView.findViewById(R.id.c_u_home_m); 
      dateTimeHome.setText(dates[position]); 
      c_home.setText(user); 
      c_home_m.setText(msgs[position]); 


     }else 
     { 
      rowView = inflater.inflate(R.layout.chat_con, parent, false); 
      TextView dateTimeAway = (TextView) rowView.findViewById(R.id.time_c_away); 
      TextView c_away = (TextView) rowView.findViewById(R.id.c_u_away); 
      TextView c_away_m = (TextView) rowView.findViewById(R.id.c_u_away_m); 
      dateTimeAway.setText(dates[position]); 
      c_away.setText(namefrm[position]); 
      c_away_m.setText(msgs[position]); 

     } 

     return rowView; 
    } 

任何想法,先生?请帮忙。 =(

在此先感谢。

回答

1

从不更新从一个非UI线程你的列表视图,而不是考虑使用处理。

1

您可以更新列表视图,

首先,它取决于你在此情况下要更新您的列表视图。

可以使用onscroll监听器列表视图更新列表视图。

现在

q题目了是如何更新自定义列表视图中的数据,

当数据需要更新,那么你必须调用这个方法,

public void updateDate(String user, String[] name,String[] namefrm, String[] msgs,String[] dates,String To) { 
    super(context, R.layout.chat_con,name); 

    this.user = user; 
    this.context = context; 
    this.msgs = msgs; 
    this.name = name; 
    this.namefrm = namefrm; 
    this.dates = dates; 
    this.To = To; 
} 

这种方法与乌尔previos适配器对象调用,然后调用

adapterObject.notifyDataSetChanged();

您的列表视图已更新。

0

我有更好的解决方案。你可以绑定listView和你的数据库,Android会自动更新你的ListView,如果数据库刷新了新的数据,那么你的工作只会从服务器接收消息并放入数据库。

为此,您需要实现ContentProvider - 它是SQLite数据库的包装。之后,你实现了CursorAdapter - 它与ArrayAdapter有着不同之处。最后一步是通过ContentResolver调用ContentProvider,它返回一个游标,并且还会通知您的适配器表中的更改。有关更多详细信息,请参阅http://www.vogella.com/articles/AndroidSQLite/article.html#sqliteoverview_listviews

0

要更新UI相关组件,请使用AsyncTask来做到这一点。
它非常容易和最佳实践。
这里是doc
从你提供的代码,使用你已经在你的线程run()方法做了同样的代码来
AsynTask'sdoInBackgrond()方法。
编辑
由于您是Android新手,您可能需要查看这里的example

+0

我同意最好的是使用AsyncTask,但一般来说规则是从UI线程更新视图,所以如果不是AsyncTask,那么runOnUiThread(Runnable)方法或Handler。 http://stackoverflow.com/questions/12850143/android-basics-running-code-in-the-ui-thread – fgeorgiew

+0

谢谢你的回应先生,但我怎么能调用AsyncTask来执行它?抱歉,我是Android新手。 =) –

+0

@KentSabanal请参阅编辑 – johntheripp3r