2016-02-22 12 views
5

Sto provando a creare una semplice applicazione di chat. Con la schermata di conversazione chat sto usando ListView con ArrayAdapter per archiviare e mostrare il messaggio, ma quando ricevo o invio un nuovo messaggio, tutto il messaggio recente è cambiato.Errore durante l'aggiunta di nuovi dati a ListView con ArrayAdapter

Questo è il mio codice adattatore:

public class MessageAdapter extends ArrayAdapter<Message> { 
    private Context context; 
    private ArrayList<Message> messages; 
    private DatabaseHelper databaseHelper; 
    private Message message; 

    @Override 
    public void add(Message object) { 
     messages.add(object); 
     super.add(object); 
    } 

    public MessageAdapter(Context context, int textViewResouceId, ArrayList<Message> messages) { 
     super(context, textViewResouceId); 
     this.context = context; 
     this.messages = messages; 
     databaseHelper = DatabaseHelper.getInstance(context); 
    } 

    public int getCount() { 
     return messages.size(); 
    } 

    public Message getItem(int index) { 
     return messages.get(index); 
    } 

    public long getItemId(int position) { 
     return position; 
    } 

    @Override 
    public int getPosition(Message item) { 
     return super.getPosition(item); 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     MessageViewHolder messageViewHolder; 

     if (convertView == null) { 
      LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); 
      convertView = inflater.inflate(R.layout.chat_item, parent, false); 
      messageViewHolder = new MessageViewHolder(); 
      messageViewHolder.tv_userName = (TextView) convertView.findViewById(R.id.tv_chatName); 
      messageViewHolder.tv_message = (TextView) convertView.findViewById(R.id.tv_messageContent); 
      convertView.setTag(messageViewHolder); 
     } else { 
      messageViewHolder = (MessageViewHolder) convertView.getTag(); 
     } 
     message = messages.get(position); 
     String username = databaseHelper.getUserByUserId(message.getUserId()).getUserName(); 
     if (message.getUserId() == AppConfig.USER_ID) { 
      messageViewHolder.tv_message.setTextColor(Color.parseColor("#0066ff")); 
      messageViewHolder.tv_userName.setTextColor(Color.parseColor("#0066ff")); 
     } else { 
      messageViewHolder.tv_message.setTextColor(Color.parseColor("#000000")); 
      messageViewHolder.tv_userName.setTextColor(Color.parseColor("#000000")); 
     } 
     messageViewHolder.tv_userName.setText(username); 
     messageViewHolder.tv_message.setText(message.getMessage()); 

     return convertView; 
    } 

    static class MessageViewHolder { 
     TextView tv_message; 
     TextView tv_userName; 
    } 


} 

Questo è il mio ListView codice Disposizione:

<LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:orientation="vertical"> 

     <android.support.design.widget.AppBarLayout 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:theme="@style/AppTheme.AppBarOverlay"> 

      <android.support.v7.widget.Toolbar 
       android:id="@+id/toolbar" 
       android:layout_width="match_parent" 
       android:layout_height="?attr/actionBarSize" 
       android:background="?attr/colorPrimary" 
       app:popupTheme="@style/AppTheme.PopupOverlay" /> 

     </android.support.design.widget.AppBarLayout> 

     <ScrollView 
      android:id="@+id/scroll_chat" 
      android:layout_width="match_parent" 
      android:layout_height="380dp"> 

      <LinearLayout 
       android:layout_width="match_parent" 
       android:layout_height="match_parent"> 

       <ListView 
        android:id="@+id/listMessage" 
        android:layout_width="match_parent" 
        android:layout_height="380dp" 
        android:background="@null" 
        android:divider="@null" 
        android:stackFromBottom="true" 
        android:drawSelectorOnTop="false" 
        android:transcriptMode="alwaysScroll" /> 
      </LinearLayout> 


     </ScrollView> 

     <LinearLayout 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:orientation="horizontal" 
      android:weightSum="1"> 

      <EditText 
       android:id="@+id/txt_chat" 
       android:layout_width="wrap_content" 
       android:layout_height="match_parent" 
       android:layout_weight="0.92" /> 

      <Button 
       android:id="@+id/btn_send" 
       android:layout_width="wrap_content" 
       android:layout_height="match_parent" 
       android:layout_marginLeft="30dp" 
       android:text="@string/btn_send" /> 
     </LinearLayout> 
    </LinearLayout> 

e questo è l'errore quando invio di due messaggi (lo stesso errore accade quando ricevo un messaggio)

First Message

Second Message

Penso che il problema sia il modo in cui impostare i dati su Visualizza ma non posso risolverlo. Qualcuno potrebbe aiutarmi a risolvere questo problema.

Questa è la schermata della chat quando chiudo e apro di nuovo l'attività: ha mostrato il messaggio corretto.

enter image description here

Questo è il codice Chatactivity:

public class ChatActivity extends AppCompatActivity implements View.OnClickListener { 
    private Button btn_send; 
    private static EditText txt_chat; 
    private String registId; 
    private Bundle bundle; 
    private String chatTitle; 
    private MessageSender mgsSender; 
    private int userId; 
    private DatabaseHelper databaseHelper; 
    private TimeUtil timeUtil; 
    private MessageAdapter messageAdapter; 
    private ListView lv_message; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_chat); 
     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 
     if (getSupportActionBar() != null) { 
      getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
     } 
     btn_send = (Button) findViewById(R.id.btn_send); 
     txt_chat = (EditText) findViewById(R.id.txt_chat); 
     lv_message = (ListView) findViewById(R.id.listMessage); 
//  lv_message.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL); 
     timeUtil = new TimeUtil(); 
     databaseHelper = DatabaseHelper.getInstance(getApplicationContext()); 
     btn_send.setOnClickListener(this); 
     bundle = getIntent().getExtras(); 
     chatTitle = bundle.getString("titleName"); 
     if (getIntent().getBundleExtra("INFO") != null) { 
      chatTitle = getIntent().getBundleExtra("INFO").getString("name"); 
      this.setTitle(chatTitle); 
     } else { 
      this.setTitle(chatTitle); 
     } 
     registId = bundle.getString("regId"); 
     userId = databaseHelper.getUser(chatTitle).getUserId(); 
     List<Message> messages = databaseHelper.getMessges(AppConfig.USER_ID, databaseHelper.getUser(chatTitle).getUserId()); 
     messageAdapter = new MessageAdapter(getApplicationContext(), R.layout.chat_item, (ArrayList<Message>) messages); 
     LocalBroadcastManager.getInstance(this).registerReceiver(onNotice, new IntentFilter("Msg")); 
     if (messages.size() > 0) lv_message.setAdapter(messageAdapter); 
    } 

    private BroadcastReceiver onNotice = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      String message = intent.getStringExtra("message"); 
      try { 
       Message messageObj = Message.getInstance(); 
       messageObj.setMessage(message); 
       messageObj.setUserId(userId); 
       messageObj.setSender_id(AppConfig.USER_ID); 
       messageObj.setExpiresTime(timeUtil.formatDateTime(timeUtil.getCurrentTime())); 
       messageAdapter.add(messageObj); 
      } catch (ParseException e) { 
       e.printStackTrace(); 
      } 
      messageAdapter.notifyDataSetChanged(); 
     } 
    }; 


    @Override 
    public void onBackPressed() { 
     super.onBackPressed(); 
     finish(); 
    } 


    @Override 
    protected void onDestroy() { 
     LocalBroadcastManager.getInstance(this).unregisterReceiver(onNotice); 
     super.onDestroy(); 
    } 


    private static MessageSenderContent createMegContent(String regId, String title) { 
     String message = txt_chat.getText().toString(); 
     MessageSenderContent mgsContent = new MessageSenderContent(); 
     mgsContent.addRegId(regId); 
     mgsContent.createData(title, message); 
     return mgsContent; 
    } 

    @Override 
    public void onClick(View v) { 
     switch (v.getId()) { 
      case R.id.btn_send: 
       String message = txt_chat.getText().toString(); 
       databaseHelper = DatabaseHelper.getInstance(getApplicationContext()); 
       mgsSender = new MessageSender(); 
       new AsyncTask<Void, Void, Void>() { 
        @Override 
        protected Void doInBackground(Void... params) { 
         MessageSenderContent mgsContent = createMegContent(registId, AppConfig.USER_NAME); 
         mgsSender.sendPost(mgsContent); 
         return null; 
        } 
       }.execute(); 
       databaseHelper.addMessage(message, timeUtil.getCurrentTime(), userId, AppConfig.USER_ID); 
       txt_chat.setText(""); 
       try { 
        Message messageObj = Message.getInstance(); 
        messageObj.setMessage(message); 
        messageObj.setUserId(AppConfig.USER_ID); 
        messageObj.setSender_id(userId); 
        messageObj.setExpiresTime(timeUtil.formatDateTime(timeUtil.getCurrentTime())); 
        messageAdapter.add(messageObj); 
       } catch (ParseException e) { 
        e.printStackTrace(); 
       } 
       messageAdapter.notifyDataSetChanged(); 
       break; 
     } 
    } 

} 
+0

quando si aggiunge un nuovo elemento alla matrice è necessario informare l'adattatore per esempio (adapter.notifyDataSetChanged();) - Provalo e segnala – Tasos

+0

l'array di messaggi ha dati corretti? –

+0

@Tasos Ho già utilizzato adapter.notifyDataSetChanged() e funziona correttamente. I dati sono stati salvati nel database è corretto, viene visualizzato solo un messaggio di errore relativo alla visualizzazione del messaggio recente –

risposta

2

Nella tua ChatActivity. In onClickEvent
tenta di modificare

Message messageObj = Message.getInstance(); 

a

Message messageObj = new Message(); 

Si può leggere di più su Singleton Pattern in here

+2

Grazie tu, lavori con successo. Potresti spiegare il motivo per me. Sono ancora confuso a riguardo. :) –

+0

Scusa, non posso spiegarlo bene perché ne so un po '.È 'Singleton Design Pattern'. Dovresti fare delle ricerche per capire il tuo problema;) –

+0

Capito. Grazie :) –