Итак, это мой сценарий: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.
Я злюсь об этом ... Я думаю, что это должно работать нормально, но это не так. Кто-нибудь может мне помочь?
Я знаю, что это немного (или много ...) беспорядочно. Если вы не понимаете, что-то не стесняйтесь спрашивать.
спасибо.
Почему вы не рассматривали случай 'else' для' if (v == null) 'в методе' getView'? Что делать, если представление представляет собой переработанное представление? – Rajesh
Хороший вопрос ... У меня так много всего в голове, я этого не понял. Попытаемся. – Fustigador