title: Android - How to make adapters layout stay in position
body: <p>I created a simple chat app using <code>firebase</code> but got a little trouble in laying <strong>bubble elements</strong> for the <code>left</code> and <code>right</code> positions. Left bubble for the other person, right bubble for me.</p>
  
  <p>This is my <strong>Adapter</strong> :</p>
  
  <pre><code>public class MessageAdapterCustom extends RecyclerView.Adapter&lt;MessageAdapterCustom.MessageViewHolder&gt; {
  
          private List&lt;Messages&gt; mMessageList;
          private Context context;
          private String mBubblePosition;
  
          public MessageAdapterCustom(Context context, List&lt;Messages&gt; mMessageList, String mBubblePosition) {
              this.context = context;
              this.mMessageList = mMessageList;
              this.mBubblePosition = mBubblePosition;
          }
  
          @Override
          public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  
              View v = LayoutInflater.from( parent.getContext() )
                      .inflate( R.layout.message_single_layout_custom, parent, false );
  
              return new MessageViewHolder( v );
          }
  
          public class MessageViewHolder extends RecyclerView.ViewHolder {
  
              public TextView messageText;
              public CircleImageView profileImage;
  
              public MessageViewHolder(View view) {
                  super( view );
  
                  if(mBubblePosition.equals( "kiri" )) {
  
                      RelativeLayout right = (RelativeLayout) view.findViewById( R.id.sendingMessageLayout );
                      right.setVisibility( View.GONE );
  
                      messageText = (TextView) view.findViewById( R.id.message_text_layout_kiri );
                      profileImage = (CircleImageView) view.findViewById( R.id.message_profile_layout_kiri );
  
                  } else {
  
                      LinearLayout left = (LinearLayout) view.findViewById(R.id.recievemessageLayout);
                      left.setVisibility(View.GONE);
  
                      messageText = (TextView) view.findViewById( R.id.message_text_layout_kanan );
                      profileImage = (CircleImageView) view.findViewById( R.id.message_profile_layout_kanan );
  
                  }
  
              }
          }
  
          @Override
          public void onBindViewHolder(final MessageViewHolder holder, int position) {
  
              final Messages msg = mMessageList.get( position );
              holder.messageText.setText( msg.getMessage() );
  
              Picasso.with( context )
                      .load( msg.getProfile_pic() )
                      .networkPolicy( NetworkPolicy.OFFLINE )
                      .into( holder.profileImage );
  
              /*Picasso.with( context )
                      .load( msg.getProfile_pic() )
                      .networkPolicy( NetworkPolicy.OFFLINE )
                      .placeholder( R.drawable.no_profile )
                      .into( holder.profileImage, new Callback() {
                          @Override
                          public void onSuccess() {
  
                          }
  
                          @Override
                          public void onError() {
                              Picasso.with( context )
                                      .load( msg.getProfile_pic() )
                                      .networkPolicy( NetworkPolicy.OFFLINE )
                                      .into( holder.profileImage );
                          }
                      } );*/
  
  
          }
  
          @Override
          public int getItemCount() {
              return mMessageList.size();
          }
      }
  </code></pre>
  
  <p>My <strong>ChatActivity :</strong> </p>
  
  <pre><code>public class ChatsActivity extends BaseActivity {
  
          private Toolbar mToolbar;
  
          private String mChatUser, mChatUserProfileImage;
  
          private DatabaseReference mRootRef, mMessageDatabase;
          private FirebaseAuth mAuth;
  
          private TextView mTitleView, mLastSeenView;
          private CircleImageView mProfileImage, mChatProfilePic;
  
          private String online, image, mCurrentUserID;
  
          private ImageButton mChatAddBtn, mChatSendBtn;
          private EditText mChatMessageText;
  
          private RecyclerView mMessagesList;
  
          private final List&lt;Messages&gt; messagesList = new ArrayList&lt;&gt;();
  
          private LinearLayoutManager mLinearLayout;
  
          private MessageAdapter mAdapter;
  
          private MessageAdapterCustom mAdapterCustom;
  
          String URL_PROFILE;
  
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate( savedInstanceState );
              setContentView( R.layout.activity_chats );
  
              mRootRef = FirebaseDatabase.getInstance().getReference();
          /*mRootRef.keepSynced( true );*/
  
              mAuth = FirebaseAuth.getInstance();
              mCurrentUserID = mAuth.getCurrentUser().getUid();
  
              mChatUser = getIntent().getStringExtra( "user_id" );
              mChatUserProfileImage = getIntent().getStringExtra( "thumb_image" );
  
          /*getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE );*/
  
              mToolbar = (Toolbar) findViewById( R.id.toolbar );
              setSupportActionBar( mToolbar );
  
              mChatAddBtn = (ImageButton) findViewById( R.id.chat_add_btn );
              mChatSendBtn = (ImageButton) findViewById( R.id.chat_send_btn );
              mChatMessageText = (EditText) findViewById( R.id.chat_message );
  
              mChatMessageText.requestFocus();
  
              mMessagesList = (RecyclerView) findViewById( R.id.chat_messages_list );
  
              mLinearLayout = new LinearLayoutManager( this );
  
              mMessagesList.setHasFixedSize( true );
              mMessagesList.setLayoutManager( mLinearLayout );
  
              ActionBar actionBar = getSupportActionBar();
              actionBar.setDisplayHomeAsUpEnabled( true );
              actionBar.setDisplayShowCustomEnabled( true );
  
              final String userName = getIntent().getStringExtra( "user_name" );
              final String thumbProfilePic = getIntent().getStringExtra( "thumb_image" );
  
              chatUserPic( mChatUser );
  
              LayoutInflater layoutInflater = (LayoutInflater) this.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
              View action_bar_view = layoutInflater.inflate( R.layout.chat_custom_bar, null );
  
              actionBar.setCustomView( action_bar_view );
  
              mTitleView = (TextView) findViewById( R.id.custom_bar_title );
              mLastSeenView = (TextView) findViewById( R.id.custom_bar_seen );
              mProfileImage = (CircleImageView) findViewById( R.id.custom_bar_image );
              mChatProfilePic = (CircleImageView) findViewById( R.id.message_profile_layout );
  
              mTitleView.setText( userName );
  
              mRootRef.child( "Users" ).child( mCurrentUserID ).child( "online" ).setValue( "Online" );
  
              loadMessages();
  
              mRootRef.child( "Users" ).child( mChatUser ).addValueEventListener( new ValueEventListener() {
                  @Override
                  public void onDataChange(DataSnapshot dataSnapshot) {
                      mTitleView.setText( userName );
  
                      online = dataSnapshot.child( "online" ).getValue().toString();
                      image = dataSnapshot.child( "image" ).getValue().toString();
  
                      if (online.equals( "Online" )) {
                          mLastSeenView.setText( online );
                      } else {
  
                          GetTimeAgo getTimeAgo = new GetTimeAgo();
                          long lastTime = Long.parseLong( online );
                          String lastSeenTime = getTimeAgo.timeAgo( lastTime, getApplicationContext() );
                          mLastSeenView.setText( lastSeenTime );
                      }
                  }
  
                  @Override
                  public void onCancelled(DatabaseError databaseError) {
  
                  }
              } );
  
              mChatMessageText.setOnClickListener( new View.OnClickListener() {
                  @Override
                  public void onClick(View view) {
                      if(mAdapterCustom != null) {
                          mMessagesList.scrollToPosition( mAdapterCustom.getItemCount() - 1 );
                      }
                  }
              } );
  
              mChatMessageText.setOnFocusChangeListener( new View.OnFocusChangeListener() {
                  @Override
                  public void onFocusChange(View view, boolean hasFocus) {
                      if (hasFocus) {
                          if(mAdapterCustom != null) {
                              mMessagesList.scrollToPosition( mAdapterCustom.getItemCount() - 1 );
                          }
                      } else {
                          if(mAdapterCustom != null) {
                              mMessagesList.scrollToPosition( mAdapterCustom.getItemCount() - 1 );
                          }
                      }
                  }
              } );
  
  
              mRootRef.child( "Chat" ).child( mCurrentUserID ).addValueEventListener( new ValueEventListener() {
                  @Override
                  public void onDataChange(DataSnapshot dataSnapshot) {
                      if (!dataSnapshot.hasChild( mChatUser )) {
  
                          Map chatAddMap = new HashMap();
                          chatAddMap.put( "seen", false );
                          chatAddMap.put( "timestamp", ServerValue.TIMESTAMP );
  
                          Map chatUserMap = new HashMap();
                          chatUserMap.put( "Chat" + "/" + mCurrentUserID + "/" + mChatUser, chatAddMap );
                          chatUserMap.put( "Chat" + "/" + mChatUser + "/" + mCurrentUserID, chatAddMap );
  
                          mRootRef.updateChildren( chatUserMap, new DatabaseReference.CompletionListener() {
                              @Override
                              public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
                                  if (databaseError != null) {
                                      Log.e( "CHAT_LOG", databaseError.getMessage().toString() );
                                  } else {
                                      mMessagesList.scrollToPosition( mAdapterCustom.getItemCount() - 1 );
                                  }
                              }
                          } );
  
                      }
                  }
  
                  @Override
                  public void onCancelled(DatabaseError databaseError) {
  
                  }
              } );
  
              mChatSendBtn.setOnClickListener( new View.OnClickListener() {
                  @Override
                  public void onClick(View view) {
                      final String message = mChatMessageText.getText().toString();
                      if (TextUtils.isEmpty( message )) {
                          onError( "Message cannot be empty!" );
                      } else {
                          DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
                          Query query = reference.child( "Users" ).child( mCurrentUserID );
                          query.addListenerForSingleValueEvent( new ValueEventListener() {
                              @Override
                              public void onDataChange(DataSnapshot dataSnapshot) {
  
                                  if (dataSnapshot.exists()) {
                                      final String URL_PROFILE = dataSnapshot.child( "thumb_image" ).getValue().toString();
                                      sendMessage( message, URL_PROFILE );
                                  }
                              }
  
                              @Override
                              public void onCancelled(DatabaseError databaseError) {
  
                              }
                          } );
  
                      }
                  }
              } );
  
          }
  
          private void chatUserPic(String id) {
              DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
              Query query = reference.child( "Users" ).child( id );
              query.addListenerForSingleValueEvent( new ValueEventListener() {
                  @Override
                  public void onDataChange(DataSnapshot dataSnapshot) {
  
                      if (dataSnapshot.exists()) {
                          final String URL_PROFILE = dataSnapshot.child( "thumb_image" ).getValue().toString();
                          Picasso.with( getApplication() )
                                  .load( URL_PROFILE )
                                  .networkPolicy( NetworkPolicy.OFFLINE )
                                  .placeholder( R.drawable.no_profile )
                                  .into( mProfileImage, new Callback() {
                                      @Override
                                      public void onSuccess() {
  
                                      }
  
                                      @Override
                                      public void onError() {
                                          Picasso.with( getApplication() )
                                                  .load( URL_PROFILE )
                                                  .placeholder( R.drawable.no_profile )
                                                  .into( mProfileImage );
                                      }
                                  } );
                      } else {
                          String URL_PROFILE = "no_profile";
                          Log.i( "PAUL", URL_PROFILE );
                      }
                  }
  
                  @Override
                  public void onCancelled(DatabaseError databaseError) {
  
                  }
              } );
          }
  
  
          private void loadMessages() {
  
              mRootRef.child( "Messages" ).child( mCurrentUserID ).child( mChatUser ).addChildEventListener( new ChildEventListener() {
                  @Override
                  public void onChildAdded(DataSnapshot dataSnapshot, String s) {
  
                      Messages message = dataSnapshot.getValue( Messages.class );
  
                      String currentUserID = message.current_user_id.toString();
  
                  /*mAdapter = new MessageAdapter( getApplicationContext(), messagesList );*/
  
                      if (currentUserID.equals( mCurrentUserID )) {
                          mAdapterCustom = new MessageAdapterCustom( getApplicationContext(), messagesList, "kanan" );
                          mMessagesList.setAdapter( mAdapterCustom );
                          messagesList.add( message );
                          mAdapterCustom.notifyDataSetChanged();
                          Log.i( "CHAT_ACTIVITY", "RIGHT" );
                      } else {
                          mAdapterCustom = new MessageAdapterCustom( getApplicationContext(), messagesList, "kiri" );
                          mMessagesList.setAdapter( mAdapterCustom );
                          messagesList.add( message );
                          mAdapterCustom.notifyDataSetChanged();
                          Log.i( "CHAT_ACTIVITY", "LEFT" );
                      }
  
                  /*mMessagesList.scrollToPosition( mAdapterCustom.getItemCount() - 1 );*/
                  }
  
                  @Override
                  public void onChildChanged(DataSnapshot dataSnapshot, String s) {
  
                  }
  
                  @Override
                  public void onChildRemoved(DataSnapshot dataSnapshot) {
  
                  }
  
                  @Override
                  public void onChildMoved(DataSnapshot dataSnapshot, String s) {
  
                  }
  
                  @Override
                  public void onCancelled(DatabaseError databaseError) {
  
                  }
              } );
          }
  
          private void sendMessage(String message, String profile_pic) {
  
              String current_user_ref = "Messages" + "/" + mCurrentUserID + "/" + mChatUser;
              String chat_user_ref = "Messages" + "/" + mChatUser + "/" + mCurrentUserID;
  
              DatabaseReference user_message_push = mRootRef.child( "Messages" )
                      .child( mCurrentUserID ).child( mChatUser ).push();
  
  
              String push_id = user_message_push.getKey();
  
              Map messageMap = new HashMap();
              messageMap.put( "message", message );
              messageMap.put( "seen", false );
              messageMap.put( "type", "text" );
              messageMap.put( "time", ServerValue.TIMESTAMP );
              messageMap.put( "profile_pic", profile_pic );
              messageMap.put( "current_user_id", mCurrentUserID );
  
  
              Map messageUserMap = new HashMap();
              messageUserMap.put( current_user_ref + "/" + push_id, messageMap );
              messageUserMap.put( chat_user_ref + "/" + push_id, messageMap );
  
              mRootRef.updateChildren( messageUserMap, new DatabaseReference.CompletionListener() {
                  @Override
                  public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
                      if (databaseError != null) {
                          mChatMessageText.setText( "" );
                          Log.e( "SEND_MESSAGE_CHAT", databaseError.getMessage().toString() );
                      } else {
                          mChatMessageText.setText( "" );
                          mMessagesList.scrollToPosition( mAdapterCustom.getItemCount() - 1 );
                      }
                  }
              } );
  
          }
  
          @Override
          protected void onStart() {
              super.onStart();
              mRootRef.child( "Users" ).child( mCurrentUserID ).child( "online" ).setValue( "Online" );
              mMessagesList.getLayoutManager().scrollToPosition( mLinearLayout.findLastVisibleItemPosition() + 1000 );
          }
  
  }  
  </code></pre>
  
  <p>You see the line :</p>
  
  <pre><code>if (currentUserID.equals( mCurrentUserID )) {
     mAdapterCustom = new MessageAdapterCustom( getApplicationContext(), messagesList, "kanan" );
     mMessagesList.setAdapter( mAdapterCustom );
     messagesList.add( message );
     mAdapterCustom.notifyDataSetChanged();
     Log.i( "CHAT_ACTIVITY", "RIGHT" );
  } else {
     mAdapterCustom = new MessageAdapterCustom( getApplicationContext(), messagesList, "kiri" );
     mMessagesList.setAdapter( mAdapterCustom );
     messagesList.add( message );
     mAdapterCustom.notifyDataSetChanged();
     Log.i( "CHAT_ACTIVITY", "LEFT" );
  }
  </code></pre>
  
  <p>When I try to use two devices, first if I myself try to send a message, Log shows <code>RIGHT</code> which means the position of the balloon on the <strong>right</strong>.
  <a href="https://i.stack.imgur.com/8iYTq.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/8iYTq.png" alt="enter image description here"></a></p>
  
  <p>But when I reply with different devices (the other person) then the adapter will move the <strong>two bubbles to the left</strong>. It seems because it follows the last adapter command.
  <a href="https://i.stack.imgur.com/WB1GK.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/WB1GK.png" alt="enter image description here"></a></p>
  
  <p>My Log
  <a href="https://i.stack.imgur.com/FDZoZ.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/FDZoZ.png" alt="enter image description here"></a></p>
  
  <p>How do I <strong>keep my adapter in position</strong> every time a <code>message arrives</code>, instead of changing all the structure of my view elements as shown.</p>
  
  <p>-- Update --
  My <strong>Layout :</strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:id="@+id/stackoverflow"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:padding="5dp"&gt;
  
      &lt;LinearLayout
          android:id="@+id/recievemessageLayout"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"&gt;
  
          &lt;de.hdodenhof.circleimageview.CircleImageView
              android:id="@+id/message_profile_layout_kiri"
              android:layout_width="55dp"
              android:layout_height="55dp"
              android:src="@drawable/no_profile" /&gt;
  
          &lt;LinearLayout
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:orientation="vertical"&gt;
  
              &lt;TextView
                  android:id="@+id/message_text_layout_kiri"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_marginStart="10dp"
                  android:layout_marginTop="5dp"
                  android:background="@drawable/message_text_background"
                  android:paddingBottom="5dp"
                  android:paddingLeft="10dp"
                  android:paddingRight="10dp"
                  android:paddingTop="5dp"
                  android:text="@string/message_here"
                  android:textColor="@android:color/white" /&gt;
  
              &lt;ImageView
                  android:id="@+id/message_buble_kiri"
                  android:layout_width="20dp"
                  android:layout_height="20dp"
                  android:layout_marginStart="10dp"
                  android:layout_marginTop="-10dp"
                  android:src="@drawable/buble_left" /&gt;
  
          &lt;/LinearLayout&gt;
  
      &lt;/LinearLayout&gt;
  
      &lt;RelativeLayout
          android:id="@+id/sendingMessageLayout"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_below="@+id/recievemessageLayout"
          android:layout_marginTop="5dp"
          android:orientation="horizontal"&gt;
  
          &lt;de.hdodenhof.circleimageview.CircleImageView
              android:id="@+id/message_profile_layout_kanan"
              android:layout_width="55dp"
              android:layout_height="55dp"
              android:layout_alignParentEnd="true"
              android:src="@drawable/no_profile" /&gt;
  
          &lt;TextView
              android:id="@+id/message_text_layout_kanan"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_alignParentTop="true"
              android:layout_marginEnd="10dp"
              android:layout_marginTop="5dp"
              android:layout_toStartOf="@+id/message_profile_layout_kanan"
              android:background="@drawable/message_text_background"
              android:paddingBottom="5dp"
              android:paddingLeft="10dp"
              android:paddingRight="10dp"
              android:paddingTop="5dp"
              android:text="@string/message_here"
              android:textColor="@android:color/white" /&gt;
  
          &lt;ImageView
              android:id="@+id/message_buble_kanan"
              android:layout_width="20dp"
              android:layout_height="20dp"
              android:layout_alignEnd="@+id/message_text_layout_kanan"
              android:layout_below="@+id/message_text_layout_kanan"
              android:layout_marginTop="-10dp"
              android:src="@drawable/buble_right" /&gt;
  
  
      &lt;/RelativeLayout&gt;
  
  &lt;/RelativeLayout&gt;
  </code></pre>