title: add new view to a listview with a cutom adapter
body: <p>here is my question.</p>
  
  <p>I'm starting android recently, and like to build a instant messenger.</p>
  
  <p>I used a listview to display the chatting history but failed to add new message into the listview. Please help if anyone could.</p>
  
  <p>here is the code:</p>
  
  <p>XML</p>
  
  <pre><code>&lt;ListView
  android:id="@+id/list"
  android:layout_width="fill_parent"
  android:layout_height="0dip"
  android:layout_above="@id/bottom_write_bar"
  android:layout_alignParentTop="true"
  android:cacheColorHint="#00000000"
  android:divider="#00000000"
  android:listSelector="#00000000" &gt;
  &lt;/ListView&gt;
  </code></pre>
  
  <p>Java</p>
  
  <pre><code>public class MessageActivity extends Activity {
  
      private EditText messageText;
      private ListView historyList;
      private Button sendButton;
      private AppManager appService;
      private FriendInfo friend = new FriendInfo();
      private LocalDataHandler localDataHandler;
      private Cursor dbCursor;
      private MessageAdapter adapter;
  
      private ArrayList&lt;Message&gt; messages = new ArrayList&lt;Message&gt;();
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_message);
  
          historyList = (ListView) findViewById(R.id.list);
          messageText = (EditText) findViewById(R.id.messageText);
          sendButton = (Button) findViewById(R.id.sendButton);
  
          adapter = new MessageAdapter(this, messages);
          historyList.setAdapter(adapter);
  
          Bundle extras = this.getIntent().getExtras();
          String msg = extras.getString(MessageInfo.MESSAGETEXT);
          setTitle("Messaging with " + friend.userName);
  
          localDataHandler = new LocalDataHandler(this);
  
          dbCursor = localDataHandler.get(friend.userName, AppService.USERNAME);
          if (dbCursor.getCount() &gt; 0) {
              int scorer = 0;
              dbCursor.moveToFirst();
              while ((!dbCursor.isAfterLast()) &amp;&amp; scorer &lt; dbCursor.getCount()) {
                  scorer++;
                  this.addToHistory(dbCursor.getString(2), dbCursor.getString(3));
                  //Log.i("test", "Sending text " + dbCursor.getString(2) + " to " + dbCursor.getString(3));
                  dbCursor.moveToNext();
              }
          }
          localDataHandler.close();
  
  
          if (msg != null) {
              this.addToHistory(friend.userName, msg);
              ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).cancel((friend.userName + msg).hashCode());
          }
          //checkMsg(msg);
  
          sendButton.setOnClickListener(new OnClickListener() {
              CharSequence message;
              Handler handler = new Handler();
  
              public void onClick(View arg0) {
                  message = messageText.getText();
                  if (message.length() &gt; 0) {
                      MessageActivity.this.addToHistory(appService.getUsername(), message.toString());
  
                      localDataHandler.insert(appService.getUsername(), friend.userName, message.toString());
  
                      messageText.setText("");
                      Thread thread = new Thread() {
                          public void run() {
                              try {
                                  if (appService.sendMessage(appService.getUsername(), friend.userName, message.toString()) == null) {
  
                                      handler.post(new Runnable() {
  
                                          public void run() {
  
                                              Toast.makeText(getApplicationContext(), R.string.message_cannot_be_sent, Toast.LENGTH_LONG).show();
  
  
                                              //showDialog(MESSAGE_CANNOT_BE_SENT);
                                          }
  
                                      });
                                  }
                              } catch (UnsupportedEncodingException e) {
                                  Toast.makeText(getApplicationContext(), R.string.message_cannot_be_sent, Toast.LENGTH_LONG).show();
  
                                  e.printStackTrace();
                              }
                          }
                      };
                      thread.start();
  
                  }
  
              }
          });
      }
  
      private void addToHistory(String name, String message) {
          if (name != null &amp;&amp; message != null) {
              if (name == friend.userName) {
                  messages.add(new Message(message, false));
                  adapter.notifyDataSetChanged();
                  historyList.setSelection(messages.size() - 1);
              } else {
                  messages.add(new Message(message, true));
                  historyList.addFooterView(messageText);
                  adapter.notifyDataSetChanged();
                  historyList.setSelection(messages.size() - 1);
              }
          }
      }
  }
  </code></pre>
  
  <p>MessageAdapter</p>
  
  <pre><code>      private Context mContext;
  private ArrayList&lt;Message&gt; mMessages;
  
  public MessageAdapter(Context context, ArrayList&lt;Message&gt; messages) {
      super();
      this.mContext = context;
      this.mMessages = messages;
  }
  
  @Override
  public int getCount() {
      // TODO Auto-generated method stub
      return mMessages.size();
  }
  
  @Override
  public Object getItem(int position) {
      // TODO Auto-generated method stub
      return mMessages.get(position);
  }
  
  @Override
  public long getItemId(int arg0) {
      // TODO Auto-generated method stub
      return 0;
  }
  
  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
      Message message = (Message) this.getItem(position);
  
      ViewHolder holder; 
      if(convertView == null)
      {
              holder = new ViewHolder();
              convertView = LayoutInflater.from(mContext).inflate(R.layout.activity_message_adapter, parent, false);
              holder.message = (TextView) convertView.findViewById(R.id.message_text);
              convertView.setTag(holder);
      }
      else
              holder = (ViewHolder) convertView.getTag();
  
      holder.message.setText(message.getMessage());
  
      LayoutParams lp = (LayoutParams) holder.message.getLayoutParams();
      //check if it is a status message then remove background, and change text color.
      if(message.isStatusMessage())
      {
              holder.message.setBackgroundDrawable(null);
              lp.gravity = Gravity.LEFT;
              holder.message.setTextColor(R.color.textFieldColor);
      }
      else
      {                
              //Check whether message is mine to show green background and align to right
              if(message.isMine())
              {
                      holder.message.setBackgroundResource(R.drawable.speech_bubble_green);
                      lp.gravity = Gravity.RIGHT;
              }
              //If not mine then it is from sender to show orange background and align to left
              else
              {
                      holder.message.setBackgroundResource(R.drawable.speech_bubble_orange);
                      lp.gravity = Gravity.LEFT;
              }
              holder.message.setLayoutParams(lp);
              holder.message.setTextColor(R.color.textColor);        
      }
      return convertView;
  }
  private static class ViewHolder
  {
      TextView message;
  }
  </code></pre>