2013-05-23 4 views
0

Итак, это мой сценарий:ArrayAdapter не работает должным образом

Я развиваю чат с помощью JSON (у нас пока нет Jabber-сервера). Существует услуга просит новые сообщения чата каждые 30 секунд:

public class ChatService extends Service { 



ArrayList<NameValuePair> params; 
int subnotid; 
String urlaskmessages; 
String response; 
ArrayList<String> mensajes; 

Timer timer=new Timer(); 

@Override 
public void onCreate() { 

    super.onCreate(); 
    subnotid=General.subnotid; 
    urlaskmessages=getString(R.string.host)+getString(R.string.appnamespace)+getString(R.string.chatpedir); 
    mensajes=new ArrayList<String>(); 
    timer.scheduleAtFixedRate(new TimerTask() { 

     @Override 
     public void run() { 
      Log.i("CHAT", "Llamamos al servicio ChatService"); 
      llamarServicio(); 
     } 
    }, 0, 30000); 

} 

@Override 
public IBinder onBind(Intent intent) { 
    // TODO Auto-generated method stub 
    return null; 
} 

public void llamarServicio(){ 

    Thread thread=new Thread(){ 

     public void run(){ 


      params=new ArrayList<NameValuePair>(); 
      params.add(new BasicNameValuePair("subnotid", String.valueOf(subnotid))); 
      try { 
       response=CustomHttpClient.executeHttpPost(urlaskmessages, params); 
       mensajes=parseJSON(response); 
       if(mensajes!=null){ 
        General.mensajes.clear(); 

        for (int i=0;i<mensajes.size();i++){ 
         General.mensajes.add(i, mensajes.get(i)); 
        } 

       } 
      } catch (Exception e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 

     private ArrayList<String> parseJSON(String resp) { 

      //General.mensajes=new ArrayList<String>(); 
      mensajes=new ArrayList<String>(); 
      JSONObject total; 

      try { 
       total = new JSONObject(resp); 
       Log.i("JSON","Respuesta recibida: "+resp); 
       JSONObject paso1=new JSONObject(total.getString("chat")); 
       JSONArray paso2=new JSONArray(paso1.getString("mensajes")); 
       //JSONArray paso3=new JSONArray(paso2.getString("mensaje")); 
       for (int i=0;i<paso2.length();i++){ 
        JSONObject jobj=paso2.getJSONObject(i); 
        mensajes.add(i,jobj.getString("mensaje")); 
        Log.i("JSON","Añadido objeto: "+paso2.getString(i)); 
       } 
      } catch (JSONException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      return mensajes; 
     } 
    }; 

    thread.start(); 
} 

@Override 
public void onDestroy() { 
    super.onDestroy(); 
    Log.i("CHAT", "ChatService destruido"); 
    timer.cancel(); 

} 

} 

Как вы можете видеть, я получаю ответ от сервера, разбор JSON и возвращает ArrayList, содержащее все сообщения, которые хранятся в Singleton class, где я храню некоторые значения (вот почему General.mensajes). Все это происходит, когда другое действие открыто и выполняет свой долг (высылайте объекты LatLng). Эта активность должна реагировать, когда пользователь получает новое сообщение, и открыть чат Активность:

timer.scheduleAtFixedRate(new TimerTask() { 

     @Override 
     public void run() { 
      try{ 


       if(General.mensajes.size() > numerodemensajes && General.chatabierto==false){ 
        Intent chat=new Intent(c, ChatActivity.class); 
        General.AzafataChat=false; 
        startActivity(chat); 
       } 

      }catch(Exception e){ 
       e.printStackTrace(); 
      } 


      numerodemensajes=General.mensajes.size(); 

     } 
    }, 0, 10000); 

В ChatActivity, у меня есть обработчик среагировать на прибывающих новое сообщение, и назначьте адаптер ::

mHandler.post(new Runnable() { 

     public void run() { 

      madapter = new MessageAdapter(getApplicationContext(), 0, General.mensajes); 
      setListAdapter(madapter); 
     } 

    }); 

И, наконец, адаптер:

public class MessageAdapter extends ArrayAdapter { 

private final Context context; 
//private final ArrayList<Message> list; 
private final ArrayList<String>list; 
private Bitmap x; 
String remitente; 
String message; 
String remite; 
String mensaje; 
private int numberOfItems; 

@SuppressWarnings("unchecked") 
public MessageAdapter(Context context, int textresourceViewid, 
     ArrayList<String> messages) { 
    super(context, textresourceViewid, messages); 
    this.context = context; 
    this.list = messages; 

} 

@Override 
public int getCount() { 

    return this.list.size(); 

} 

@Override 
public Object getItem(int position) { 

    return this.list.get(position); 
} 

@Override 
public long getItemId(int position) { 
    // TODO Auto-generated method stub 
    return position; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    View v = convertView; 
    numberOfItems=list.size(); 
    try { 

     message = list.get(position); 

    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     //e.printStackTrace(); 

    } 
    //ViewHolder holder=new ViewHolder(); 
    if (v == null) { 

     if (message.split(":")[0].equals("personal")){ 
      //holder=new ViewHolder(); 
      Log.i("CHAT", "En la lista hay "+list.size()+" mensajes"); 
      Log.i("CHAT", "El mensaje dice: "+list.get(0).split(":")[1]); 
      LayoutInflater vi = (LayoutInflater) context 
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      v = vi.inflate(R.layout.chatsenderlayout, null);  
      if (message != null) { 
       TextView texto=(TextView)v.findViewById(R.id.textaza); 
       texto.setText(message); 



      } 
     }else{ 
      Log.i("CHAT", "Estamos en el else"); 
     //holder=new ViewHolder(); 
     LayoutInflater vi = (LayoutInflater) context 
       .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = vi.inflate(R.layout.chatazafatalayout, null); 
     if (message != null) { 
      TextView texto=(TextView)v.findViewById(R.id.textaza); 
      texto.setText(message); 



     } 



    } 


    }  
    return v; 
} 



public int getLastIndex() { 
    int last = 0; 
    if (!list.isEmpty()) { 
     last = list.size() - 1; 
    } 
    return last; 
} 


} 

После всего этого, проблема:

Когда ChatActivity открыт, он показывает только последние 5 сообщений ... повторяется, я имею в виду: если в ArrayList присутствует 12 сообщений, ChatActivity показывает 12 сообщений, но только 5 последних сообщений: 8,9,10,11 , 12,8,9,10,11,12,8,9.

Я злюсь об этом ... Я думаю, что это должно работать нормально, но это не так. Кто-нибудь может мне помочь?

Я знаю, что это немного (или много ...) беспорядочно. Если вы не понимаете, что-то не стесняйтесь спрашивать.

спасибо.

+1

Почему вы не рассматривали случай 'else' для' if (v == null) 'в методе' getView'? Что делать, если представление представляет собой переработанное представление? – Rajesh

+0

Хороший вопрос ... У меня так много всего в голове, я этого не понял. Попытаемся. – Fustigador

ответ

1

в вашем адаптере getView метод, у вас есть пропуск для v == null, но не путь для, когда v не является нулевым, поэтому, когда listview просматривает переработку, а параметры convertView, переданные вашему методу getView, не являются null, ваш метод ничего не делает и поэтому отображается предыдущее представление (показывающее старые данные строки). Вам нужно добавить случай, когда v! = Null, и соответственно обновить существующее представление.

+0

Хм ... должен ли я просто «вернуть v», если v не является нулевым? – Fustigador

+0

Это то, что вы сейчас делаете. Что вам нужно сделать, это обновить представления в v с вашими новыми данными. (или в качестве короткого взлома, чтобы доказать, что это проблема, игнорировать начальное значение v и всегда раздувать новый вид) – superfell

+0

Теперь, когда я принудительно возвращаю новый вид, он отлично работает сейчас. Спасибо!! – Fustigador