RecyclerView messes up when scrolling












0















I never asked any question before but hope you'll get my point.
I am making a chat app in which I am using a RecyclerView to show messages. The problem is when I scroll the RecyclerView some of the items disappear from the top and the whole items messes up when I try to add a message it doesn't even scroll to bottom nor added in the ListView.



Here is my RecyclerView:



<android.support.v7.widget.RecyclerView
android:id="@+id/conversation_recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:layout_above="@id/typingConversationLayout"
android:layout_below="@id/topLayout_conversation_activity"
android:layout_marginBottom="-5dp"
android:paddingBottom="7dp" />


Initializing and setting the RecycerView:



linearLayoutManager = new LinearLayoutManager(this);
adapter = new ConversationRecyclerViewAdapter();
conversationRecyclerView.setAdapter(adapter);
conversationRecyclerView.setLayoutManager(linearLayoutManager);
linearLayoutManager.setStackFromEnd(true);
conversationRecyclerView.setHasFixedSize(true);
conversationRecyclerView.setNestedScrollingEnabled(false);


Here is my Adapter class:



private class ConversationRecyclerViewAdapter
extends RecyclerView.Adapter<ConversationRecyclerViewAdapter.ConversationViewHolder> {

@NonNull
@Override
public ConversationViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {

Log.d(TAG, "onCreateViewHolder: Users Find started");

View conversationsView = LayoutInflater.from(parent.getContext()).inflate(
R.layout.layout_message_received, parent, false);

return new ConversationViewHolder(conversationsView);
}

@Override
public void onBindViewHolder(@NonNull final ConversationViewHolder holderConversation, int i) {
Log.d(TAG, "onBindViewHolder: Users Find started at position is " + i);

final int position = holderConversation.getAdapterPosition();

if (mOwnUser_1.get(position)) {
holderConversation.receivedMsgLayout.setVisibility(View.GONE);

holderConversation.sentProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.sentMsg.setText(mUserText_3.get(position));

} else {

holderConversation.sentMsgLayout.setVisibility(View.GONE);

holderConversation.receivedProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.receivedMsg.setText(mUserText_3.get(position));

}

Log.d(TAG, "onBindViewHolder: completed at " + position);

}

@Override
public int getItemCount() {
return mOwnUser_1.size();
}

public class ConversationViewHolder extends RecyclerView.ViewHolder {

RelativeLayout receivedMsgLayout, sentMsgLayout;
EmojiTextView receivedMsg, sentMsg;
CircleImageView receivedProfileImg, sentProfileImg;

public ConversationViewHolder(@NonNull View v) {
super(v);

receivedMsgLayout = v.findViewById(R.id.received_message_layout);
sentMsgLayout = v.findViewById(R.id.sent_message_layout);
receivedMsg = v.findViewById(R.id.received_message_text);
sentMsg = v.findViewById(R.id.sent_message_text);
receivedProfileImg = v.findViewById(R.id.received_message_user__profile_image);
sentProfileImg = v.findViewById(R.id.sent_message_user__profile_image);

}
}
}


Here I am adding data to ListView and displaying to the RecyclerView:



sendBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {

String msg = editText.getText().toString().trim();

if (TextUtils.isEmpty(msg)) {

editText.setError("Please add a message");
editText.requestFocus();

} else {
Log.d(TAG, "onClick: send Btn ADDED TEXT.. ");

mOwnUser_1.add(user);
mUserProfileImg_2.add(image);
mUserText_3.add(message);

editText.setText("");
editText.requestFocus();

adapter.notifyItemInserted(mOwnUser_1.size());
conversationRecyclerView.scrollToPosition(mOwnUser_1.size() - 1);


}

}
});


I don't know what i am doing wrong but it does not seem to work as i wanted.



Update Code:



The three listviews:



private ArrayList<Boolean> mOwnUser_1 = new ArrayList<>();
private ArrayList<Integer> mUserProfileImg_2 = new ArrayList<>();
private ArrayList<String> mUserText_3 = new ArrayList<>();


And the way of adding data to adapter:



mOwnUser_1.add(true);
mUserProfileImg_2.add(R.drawable.boy);
mUserText_3.add(edittext.getText().toString().trim());
adapter.notifyItemInserted(mOwnUser_1.size());
conversationRecyclerView.scrollToPosition(mOwnUser_1.size() - 1);


My Whole Conversation Activity Class:



public class ConversationActivity extends AppCompatActivity {
private static final String TAG = "ConversationActivity";

private EditText editText;
private LinearLayout linearLayout;
private LinearLayoutManager linearLayoutManager;

private ImageView sendBtn;
private ImageView emojiImage;
private View rootView;
private Boolean popUpShown = false;
private Boolean micShown = false;
private ImageView micBtn;
private RelativeLayout micLayout;
private RecyclerView conversationRecyclerView;

// Array Lists for Find USERS
private ArrayList<Boolean> mOwnUser_1 = new ArrayList<>();
private ArrayList<Integer> mUserProfileImg_2 = new ArrayList<>();
private ArrayList<String> mUserText_3 = new ArrayList<>();

private ConversationRecyclerViewAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate: started");
super.onCreate(savedInstanceState);
EmojiManager.install(new TwitterEmojiProvider());
setContentView(R.layout.activity_conversation);

editText = findViewById(R.id.conversationEditText);
linearLayout = findViewById(R.id.optionsOther);
emojiImage = findViewById(R.id.emojiIconOther);
rootView = findViewById(R.id.root_view_conversation);
micBtn = findViewById(R.id.microphoneBtn);
micLayout = findViewById(R.id.microphoneLayout);
conversationRecyclerView = findViewById(R.id.conversation_recyclerView);
sendBtn = findViewById(R.id.sendBtnConversation);

if (!(Build.VERSION.SDK_INT >= 21))
findViewById(R.id.typingConversationLayout).setBackgroundResource(R.drawable.edit_text_conversation_background_below_api);

sendBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {

String msg = editText.getText().toString().trim();

if (TextUtils.isEmpty(msg)) {

editText.setError("Please add a message");
editText.requestFocus();

} else {
Log.d(TAG, "onClick: send Btn ADDED TEXT.. ");

addData(true, R.drawable.boy0, msg);
}

}
});

initConversationArrayList();

}

private void addData(Boolean user, int image, String message) {

mOwnUser_1.add(user);
mUserProfileImg_2.add(image);
mUserText_3.add(message);

editText.setText("");
editText.requestFocus();

adapter.notifyItemInserted(mOwnUser_1.size());
conversationRecyclerView.scrollToPosition(mOwnUser_1.size() - 1);

}


private void initConversationArrayList() {
Log.d(TAG, "initConversationArrayList: created");

mOwnUser_1.add(true);
mUserProfileImg_2.add(R.drawable.boy0);
mUserText_3.add("Hello How are you?");


Log.d(TAG, "initConversationArrayList: completed");

initConversationRecyclerView();

}

private void initConversationRecyclerView() {
Log.d(TAG, "initConversationRecyclerView: started");

linearLayoutManager = new LinearLayoutManager(this);
adapter = new ConversationRecyclerViewAdapter();
conversationRecyclerView.setAdapter(adapter);
conversationRecyclerView.setLayoutManager(linearLayoutManager);
linearLayoutManager.setStackFromEnd(true);
conversationRecyclerView.setHasFixedSize(true);
conversationRecyclerView.setNestedScrollingEnabled(false);

Log.d(TAG, "initConversationRecyclerView: completed");
}









share|improve this question

























  • where are u adding the editText.getText().toString() to the adapter data?

    – Hudi Ilfeld
    Nov 18 '18 at 11:17











  • @HudiIlfeld In three listviews where one is the type of user (Sender or receiver), second is the image of user and the third is the message which is retrieved from EditText

    – Moutamid Waseem
    Nov 18 '18 at 11:21













  • could you point to the specific line in your code where you are supposedly adding the fresh data to your adapter?

    – Hudi Ilfeld
    Nov 18 '18 at 11:23











  • @HudiIlfeld I have updated the code Have a look.

    – Moutamid Waseem
    Nov 18 '18 at 11:32











  • You are missing an important part in your recyclerView. you are not adding anything to your recyclerView adapter. If you have a link (on GitHub etc) to your project I would be more then happy to add the missing parts and solve your problem

    – Hudi Ilfeld
    Nov 18 '18 at 11:47
















0















I never asked any question before but hope you'll get my point.
I am making a chat app in which I am using a RecyclerView to show messages. The problem is when I scroll the RecyclerView some of the items disappear from the top and the whole items messes up when I try to add a message it doesn't even scroll to bottom nor added in the ListView.



Here is my RecyclerView:



<android.support.v7.widget.RecyclerView
android:id="@+id/conversation_recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:layout_above="@id/typingConversationLayout"
android:layout_below="@id/topLayout_conversation_activity"
android:layout_marginBottom="-5dp"
android:paddingBottom="7dp" />


Initializing and setting the RecycerView:



linearLayoutManager = new LinearLayoutManager(this);
adapter = new ConversationRecyclerViewAdapter();
conversationRecyclerView.setAdapter(adapter);
conversationRecyclerView.setLayoutManager(linearLayoutManager);
linearLayoutManager.setStackFromEnd(true);
conversationRecyclerView.setHasFixedSize(true);
conversationRecyclerView.setNestedScrollingEnabled(false);


Here is my Adapter class:



private class ConversationRecyclerViewAdapter
extends RecyclerView.Adapter<ConversationRecyclerViewAdapter.ConversationViewHolder> {

@NonNull
@Override
public ConversationViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {

Log.d(TAG, "onCreateViewHolder: Users Find started");

View conversationsView = LayoutInflater.from(parent.getContext()).inflate(
R.layout.layout_message_received, parent, false);

return new ConversationViewHolder(conversationsView);
}

@Override
public void onBindViewHolder(@NonNull final ConversationViewHolder holderConversation, int i) {
Log.d(TAG, "onBindViewHolder: Users Find started at position is " + i);

final int position = holderConversation.getAdapterPosition();

if (mOwnUser_1.get(position)) {
holderConversation.receivedMsgLayout.setVisibility(View.GONE);

holderConversation.sentProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.sentMsg.setText(mUserText_3.get(position));

} else {

holderConversation.sentMsgLayout.setVisibility(View.GONE);

holderConversation.receivedProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.receivedMsg.setText(mUserText_3.get(position));

}

Log.d(TAG, "onBindViewHolder: completed at " + position);

}

@Override
public int getItemCount() {
return mOwnUser_1.size();
}

public class ConversationViewHolder extends RecyclerView.ViewHolder {

RelativeLayout receivedMsgLayout, sentMsgLayout;
EmojiTextView receivedMsg, sentMsg;
CircleImageView receivedProfileImg, sentProfileImg;

public ConversationViewHolder(@NonNull View v) {
super(v);

receivedMsgLayout = v.findViewById(R.id.received_message_layout);
sentMsgLayout = v.findViewById(R.id.sent_message_layout);
receivedMsg = v.findViewById(R.id.received_message_text);
sentMsg = v.findViewById(R.id.sent_message_text);
receivedProfileImg = v.findViewById(R.id.received_message_user__profile_image);
sentProfileImg = v.findViewById(R.id.sent_message_user__profile_image);

}
}
}


Here I am adding data to ListView and displaying to the RecyclerView:



sendBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {

String msg = editText.getText().toString().trim();

if (TextUtils.isEmpty(msg)) {

editText.setError("Please add a message");
editText.requestFocus();

} else {
Log.d(TAG, "onClick: send Btn ADDED TEXT.. ");

mOwnUser_1.add(user);
mUserProfileImg_2.add(image);
mUserText_3.add(message);

editText.setText("");
editText.requestFocus();

adapter.notifyItemInserted(mOwnUser_1.size());
conversationRecyclerView.scrollToPosition(mOwnUser_1.size() - 1);


}

}
});


I don't know what i am doing wrong but it does not seem to work as i wanted.



Update Code:



The three listviews:



private ArrayList<Boolean> mOwnUser_1 = new ArrayList<>();
private ArrayList<Integer> mUserProfileImg_2 = new ArrayList<>();
private ArrayList<String> mUserText_3 = new ArrayList<>();


And the way of adding data to adapter:



mOwnUser_1.add(true);
mUserProfileImg_2.add(R.drawable.boy);
mUserText_3.add(edittext.getText().toString().trim());
adapter.notifyItemInserted(mOwnUser_1.size());
conversationRecyclerView.scrollToPosition(mOwnUser_1.size() - 1);


My Whole Conversation Activity Class:



public class ConversationActivity extends AppCompatActivity {
private static final String TAG = "ConversationActivity";

private EditText editText;
private LinearLayout linearLayout;
private LinearLayoutManager linearLayoutManager;

private ImageView sendBtn;
private ImageView emojiImage;
private View rootView;
private Boolean popUpShown = false;
private Boolean micShown = false;
private ImageView micBtn;
private RelativeLayout micLayout;
private RecyclerView conversationRecyclerView;

// Array Lists for Find USERS
private ArrayList<Boolean> mOwnUser_1 = new ArrayList<>();
private ArrayList<Integer> mUserProfileImg_2 = new ArrayList<>();
private ArrayList<String> mUserText_3 = new ArrayList<>();

private ConversationRecyclerViewAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate: started");
super.onCreate(savedInstanceState);
EmojiManager.install(new TwitterEmojiProvider());
setContentView(R.layout.activity_conversation);

editText = findViewById(R.id.conversationEditText);
linearLayout = findViewById(R.id.optionsOther);
emojiImage = findViewById(R.id.emojiIconOther);
rootView = findViewById(R.id.root_view_conversation);
micBtn = findViewById(R.id.microphoneBtn);
micLayout = findViewById(R.id.microphoneLayout);
conversationRecyclerView = findViewById(R.id.conversation_recyclerView);
sendBtn = findViewById(R.id.sendBtnConversation);

if (!(Build.VERSION.SDK_INT >= 21))
findViewById(R.id.typingConversationLayout).setBackgroundResource(R.drawable.edit_text_conversation_background_below_api);

sendBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {

String msg = editText.getText().toString().trim();

if (TextUtils.isEmpty(msg)) {

editText.setError("Please add a message");
editText.requestFocus();

} else {
Log.d(TAG, "onClick: send Btn ADDED TEXT.. ");

addData(true, R.drawable.boy0, msg);
}

}
});

initConversationArrayList();

}

private void addData(Boolean user, int image, String message) {

mOwnUser_1.add(user);
mUserProfileImg_2.add(image);
mUserText_3.add(message);

editText.setText("");
editText.requestFocus();

adapter.notifyItemInserted(mOwnUser_1.size());
conversationRecyclerView.scrollToPosition(mOwnUser_1.size() - 1);

}


private void initConversationArrayList() {
Log.d(TAG, "initConversationArrayList: created");

mOwnUser_1.add(true);
mUserProfileImg_2.add(R.drawable.boy0);
mUserText_3.add("Hello How are you?");


Log.d(TAG, "initConversationArrayList: completed");

initConversationRecyclerView();

}

private void initConversationRecyclerView() {
Log.d(TAG, "initConversationRecyclerView: started");

linearLayoutManager = new LinearLayoutManager(this);
adapter = new ConversationRecyclerViewAdapter();
conversationRecyclerView.setAdapter(adapter);
conversationRecyclerView.setLayoutManager(linearLayoutManager);
linearLayoutManager.setStackFromEnd(true);
conversationRecyclerView.setHasFixedSize(true);
conversationRecyclerView.setNestedScrollingEnabled(false);

Log.d(TAG, "initConversationRecyclerView: completed");
}









share|improve this question

























  • where are u adding the editText.getText().toString() to the adapter data?

    – Hudi Ilfeld
    Nov 18 '18 at 11:17











  • @HudiIlfeld In three listviews where one is the type of user (Sender or receiver), second is the image of user and the third is the message which is retrieved from EditText

    – Moutamid Waseem
    Nov 18 '18 at 11:21













  • could you point to the specific line in your code where you are supposedly adding the fresh data to your adapter?

    – Hudi Ilfeld
    Nov 18 '18 at 11:23











  • @HudiIlfeld I have updated the code Have a look.

    – Moutamid Waseem
    Nov 18 '18 at 11:32











  • You are missing an important part in your recyclerView. you are not adding anything to your recyclerView adapter. If you have a link (on GitHub etc) to your project I would be more then happy to add the missing parts and solve your problem

    – Hudi Ilfeld
    Nov 18 '18 at 11:47














0












0








0








I never asked any question before but hope you'll get my point.
I am making a chat app in which I am using a RecyclerView to show messages. The problem is when I scroll the RecyclerView some of the items disappear from the top and the whole items messes up when I try to add a message it doesn't even scroll to bottom nor added in the ListView.



Here is my RecyclerView:



<android.support.v7.widget.RecyclerView
android:id="@+id/conversation_recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:layout_above="@id/typingConversationLayout"
android:layout_below="@id/topLayout_conversation_activity"
android:layout_marginBottom="-5dp"
android:paddingBottom="7dp" />


Initializing and setting the RecycerView:



linearLayoutManager = new LinearLayoutManager(this);
adapter = new ConversationRecyclerViewAdapter();
conversationRecyclerView.setAdapter(adapter);
conversationRecyclerView.setLayoutManager(linearLayoutManager);
linearLayoutManager.setStackFromEnd(true);
conversationRecyclerView.setHasFixedSize(true);
conversationRecyclerView.setNestedScrollingEnabled(false);


Here is my Adapter class:



private class ConversationRecyclerViewAdapter
extends RecyclerView.Adapter<ConversationRecyclerViewAdapter.ConversationViewHolder> {

@NonNull
@Override
public ConversationViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {

Log.d(TAG, "onCreateViewHolder: Users Find started");

View conversationsView = LayoutInflater.from(parent.getContext()).inflate(
R.layout.layout_message_received, parent, false);

return new ConversationViewHolder(conversationsView);
}

@Override
public void onBindViewHolder(@NonNull final ConversationViewHolder holderConversation, int i) {
Log.d(TAG, "onBindViewHolder: Users Find started at position is " + i);

final int position = holderConversation.getAdapterPosition();

if (mOwnUser_1.get(position)) {
holderConversation.receivedMsgLayout.setVisibility(View.GONE);

holderConversation.sentProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.sentMsg.setText(mUserText_3.get(position));

} else {

holderConversation.sentMsgLayout.setVisibility(View.GONE);

holderConversation.receivedProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.receivedMsg.setText(mUserText_3.get(position));

}

Log.d(TAG, "onBindViewHolder: completed at " + position);

}

@Override
public int getItemCount() {
return mOwnUser_1.size();
}

public class ConversationViewHolder extends RecyclerView.ViewHolder {

RelativeLayout receivedMsgLayout, sentMsgLayout;
EmojiTextView receivedMsg, sentMsg;
CircleImageView receivedProfileImg, sentProfileImg;

public ConversationViewHolder(@NonNull View v) {
super(v);

receivedMsgLayout = v.findViewById(R.id.received_message_layout);
sentMsgLayout = v.findViewById(R.id.sent_message_layout);
receivedMsg = v.findViewById(R.id.received_message_text);
sentMsg = v.findViewById(R.id.sent_message_text);
receivedProfileImg = v.findViewById(R.id.received_message_user__profile_image);
sentProfileImg = v.findViewById(R.id.sent_message_user__profile_image);

}
}
}


Here I am adding data to ListView and displaying to the RecyclerView:



sendBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {

String msg = editText.getText().toString().trim();

if (TextUtils.isEmpty(msg)) {

editText.setError("Please add a message");
editText.requestFocus();

} else {
Log.d(TAG, "onClick: send Btn ADDED TEXT.. ");

mOwnUser_1.add(user);
mUserProfileImg_2.add(image);
mUserText_3.add(message);

editText.setText("");
editText.requestFocus();

adapter.notifyItemInserted(mOwnUser_1.size());
conversationRecyclerView.scrollToPosition(mOwnUser_1.size() - 1);


}

}
});


I don't know what i am doing wrong but it does not seem to work as i wanted.



Update Code:



The three listviews:



private ArrayList<Boolean> mOwnUser_1 = new ArrayList<>();
private ArrayList<Integer> mUserProfileImg_2 = new ArrayList<>();
private ArrayList<String> mUserText_3 = new ArrayList<>();


And the way of adding data to adapter:



mOwnUser_1.add(true);
mUserProfileImg_2.add(R.drawable.boy);
mUserText_3.add(edittext.getText().toString().trim());
adapter.notifyItemInserted(mOwnUser_1.size());
conversationRecyclerView.scrollToPosition(mOwnUser_1.size() - 1);


My Whole Conversation Activity Class:



public class ConversationActivity extends AppCompatActivity {
private static final String TAG = "ConversationActivity";

private EditText editText;
private LinearLayout linearLayout;
private LinearLayoutManager linearLayoutManager;

private ImageView sendBtn;
private ImageView emojiImage;
private View rootView;
private Boolean popUpShown = false;
private Boolean micShown = false;
private ImageView micBtn;
private RelativeLayout micLayout;
private RecyclerView conversationRecyclerView;

// Array Lists for Find USERS
private ArrayList<Boolean> mOwnUser_1 = new ArrayList<>();
private ArrayList<Integer> mUserProfileImg_2 = new ArrayList<>();
private ArrayList<String> mUserText_3 = new ArrayList<>();

private ConversationRecyclerViewAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate: started");
super.onCreate(savedInstanceState);
EmojiManager.install(new TwitterEmojiProvider());
setContentView(R.layout.activity_conversation);

editText = findViewById(R.id.conversationEditText);
linearLayout = findViewById(R.id.optionsOther);
emojiImage = findViewById(R.id.emojiIconOther);
rootView = findViewById(R.id.root_view_conversation);
micBtn = findViewById(R.id.microphoneBtn);
micLayout = findViewById(R.id.microphoneLayout);
conversationRecyclerView = findViewById(R.id.conversation_recyclerView);
sendBtn = findViewById(R.id.sendBtnConversation);

if (!(Build.VERSION.SDK_INT >= 21))
findViewById(R.id.typingConversationLayout).setBackgroundResource(R.drawable.edit_text_conversation_background_below_api);

sendBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {

String msg = editText.getText().toString().trim();

if (TextUtils.isEmpty(msg)) {

editText.setError("Please add a message");
editText.requestFocus();

} else {
Log.d(TAG, "onClick: send Btn ADDED TEXT.. ");

addData(true, R.drawable.boy0, msg);
}

}
});

initConversationArrayList();

}

private void addData(Boolean user, int image, String message) {

mOwnUser_1.add(user);
mUserProfileImg_2.add(image);
mUserText_3.add(message);

editText.setText("");
editText.requestFocus();

adapter.notifyItemInserted(mOwnUser_1.size());
conversationRecyclerView.scrollToPosition(mOwnUser_1.size() - 1);

}


private void initConversationArrayList() {
Log.d(TAG, "initConversationArrayList: created");

mOwnUser_1.add(true);
mUserProfileImg_2.add(R.drawable.boy0);
mUserText_3.add("Hello How are you?");


Log.d(TAG, "initConversationArrayList: completed");

initConversationRecyclerView();

}

private void initConversationRecyclerView() {
Log.d(TAG, "initConversationRecyclerView: started");

linearLayoutManager = new LinearLayoutManager(this);
adapter = new ConversationRecyclerViewAdapter();
conversationRecyclerView.setAdapter(adapter);
conversationRecyclerView.setLayoutManager(linearLayoutManager);
linearLayoutManager.setStackFromEnd(true);
conversationRecyclerView.setHasFixedSize(true);
conversationRecyclerView.setNestedScrollingEnabled(false);

Log.d(TAG, "initConversationRecyclerView: completed");
}









share|improve this question
















I never asked any question before but hope you'll get my point.
I am making a chat app in which I am using a RecyclerView to show messages. The problem is when I scroll the RecyclerView some of the items disappear from the top and the whole items messes up when I try to add a message it doesn't even scroll to bottom nor added in the ListView.



Here is my RecyclerView:



<android.support.v7.widget.RecyclerView
android:id="@+id/conversation_recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:layout_above="@id/typingConversationLayout"
android:layout_below="@id/topLayout_conversation_activity"
android:layout_marginBottom="-5dp"
android:paddingBottom="7dp" />


Initializing and setting the RecycerView:



linearLayoutManager = new LinearLayoutManager(this);
adapter = new ConversationRecyclerViewAdapter();
conversationRecyclerView.setAdapter(adapter);
conversationRecyclerView.setLayoutManager(linearLayoutManager);
linearLayoutManager.setStackFromEnd(true);
conversationRecyclerView.setHasFixedSize(true);
conversationRecyclerView.setNestedScrollingEnabled(false);


Here is my Adapter class:



private class ConversationRecyclerViewAdapter
extends RecyclerView.Adapter<ConversationRecyclerViewAdapter.ConversationViewHolder> {

@NonNull
@Override
public ConversationViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {

Log.d(TAG, "onCreateViewHolder: Users Find started");

View conversationsView = LayoutInflater.from(parent.getContext()).inflate(
R.layout.layout_message_received, parent, false);

return new ConversationViewHolder(conversationsView);
}

@Override
public void onBindViewHolder(@NonNull final ConversationViewHolder holderConversation, int i) {
Log.d(TAG, "onBindViewHolder: Users Find started at position is " + i);

final int position = holderConversation.getAdapterPosition();

if (mOwnUser_1.get(position)) {
holderConversation.receivedMsgLayout.setVisibility(View.GONE);

holderConversation.sentProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.sentMsg.setText(mUserText_3.get(position));

} else {

holderConversation.sentMsgLayout.setVisibility(View.GONE);

holderConversation.receivedProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.receivedMsg.setText(mUserText_3.get(position));

}

Log.d(TAG, "onBindViewHolder: completed at " + position);

}

@Override
public int getItemCount() {
return mOwnUser_1.size();
}

public class ConversationViewHolder extends RecyclerView.ViewHolder {

RelativeLayout receivedMsgLayout, sentMsgLayout;
EmojiTextView receivedMsg, sentMsg;
CircleImageView receivedProfileImg, sentProfileImg;

public ConversationViewHolder(@NonNull View v) {
super(v);

receivedMsgLayout = v.findViewById(R.id.received_message_layout);
sentMsgLayout = v.findViewById(R.id.sent_message_layout);
receivedMsg = v.findViewById(R.id.received_message_text);
sentMsg = v.findViewById(R.id.sent_message_text);
receivedProfileImg = v.findViewById(R.id.received_message_user__profile_image);
sentProfileImg = v.findViewById(R.id.sent_message_user__profile_image);

}
}
}


Here I am adding data to ListView and displaying to the RecyclerView:



sendBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {

String msg = editText.getText().toString().trim();

if (TextUtils.isEmpty(msg)) {

editText.setError("Please add a message");
editText.requestFocus();

} else {
Log.d(TAG, "onClick: send Btn ADDED TEXT.. ");

mOwnUser_1.add(user);
mUserProfileImg_2.add(image);
mUserText_3.add(message);

editText.setText("");
editText.requestFocus();

adapter.notifyItemInserted(mOwnUser_1.size());
conversationRecyclerView.scrollToPosition(mOwnUser_1.size() - 1);


}

}
});


I don't know what i am doing wrong but it does not seem to work as i wanted.



Update Code:



The three listviews:



private ArrayList<Boolean> mOwnUser_1 = new ArrayList<>();
private ArrayList<Integer> mUserProfileImg_2 = new ArrayList<>();
private ArrayList<String> mUserText_3 = new ArrayList<>();


And the way of adding data to adapter:



mOwnUser_1.add(true);
mUserProfileImg_2.add(R.drawable.boy);
mUserText_3.add(edittext.getText().toString().trim());
adapter.notifyItemInserted(mOwnUser_1.size());
conversationRecyclerView.scrollToPosition(mOwnUser_1.size() - 1);


My Whole Conversation Activity Class:



public class ConversationActivity extends AppCompatActivity {
private static final String TAG = "ConversationActivity";

private EditText editText;
private LinearLayout linearLayout;
private LinearLayoutManager linearLayoutManager;

private ImageView sendBtn;
private ImageView emojiImage;
private View rootView;
private Boolean popUpShown = false;
private Boolean micShown = false;
private ImageView micBtn;
private RelativeLayout micLayout;
private RecyclerView conversationRecyclerView;

// Array Lists for Find USERS
private ArrayList<Boolean> mOwnUser_1 = new ArrayList<>();
private ArrayList<Integer> mUserProfileImg_2 = new ArrayList<>();
private ArrayList<String> mUserText_3 = new ArrayList<>();

private ConversationRecyclerViewAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate: started");
super.onCreate(savedInstanceState);
EmojiManager.install(new TwitterEmojiProvider());
setContentView(R.layout.activity_conversation);

editText = findViewById(R.id.conversationEditText);
linearLayout = findViewById(R.id.optionsOther);
emojiImage = findViewById(R.id.emojiIconOther);
rootView = findViewById(R.id.root_view_conversation);
micBtn = findViewById(R.id.microphoneBtn);
micLayout = findViewById(R.id.microphoneLayout);
conversationRecyclerView = findViewById(R.id.conversation_recyclerView);
sendBtn = findViewById(R.id.sendBtnConversation);

if (!(Build.VERSION.SDK_INT >= 21))
findViewById(R.id.typingConversationLayout).setBackgroundResource(R.drawable.edit_text_conversation_background_below_api);

sendBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {

String msg = editText.getText().toString().trim();

if (TextUtils.isEmpty(msg)) {

editText.setError("Please add a message");
editText.requestFocus();

} else {
Log.d(TAG, "onClick: send Btn ADDED TEXT.. ");

addData(true, R.drawable.boy0, msg);
}

}
});

initConversationArrayList();

}

private void addData(Boolean user, int image, String message) {

mOwnUser_1.add(user);
mUserProfileImg_2.add(image);
mUserText_3.add(message);

editText.setText("");
editText.requestFocus();

adapter.notifyItemInserted(mOwnUser_1.size());
conversationRecyclerView.scrollToPosition(mOwnUser_1.size() - 1);

}


private void initConversationArrayList() {
Log.d(TAG, "initConversationArrayList: created");

mOwnUser_1.add(true);
mUserProfileImg_2.add(R.drawable.boy0);
mUserText_3.add("Hello How are you?");


Log.d(TAG, "initConversationArrayList: completed");

initConversationRecyclerView();

}

private void initConversationRecyclerView() {
Log.d(TAG, "initConversationRecyclerView: started");

linearLayoutManager = new LinearLayoutManager(this);
adapter = new ConversationRecyclerViewAdapter();
conversationRecyclerView.setAdapter(adapter);
conversationRecyclerView.setLayoutManager(linearLayoutManager);
linearLayoutManager.setStackFromEnd(true);
conversationRecyclerView.setHasFixedSize(true);
conversationRecyclerView.setNestedScrollingEnabled(false);

Log.d(TAG, "initConversationRecyclerView: completed");
}






android android-recyclerview recyclerview-layout






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 22 '18 at 8:20









Aniruddh Parihar

2,18911027




2,18911027










asked Nov 18 '18 at 11:09









Moutamid WaseemMoutamid Waseem

34




34













  • where are u adding the editText.getText().toString() to the adapter data?

    – Hudi Ilfeld
    Nov 18 '18 at 11:17











  • @HudiIlfeld In three listviews where one is the type of user (Sender or receiver), second is the image of user and the third is the message which is retrieved from EditText

    – Moutamid Waseem
    Nov 18 '18 at 11:21













  • could you point to the specific line in your code where you are supposedly adding the fresh data to your adapter?

    – Hudi Ilfeld
    Nov 18 '18 at 11:23











  • @HudiIlfeld I have updated the code Have a look.

    – Moutamid Waseem
    Nov 18 '18 at 11:32











  • You are missing an important part in your recyclerView. you are not adding anything to your recyclerView adapter. If you have a link (on GitHub etc) to your project I would be more then happy to add the missing parts and solve your problem

    – Hudi Ilfeld
    Nov 18 '18 at 11:47



















  • where are u adding the editText.getText().toString() to the adapter data?

    – Hudi Ilfeld
    Nov 18 '18 at 11:17











  • @HudiIlfeld In three listviews where one is the type of user (Sender or receiver), second is the image of user and the third is the message which is retrieved from EditText

    – Moutamid Waseem
    Nov 18 '18 at 11:21













  • could you point to the specific line in your code where you are supposedly adding the fresh data to your adapter?

    – Hudi Ilfeld
    Nov 18 '18 at 11:23











  • @HudiIlfeld I have updated the code Have a look.

    – Moutamid Waseem
    Nov 18 '18 at 11:32











  • You are missing an important part in your recyclerView. you are not adding anything to your recyclerView adapter. If you have a link (on GitHub etc) to your project I would be more then happy to add the missing parts and solve your problem

    – Hudi Ilfeld
    Nov 18 '18 at 11:47

















where are u adding the editText.getText().toString() to the adapter data?

– Hudi Ilfeld
Nov 18 '18 at 11:17





where are u adding the editText.getText().toString() to the adapter data?

– Hudi Ilfeld
Nov 18 '18 at 11:17













@HudiIlfeld In three listviews where one is the type of user (Sender or receiver), second is the image of user and the third is the message which is retrieved from EditText

– Moutamid Waseem
Nov 18 '18 at 11:21







@HudiIlfeld In three listviews where one is the type of user (Sender or receiver), second is the image of user and the third is the message which is retrieved from EditText

– Moutamid Waseem
Nov 18 '18 at 11:21















could you point to the specific line in your code where you are supposedly adding the fresh data to your adapter?

– Hudi Ilfeld
Nov 18 '18 at 11:23





could you point to the specific line in your code where you are supposedly adding the fresh data to your adapter?

– Hudi Ilfeld
Nov 18 '18 at 11:23













@HudiIlfeld I have updated the code Have a look.

– Moutamid Waseem
Nov 18 '18 at 11:32





@HudiIlfeld I have updated the code Have a look.

– Moutamid Waseem
Nov 18 '18 at 11:32













You are missing an important part in your recyclerView. you are not adding anything to your recyclerView adapter. If you have a link (on GitHub etc) to your project I would be more then happy to add the missing parts and solve your problem

– Hudi Ilfeld
Nov 18 '18 at 11:47





You are missing an important part in your recyclerView. you are not adding anything to your recyclerView adapter. If you have a link (on GitHub etc) to your project I would be more then happy to add the missing parts and solve your problem

– Hudi Ilfeld
Nov 18 '18 at 11:47












2 Answers
2






active

oldest

votes


















0














Currently I am also working on chat module, let me show you how am I doing this. I am going to show you in steps.



Step 1: make two separate layout for recyclerview items, one for message that has been sent from your side and one for message received from another side.



Step 2 : make two view holders to populate different layout according to your scenario, made in above step, like this:



public class ChatNewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<Chat> chats;

public ChatNewAdapter(List<Chat> chats) {
this.chats = chats;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

if (viewType == 0) {
View viewSend = (View) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message_send, parent, false);
return new ViewHolderSend(viewSend);
} else {
View viewReceive = (View) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message_received, parent, false);
return new ViewHolderReceive(viewReceive);
}
}

@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case 0:
ViewHolderSend viewHolderSend = (ViewHolderSend) holder;
viewHolderSend.messageSend.setText(chats.get(position).getMessage());
break;

case 1:
ViewHolderReceive viewHolderReceive = (ViewHolderReceive) holder;
viewHolderReceive.messageReceived.setText(chats.get(position).getMessage());
break;
}
}

@Override
public int getItemCount() {
return chats.size();
}

@Override
public int getItemViewType(int position) {
if (chats != null && !chats.get(position).fromAdmin) {
return 0;
} else
return 1;
}

class ViewHolderSend extends RecyclerView.ViewHolder {
TextView messageSend;

public ViewHolderSend(View itemView) {
super(itemView);
messageSend = (TextView) itemView.findViewById(R.id.messageSend);
}
}

class ViewHolderReceive extends RecyclerView.ViewHolder {
TextView messageReceived;

public ViewHolderReceive(View itemView) {
super(itemView);
messageReceived = (TextView) itemView.findViewById(R.id.messageReceived);
}
}

public int addMessages(Chat chat) {
chats.add(chat);
notifyDataSetChanged();
return chats.size();
}


Step 3 : now in your activity:



public class Test extends AppCompatActivity {

RecyclerView chatList;
RecyclerView.LayoutManager mLayoutManager;
ChatNewAdapter adapter;
ImageView sendButton;
EditText messageEditText;
boolean keyboardUp = false;
boolean isRunning = false;
ArrayList<Chat> chats;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
isRunning = true;
setUpComponents();
}


public void setUpComponents() {
chatList = (RecyclerView) findViewById(R.id.chat_list);
chatList.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
chatList.setLayoutManager(mLayoutManager);
messageEditText = (EditText) findViewById(R.id.messageText);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
sendButton = (ImageView) findViewById(R.id.send);

adapter = new ChatNewAdapter(chats);
chatList.setAdapter(adapter);
chatList.scrollToPosition(chatList.getAdapter().getItemCount() - 1);

messageEditText.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (keyboardShown(messageEditText.getRootView())) {
Log.d("keyboard", "keyboard UP");

if (keyboardUp == false) {
if (chats.size() > 0)
chatList.smoothScrollToPosition(chats.size() + 1);
keyboardUp = true;
}

} else {
Log.d("keyboard", "keyboard Down");
keyboardUp = false;
}
}
});


sendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {

final String message = messageEditText.getText().toString().trim();
if (!message.equals("")) {
Chat chat = new Chat();
String name = message;
chat.setMessage(name);
messageEditText.setText("");
adapter.addMessages(chat);
chatList.scrollToPosition(chatList.getAdapter().getItemCount() - 1);

} else {
Log.d("sending message Error", "error fetching dates");
}
}
});
}

private boolean keyboardShown(View rootView) {

final int softKeyboardHeight = 100;
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
DisplayMetrics dm = rootView.getResources().getDisplayMetrics();
int heightDiff = rootView.getBottom() - r.bottom;
return heightDiff > softKeyboardHeight * dm.density;
}


And this is my model class, ignore @PrimaryKey and @Required annotation it just because I am using Realm for local DB. In your case you wont required these annotation.



public class Chat extends RealmObject {

@PrimaryKey
@Required
public Long id;
public boolean fromAdmin;
@Required
public String message;
public int type;
public boolean isRead;
public boolean isSent;
public Date date;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public boolean isFromAdmin() {
return fromAdmin;
}

public void setFromAdmin(boolean fromAdmin) {
this.fromAdmin = fromAdmin;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

public int getType() {
return type;
}

public void setType(int type) {
this.type = type;
}

public boolean isRead() {
return isRead;
}

public void setRead(boolean read) {
isRead = read;
}

public boolean isSent() {
return isSent;
}

public void setSent(boolean sent) {
isSent = sent;
}

public Date getDate() {
return date;
}

public void setDate(Date date) {
this.date = date;
}


I hope it will be helpful for you, you can ask further if you want to know anything else related to code.






share|improve this answer


























  • Ok let me see if it works furthermore i see that you're notifying the adapter by using notifyDataSetChanged() i think notifyItemInserted() would be more preferable can you show me how would i implement this. Thanks

    – Moutamid Waseem
    Nov 19 '18 at 16:44











  • Can you share your Chat Class also and what is that ".fromAdmin()" in getItemViewType and ".getMessage()" in OnBindViewHolder it gives me error saying Cannot resolve. :)

    – Moutamid Waseem
    Nov 19 '18 at 18:18











  • In my case I have a variable named as fromAdmin(boolean) in my response data, if the value of this variable is true its mean this message is from other side and in this case we will have to populate the xml which is on right side and if the fromAdmin is false its mean this message is from my own side, this is how it works. Kindly vote up my answer and check as accepted if you really find it helpful for you. Thanks :)

    – Taha wakeel
    Nov 20 '18 at 7:29











  • I will certainly mark your question as accepted but i have a problem implementing the Chat class i got your point about forAdmin() but can you please show me your Chat class

    – Moutamid Waseem
    Nov 20 '18 at 8:15











  • Thanks man, The code in Test class that I have provided you above is actually my chat class. I have implemented realm cloud in it so there were lot of extra work in my class that I removed before posting here, go through Test class and feel free to ask anything I am available.

    – Taha wakeel
    Nov 20 '18 at 8:20



















0














RecyclerView as the name stands recycles the views. When binding data to a view, you need to ensure you set or reset all views that are touched in the adapter. Messups typically occur when there's data that is set only conditionally for some but not all items.



In particular:



if (mOwnUser_1.get(position)) {
holderConversation.receivedMsgLayout.setVisibility(View.GONE);

holderConversation.sentProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.sentMsg.setText(mUserText_3.get(position));

} else {

holderConversation.sentMsgLayout.setVisibility(View.GONE);

holderConversation.receivedProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.receivedMsg.setText(mUserText_3.get(position));

}


Both of these branches will need to reset the other layout back to visible.



Anyway with this kind of two-layout approach you are likely better off by having them as separate view types in your adapter. See How to create RecyclerView with multiple view type?






share|improve this answer
























  • Thanks for answering i find out a way to solve it 😁

    – Moutamid Waseem
    Nov 22 '18 at 19:17











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53360175%2frecyclerview-messes-up-when-scrolling%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














Currently I am also working on chat module, let me show you how am I doing this. I am going to show you in steps.



Step 1: make two separate layout for recyclerview items, one for message that has been sent from your side and one for message received from another side.



Step 2 : make two view holders to populate different layout according to your scenario, made in above step, like this:



public class ChatNewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<Chat> chats;

public ChatNewAdapter(List<Chat> chats) {
this.chats = chats;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

if (viewType == 0) {
View viewSend = (View) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message_send, parent, false);
return new ViewHolderSend(viewSend);
} else {
View viewReceive = (View) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message_received, parent, false);
return new ViewHolderReceive(viewReceive);
}
}

@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case 0:
ViewHolderSend viewHolderSend = (ViewHolderSend) holder;
viewHolderSend.messageSend.setText(chats.get(position).getMessage());
break;

case 1:
ViewHolderReceive viewHolderReceive = (ViewHolderReceive) holder;
viewHolderReceive.messageReceived.setText(chats.get(position).getMessage());
break;
}
}

@Override
public int getItemCount() {
return chats.size();
}

@Override
public int getItemViewType(int position) {
if (chats != null && !chats.get(position).fromAdmin) {
return 0;
} else
return 1;
}

class ViewHolderSend extends RecyclerView.ViewHolder {
TextView messageSend;

public ViewHolderSend(View itemView) {
super(itemView);
messageSend = (TextView) itemView.findViewById(R.id.messageSend);
}
}

class ViewHolderReceive extends RecyclerView.ViewHolder {
TextView messageReceived;

public ViewHolderReceive(View itemView) {
super(itemView);
messageReceived = (TextView) itemView.findViewById(R.id.messageReceived);
}
}

public int addMessages(Chat chat) {
chats.add(chat);
notifyDataSetChanged();
return chats.size();
}


Step 3 : now in your activity:



public class Test extends AppCompatActivity {

RecyclerView chatList;
RecyclerView.LayoutManager mLayoutManager;
ChatNewAdapter adapter;
ImageView sendButton;
EditText messageEditText;
boolean keyboardUp = false;
boolean isRunning = false;
ArrayList<Chat> chats;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
isRunning = true;
setUpComponents();
}


public void setUpComponents() {
chatList = (RecyclerView) findViewById(R.id.chat_list);
chatList.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
chatList.setLayoutManager(mLayoutManager);
messageEditText = (EditText) findViewById(R.id.messageText);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
sendButton = (ImageView) findViewById(R.id.send);

adapter = new ChatNewAdapter(chats);
chatList.setAdapter(adapter);
chatList.scrollToPosition(chatList.getAdapter().getItemCount() - 1);

messageEditText.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (keyboardShown(messageEditText.getRootView())) {
Log.d("keyboard", "keyboard UP");

if (keyboardUp == false) {
if (chats.size() > 0)
chatList.smoothScrollToPosition(chats.size() + 1);
keyboardUp = true;
}

} else {
Log.d("keyboard", "keyboard Down");
keyboardUp = false;
}
}
});


sendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {

final String message = messageEditText.getText().toString().trim();
if (!message.equals("")) {
Chat chat = new Chat();
String name = message;
chat.setMessage(name);
messageEditText.setText("");
adapter.addMessages(chat);
chatList.scrollToPosition(chatList.getAdapter().getItemCount() - 1);

} else {
Log.d("sending message Error", "error fetching dates");
}
}
});
}

private boolean keyboardShown(View rootView) {

final int softKeyboardHeight = 100;
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
DisplayMetrics dm = rootView.getResources().getDisplayMetrics();
int heightDiff = rootView.getBottom() - r.bottom;
return heightDiff > softKeyboardHeight * dm.density;
}


And this is my model class, ignore @PrimaryKey and @Required annotation it just because I am using Realm for local DB. In your case you wont required these annotation.



public class Chat extends RealmObject {

@PrimaryKey
@Required
public Long id;
public boolean fromAdmin;
@Required
public String message;
public int type;
public boolean isRead;
public boolean isSent;
public Date date;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public boolean isFromAdmin() {
return fromAdmin;
}

public void setFromAdmin(boolean fromAdmin) {
this.fromAdmin = fromAdmin;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

public int getType() {
return type;
}

public void setType(int type) {
this.type = type;
}

public boolean isRead() {
return isRead;
}

public void setRead(boolean read) {
isRead = read;
}

public boolean isSent() {
return isSent;
}

public void setSent(boolean sent) {
isSent = sent;
}

public Date getDate() {
return date;
}

public void setDate(Date date) {
this.date = date;
}


I hope it will be helpful for you, you can ask further if you want to know anything else related to code.






share|improve this answer


























  • Ok let me see if it works furthermore i see that you're notifying the adapter by using notifyDataSetChanged() i think notifyItemInserted() would be more preferable can you show me how would i implement this. Thanks

    – Moutamid Waseem
    Nov 19 '18 at 16:44











  • Can you share your Chat Class also and what is that ".fromAdmin()" in getItemViewType and ".getMessage()" in OnBindViewHolder it gives me error saying Cannot resolve. :)

    – Moutamid Waseem
    Nov 19 '18 at 18:18











  • In my case I have a variable named as fromAdmin(boolean) in my response data, if the value of this variable is true its mean this message is from other side and in this case we will have to populate the xml which is on right side and if the fromAdmin is false its mean this message is from my own side, this is how it works. Kindly vote up my answer and check as accepted if you really find it helpful for you. Thanks :)

    – Taha wakeel
    Nov 20 '18 at 7:29











  • I will certainly mark your question as accepted but i have a problem implementing the Chat class i got your point about forAdmin() but can you please show me your Chat class

    – Moutamid Waseem
    Nov 20 '18 at 8:15











  • Thanks man, The code in Test class that I have provided you above is actually my chat class. I have implemented realm cloud in it so there were lot of extra work in my class that I removed before posting here, go through Test class and feel free to ask anything I am available.

    – Taha wakeel
    Nov 20 '18 at 8:20
















0














Currently I am also working on chat module, let me show you how am I doing this. I am going to show you in steps.



Step 1: make two separate layout for recyclerview items, one for message that has been sent from your side and one for message received from another side.



Step 2 : make two view holders to populate different layout according to your scenario, made in above step, like this:



public class ChatNewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<Chat> chats;

public ChatNewAdapter(List<Chat> chats) {
this.chats = chats;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

if (viewType == 0) {
View viewSend = (View) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message_send, parent, false);
return new ViewHolderSend(viewSend);
} else {
View viewReceive = (View) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message_received, parent, false);
return new ViewHolderReceive(viewReceive);
}
}

@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case 0:
ViewHolderSend viewHolderSend = (ViewHolderSend) holder;
viewHolderSend.messageSend.setText(chats.get(position).getMessage());
break;

case 1:
ViewHolderReceive viewHolderReceive = (ViewHolderReceive) holder;
viewHolderReceive.messageReceived.setText(chats.get(position).getMessage());
break;
}
}

@Override
public int getItemCount() {
return chats.size();
}

@Override
public int getItemViewType(int position) {
if (chats != null && !chats.get(position).fromAdmin) {
return 0;
} else
return 1;
}

class ViewHolderSend extends RecyclerView.ViewHolder {
TextView messageSend;

public ViewHolderSend(View itemView) {
super(itemView);
messageSend = (TextView) itemView.findViewById(R.id.messageSend);
}
}

class ViewHolderReceive extends RecyclerView.ViewHolder {
TextView messageReceived;

public ViewHolderReceive(View itemView) {
super(itemView);
messageReceived = (TextView) itemView.findViewById(R.id.messageReceived);
}
}

public int addMessages(Chat chat) {
chats.add(chat);
notifyDataSetChanged();
return chats.size();
}


Step 3 : now in your activity:



public class Test extends AppCompatActivity {

RecyclerView chatList;
RecyclerView.LayoutManager mLayoutManager;
ChatNewAdapter adapter;
ImageView sendButton;
EditText messageEditText;
boolean keyboardUp = false;
boolean isRunning = false;
ArrayList<Chat> chats;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
isRunning = true;
setUpComponents();
}


public void setUpComponents() {
chatList = (RecyclerView) findViewById(R.id.chat_list);
chatList.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
chatList.setLayoutManager(mLayoutManager);
messageEditText = (EditText) findViewById(R.id.messageText);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
sendButton = (ImageView) findViewById(R.id.send);

adapter = new ChatNewAdapter(chats);
chatList.setAdapter(adapter);
chatList.scrollToPosition(chatList.getAdapter().getItemCount() - 1);

messageEditText.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (keyboardShown(messageEditText.getRootView())) {
Log.d("keyboard", "keyboard UP");

if (keyboardUp == false) {
if (chats.size() > 0)
chatList.smoothScrollToPosition(chats.size() + 1);
keyboardUp = true;
}

} else {
Log.d("keyboard", "keyboard Down");
keyboardUp = false;
}
}
});


sendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {

final String message = messageEditText.getText().toString().trim();
if (!message.equals("")) {
Chat chat = new Chat();
String name = message;
chat.setMessage(name);
messageEditText.setText("");
adapter.addMessages(chat);
chatList.scrollToPosition(chatList.getAdapter().getItemCount() - 1);

} else {
Log.d("sending message Error", "error fetching dates");
}
}
});
}

private boolean keyboardShown(View rootView) {

final int softKeyboardHeight = 100;
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
DisplayMetrics dm = rootView.getResources().getDisplayMetrics();
int heightDiff = rootView.getBottom() - r.bottom;
return heightDiff > softKeyboardHeight * dm.density;
}


And this is my model class, ignore @PrimaryKey and @Required annotation it just because I am using Realm for local DB. In your case you wont required these annotation.



public class Chat extends RealmObject {

@PrimaryKey
@Required
public Long id;
public boolean fromAdmin;
@Required
public String message;
public int type;
public boolean isRead;
public boolean isSent;
public Date date;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public boolean isFromAdmin() {
return fromAdmin;
}

public void setFromAdmin(boolean fromAdmin) {
this.fromAdmin = fromAdmin;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

public int getType() {
return type;
}

public void setType(int type) {
this.type = type;
}

public boolean isRead() {
return isRead;
}

public void setRead(boolean read) {
isRead = read;
}

public boolean isSent() {
return isSent;
}

public void setSent(boolean sent) {
isSent = sent;
}

public Date getDate() {
return date;
}

public void setDate(Date date) {
this.date = date;
}


I hope it will be helpful for you, you can ask further if you want to know anything else related to code.






share|improve this answer


























  • Ok let me see if it works furthermore i see that you're notifying the adapter by using notifyDataSetChanged() i think notifyItemInserted() would be more preferable can you show me how would i implement this. Thanks

    – Moutamid Waseem
    Nov 19 '18 at 16:44











  • Can you share your Chat Class also and what is that ".fromAdmin()" in getItemViewType and ".getMessage()" in OnBindViewHolder it gives me error saying Cannot resolve. :)

    – Moutamid Waseem
    Nov 19 '18 at 18:18











  • In my case I have a variable named as fromAdmin(boolean) in my response data, if the value of this variable is true its mean this message is from other side and in this case we will have to populate the xml which is on right side and if the fromAdmin is false its mean this message is from my own side, this is how it works. Kindly vote up my answer and check as accepted if you really find it helpful for you. Thanks :)

    – Taha wakeel
    Nov 20 '18 at 7:29











  • I will certainly mark your question as accepted but i have a problem implementing the Chat class i got your point about forAdmin() but can you please show me your Chat class

    – Moutamid Waseem
    Nov 20 '18 at 8:15











  • Thanks man, The code in Test class that I have provided you above is actually my chat class. I have implemented realm cloud in it so there were lot of extra work in my class that I removed before posting here, go through Test class and feel free to ask anything I am available.

    – Taha wakeel
    Nov 20 '18 at 8:20














0












0








0







Currently I am also working on chat module, let me show you how am I doing this. I am going to show you in steps.



Step 1: make two separate layout for recyclerview items, one for message that has been sent from your side and one for message received from another side.



Step 2 : make two view holders to populate different layout according to your scenario, made in above step, like this:



public class ChatNewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<Chat> chats;

public ChatNewAdapter(List<Chat> chats) {
this.chats = chats;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

if (viewType == 0) {
View viewSend = (View) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message_send, parent, false);
return new ViewHolderSend(viewSend);
} else {
View viewReceive = (View) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message_received, parent, false);
return new ViewHolderReceive(viewReceive);
}
}

@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case 0:
ViewHolderSend viewHolderSend = (ViewHolderSend) holder;
viewHolderSend.messageSend.setText(chats.get(position).getMessage());
break;

case 1:
ViewHolderReceive viewHolderReceive = (ViewHolderReceive) holder;
viewHolderReceive.messageReceived.setText(chats.get(position).getMessage());
break;
}
}

@Override
public int getItemCount() {
return chats.size();
}

@Override
public int getItemViewType(int position) {
if (chats != null && !chats.get(position).fromAdmin) {
return 0;
} else
return 1;
}

class ViewHolderSend extends RecyclerView.ViewHolder {
TextView messageSend;

public ViewHolderSend(View itemView) {
super(itemView);
messageSend = (TextView) itemView.findViewById(R.id.messageSend);
}
}

class ViewHolderReceive extends RecyclerView.ViewHolder {
TextView messageReceived;

public ViewHolderReceive(View itemView) {
super(itemView);
messageReceived = (TextView) itemView.findViewById(R.id.messageReceived);
}
}

public int addMessages(Chat chat) {
chats.add(chat);
notifyDataSetChanged();
return chats.size();
}


Step 3 : now in your activity:



public class Test extends AppCompatActivity {

RecyclerView chatList;
RecyclerView.LayoutManager mLayoutManager;
ChatNewAdapter adapter;
ImageView sendButton;
EditText messageEditText;
boolean keyboardUp = false;
boolean isRunning = false;
ArrayList<Chat> chats;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
isRunning = true;
setUpComponents();
}


public void setUpComponents() {
chatList = (RecyclerView) findViewById(R.id.chat_list);
chatList.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
chatList.setLayoutManager(mLayoutManager);
messageEditText = (EditText) findViewById(R.id.messageText);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
sendButton = (ImageView) findViewById(R.id.send);

adapter = new ChatNewAdapter(chats);
chatList.setAdapter(adapter);
chatList.scrollToPosition(chatList.getAdapter().getItemCount() - 1);

messageEditText.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (keyboardShown(messageEditText.getRootView())) {
Log.d("keyboard", "keyboard UP");

if (keyboardUp == false) {
if (chats.size() > 0)
chatList.smoothScrollToPosition(chats.size() + 1);
keyboardUp = true;
}

} else {
Log.d("keyboard", "keyboard Down");
keyboardUp = false;
}
}
});


sendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {

final String message = messageEditText.getText().toString().trim();
if (!message.equals("")) {
Chat chat = new Chat();
String name = message;
chat.setMessage(name);
messageEditText.setText("");
adapter.addMessages(chat);
chatList.scrollToPosition(chatList.getAdapter().getItemCount() - 1);

} else {
Log.d("sending message Error", "error fetching dates");
}
}
});
}

private boolean keyboardShown(View rootView) {

final int softKeyboardHeight = 100;
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
DisplayMetrics dm = rootView.getResources().getDisplayMetrics();
int heightDiff = rootView.getBottom() - r.bottom;
return heightDiff > softKeyboardHeight * dm.density;
}


And this is my model class, ignore @PrimaryKey and @Required annotation it just because I am using Realm for local DB. In your case you wont required these annotation.



public class Chat extends RealmObject {

@PrimaryKey
@Required
public Long id;
public boolean fromAdmin;
@Required
public String message;
public int type;
public boolean isRead;
public boolean isSent;
public Date date;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public boolean isFromAdmin() {
return fromAdmin;
}

public void setFromAdmin(boolean fromAdmin) {
this.fromAdmin = fromAdmin;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

public int getType() {
return type;
}

public void setType(int type) {
this.type = type;
}

public boolean isRead() {
return isRead;
}

public void setRead(boolean read) {
isRead = read;
}

public boolean isSent() {
return isSent;
}

public void setSent(boolean sent) {
isSent = sent;
}

public Date getDate() {
return date;
}

public void setDate(Date date) {
this.date = date;
}


I hope it will be helpful for you, you can ask further if you want to know anything else related to code.






share|improve this answer















Currently I am also working on chat module, let me show you how am I doing this. I am going to show you in steps.



Step 1: make two separate layout for recyclerview items, one for message that has been sent from your side and one for message received from another side.



Step 2 : make two view holders to populate different layout according to your scenario, made in above step, like this:



public class ChatNewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<Chat> chats;

public ChatNewAdapter(List<Chat> chats) {
this.chats = chats;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

if (viewType == 0) {
View viewSend = (View) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message_send, parent, false);
return new ViewHolderSend(viewSend);
} else {
View viewReceive = (View) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message_received, parent, false);
return new ViewHolderReceive(viewReceive);
}
}

@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case 0:
ViewHolderSend viewHolderSend = (ViewHolderSend) holder;
viewHolderSend.messageSend.setText(chats.get(position).getMessage());
break;

case 1:
ViewHolderReceive viewHolderReceive = (ViewHolderReceive) holder;
viewHolderReceive.messageReceived.setText(chats.get(position).getMessage());
break;
}
}

@Override
public int getItemCount() {
return chats.size();
}

@Override
public int getItemViewType(int position) {
if (chats != null && !chats.get(position).fromAdmin) {
return 0;
} else
return 1;
}

class ViewHolderSend extends RecyclerView.ViewHolder {
TextView messageSend;

public ViewHolderSend(View itemView) {
super(itemView);
messageSend = (TextView) itemView.findViewById(R.id.messageSend);
}
}

class ViewHolderReceive extends RecyclerView.ViewHolder {
TextView messageReceived;

public ViewHolderReceive(View itemView) {
super(itemView);
messageReceived = (TextView) itemView.findViewById(R.id.messageReceived);
}
}

public int addMessages(Chat chat) {
chats.add(chat);
notifyDataSetChanged();
return chats.size();
}


Step 3 : now in your activity:



public class Test extends AppCompatActivity {

RecyclerView chatList;
RecyclerView.LayoutManager mLayoutManager;
ChatNewAdapter adapter;
ImageView sendButton;
EditText messageEditText;
boolean keyboardUp = false;
boolean isRunning = false;
ArrayList<Chat> chats;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
isRunning = true;
setUpComponents();
}


public void setUpComponents() {
chatList = (RecyclerView) findViewById(R.id.chat_list);
chatList.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
chatList.setLayoutManager(mLayoutManager);
messageEditText = (EditText) findViewById(R.id.messageText);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
sendButton = (ImageView) findViewById(R.id.send);

adapter = new ChatNewAdapter(chats);
chatList.setAdapter(adapter);
chatList.scrollToPosition(chatList.getAdapter().getItemCount() - 1);

messageEditText.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (keyboardShown(messageEditText.getRootView())) {
Log.d("keyboard", "keyboard UP");

if (keyboardUp == false) {
if (chats.size() > 0)
chatList.smoothScrollToPosition(chats.size() + 1);
keyboardUp = true;
}

} else {
Log.d("keyboard", "keyboard Down");
keyboardUp = false;
}
}
});


sendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {

final String message = messageEditText.getText().toString().trim();
if (!message.equals("")) {
Chat chat = new Chat();
String name = message;
chat.setMessage(name);
messageEditText.setText("");
adapter.addMessages(chat);
chatList.scrollToPosition(chatList.getAdapter().getItemCount() - 1);

} else {
Log.d("sending message Error", "error fetching dates");
}
}
});
}

private boolean keyboardShown(View rootView) {

final int softKeyboardHeight = 100;
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
DisplayMetrics dm = rootView.getResources().getDisplayMetrics();
int heightDiff = rootView.getBottom() - r.bottom;
return heightDiff > softKeyboardHeight * dm.density;
}


And this is my model class, ignore @PrimaryKey and @Required annotation it just because I am using Realm for local DB. In your case you wont required these annotation.



public class Chat extends RealmObject {

@PrimaryKey
@Required
public Long id;
public boolean fromAdmin;
@Required
public String message;
public int type;
public boolean isRead;
public boolean isSent;
public Date date;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public boolean isFromAdmin() {
return fromAdmin;
}

public void setFromAdmin(boolean fromAdmin) {
this.fromAdmin = fromAdmin;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

public int getType() {
return type;
}

public void setType(int type) {
this.type = type;
}

public boolean isRead() {
return isRead;
}

public void setRead(boolean read) {
isRead = read;
}

public boolean isSent() {
return isSent;
}

public void setSent(boolean sent) {
isSent = sent;
}

public Date getDate() {
return date;
}

public void setDate(Date date) {
this.date = date;
}


I hope it will be helpful for you, you can ask further if you want to know anything else related to code.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 22 '18 at 8:08

























answered Nov 19 '18 at 15:37









Taha wakeelTaha wakeel

896




896













  • Ok let me see if it works furthermore i see that you're notifying the adapter by using notifyDataSetChanged() i think notifyItemInserted() would be more preferable can you show me how would i implement this. Thanks

    – Moutamid Waseem
    Nov 19 '18 at 16:44











  • Can you share your Chat Class also and what is that ".fromAdmin()" in getItemViewType and ".getMessage()" in OnBindViewHolder it gives me error saying Cannot resolve. :)

    – Moutamid Waseem
    Nov 19 '18 at 18:18











  • In my case I have a variable named as fromAdmin(boolean) in my response data, if the value of this variable is true its mean this message is from other side and in this case we will have to populate the xml which is on right side and if the fromAdmin is false its mean this message is from my own side, this is how it works. Kindly vote up my answer and check as accepted if you really find it helpful for you. Thanks :)

    – Taha wakeel
    Nov 20 '18 at 7:29











  • I will certainly mark your question as accepted but i have a problem implementing the Chat class i got your point about forAdmin() but can you please show me your Chat class

    – Moutamid Waseem
    Nov 20 '18 at 8:15











  • Thanks man, The code in Test class that I have provided you above is actually my chat class. I have implemented realm cloud in it so there were lot of extra work in my class that I removed before posting here, go through Test class and feel free to ask anything I am available.

    – Taha wakeel
    Nov 20 '18 at 8:20



















  • Ok let me see if it works furthermore i see that you're notifying the adapter by using notifyDataSetChanged() i think notifyItemInserted() would be more preferable can you show me how would i implement this. Thanks

    – Moutamid Waseem
    Nov 19 '18 at 16:44











  • Can you share your Chat Class also and what is that ".fromAdmin()" in getItemViewType and ".getMessage()" in OnBindViewHolder it gives me error saying Cannot resolve. :)

    – Moutamid Waseem
    Nov 19 '18 at 18:18











  • In my case I have a variable named as fromAdmin(boolean) in my response data, if the value of this variable is true its mean this message is from other side and in this case we will have to populate the xml which is on right side and if the fromAdmin is false its mean this message is from my own side, this is how it works. Kindly vote up my answer and check as accepted if you really find it helpful for you. Thanks :)

    – Taha wakeel
    Nov 20 '18 at 7:29











  • I will certainly mark your question as accepted but i have a problem implementing the Chat class i got your point about forAdmin() but can you please show me your Chat class

    – Moutamid Waseem
    Nov 20 '18 at 8:15











  • Thanks man, The code in Test class that I have provided you above is actually my chat class. I have implemented realm cloud in it so there were lot of extra work in my class that I removed before posting here, go through Test class and feel free to ask anything I am available.

    – Taha wakeel
    Nov 20 '18 at 8:20

















Ok let me see if it works furthermore i see that you're notifying the adapter by using notifyDataSetChanged() i think notifyItemInserted() would be more preferable can you show me how would i implement this. Thanks

– Moutamid Waseem
Nov 19 '18 at 16:44





Ok let me see if it works furthermore i see that you're notifying the adapter by using notifyDataSetChanged() i think notifyItemInserted() would be more preferable can you show me how would i implement this. Thanks

– Moutamid Waseem
Nov 19 '18 at 16:44













Can you share your Chat Class also and what is that ".fromAdmin()" in getItemViewType and ".getMessage()" in OnBindViewHolder it gives me error saying Cannot resolve. :)

– Moutamid Waseem
Nov 19 '18 at 18:18





Can you share your Chat Class also and what is that ".fromAdmin()" in getItemViewType and ".getMessage()" in OnBindViewHolder it gives me error saying Cannot resolve. :)

– Moutamid Waseem
Nov 19 '18 at 18:18













In my case I have a variable named as fromAdmin(boolean) in my response data, if the value of this variable is true its mean this message is from other side and in this case we will have to populate the xml which is on right side and if the fromAdmin is false its mean this message is from my own side, this is how it works. Kindly vote up my answer and check as accepted if you really find it helpful for you. Thanks :)

– Taha wakeel
Nov 20 '18 at 7:29





In my case I have a variable named as fromAdmin(boolean) in my response data, if the value of this variable is true its mean this message is from other side and in this case we will have to populate the xml which is on right side and if the fromAdmin is false its mean this message is from my own side, this is how it works. Kindly vote up my answer and check as accepted if you really find it helpful for you. Thanks :)

– Taha wakeel
Nov 20 '18 at 7:29













I will certainly mark your question as accepted but i have a problem implementing the Chat class i got your point about forAdmin() but can you please show me your Chat class

– Moutamid Waseem
Nov 20 '18 at 8:15





I will certainly mark your question as accepted but i have a problem implementing the Chat class i got your point about forAdmin() but can you please show me your Chat class

– Moutamid Waseem
Nov 20 '18 at 8:15













Thanks man, The code in Test class that I have provided you above is actually my chat class. I have implemented realm cloud in it so there were lot of extra work in my class that I removed before posting here, go through Test class and feel free to ask anything I am available.

– Taha wakeel
Nov 20 '18 at 8:20





Thanks man, The code in Test class that I have provided you above is actually my chat class. I have implemented realm cloud in it so there were lot of extra work in my class that I removed before posting here, go through Test class and feel free to ask anything I am available.

– Taha wakeel
Nov 20 '18 at 8:20













0














RecyclerView as the name stands recycles the views. When binding data to a view, you need to ensure you set or reset all views that are touched in the adapter. Messups typically occur when there's data that is set only conditionally for some but not all items.



In particular:



if (mOwnUser_1.get(position)) {
holderConversation.receivedMsgLayout.setVisibility(View.GONE);

holderConversation.sentProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.sentMsg.setText(mUserText_3.get(position));

} else {

holderConversation.sentMsgLayout.setVisibility(View.GONE);

holderConversation.receivedProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.receivedMsg.setText(mUserText_3.get(position));

}


Both of these branches will need to reset the other layout back to visible.



Anyway with this kind of two-layout approach you are likely better off by having them as separate view types in your adapter. See How to create RecyclerView with multiple view type?






share|improve this answer
























  • Thanks for answering i find out a way to solve it 😁

    – Moutamid Waseem
    Nov 22 '18 at 19:17
















0














RecyclerView as the name stands recycles the views. When binding data to a view, you need to ensure you set or reset all views that are touched in the adapter. Messups typically occur when there's data that is set only conditionally for some but not all items.



In particular:



if (mOwnUser_1.get(position)) {
holderConversation.receivedMsgLayout.setVisibility(View.GONE);

holderConversation.sentProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.sentMsg.setText(mUserText_3.get(position));

} else {

holderConversation.sentMsgLayout.setVisibility(View.GONE);

holderConversation.receivedProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.receivedMsg.setText(mUserText_3.get(position));

}


Both of these branches will need to reset the other layout back to visible.



Anyway with this kind of two-layout approach you are likely better off by having them as separate view types in your adapter. See How to create RecyclerView with multiple view type?






share|improve this answer
























  • Thanks for answering i find out a way to solve it 😁

    – Moutamid Waseem
    Nov 22 '18 at 19:17














0












0








0







RecyclerView as the name stands recycles the views. When binding data to a view, you need to ensure you set or reset all views that are touched in the adapter. Messups typically occur when there's data that is set only conditionally for some but not all items.



In particular:



if (mOwnUser_1.get(position)) {
holderConversation.receivedMsgLayout.setVisibility(View.GONE);

holderConversation.sentProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.sentMsg.setText(mUserText_3.get(position));

} else {

holderConversation.sentMsgLayout.setVisibility(View.GONE);

holderConversation.receivedProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.receivedMsg.setText(mUserText_3.get(position));

}


Both of these branches will need to reset the other layout back to visible.



Anyway with this kind of two-layout approach you are likely better off by having them as separate view types in your adapter. See How to create RecyclerView with multiple view type?






share|improve this answer













RecyclerView as the name stands recycles the views. When binding data to a view, you need to ensure you set or reset all views that are touched in the adapter. Messups typically occur when there's data that is set only conditionally for some but not all items.



In particular:



if (mOwnUser_1.get(position)) {
holderConversation.receivedMsgLayout.setVisibility(View.GONE);

holderConversation.sentProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.sentMsg.setText(mUserText_3.get(position));

} else {

holderConversation.sentMsgLayout.setVisibility(View.GONE);

holderConversation.receivedProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.receivedMsg.setText(mUserText_3.get(position));

}


Both of these branches will need to reset the other layout back to visible.



Anyway with this kind of two-layout approach you are likely better off by having them as separate view types in your adapter. See How to create RecyclerView with multiple view type?







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 22 '18 at 8:14









laaltolaalto

116k27190227




116k27190227













  • Thanks for answering i find out a way to solve it 😁

    – Moutamid Waseem
    Nov 22 '18 at 19:17



















  • Thanks for answering i find out a way to solve it 😁

    – Moutamid Waseem
    Nov 22 '18 at 19:17

















Thanks for answering i find out a way to solve it 😁

– Moutamid Waseem
Nov 22 '18 at 19:17





Thanks for answering i find out a way to solve it 😁

– Moutamid Waseem
Nov 22 '18 at 19:17


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53360175%2frecyclerview-messes-up-when-scrolling%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Guess what letter conforming each word

Port of Spain

Run scheduled task as local user group (not BUILTIN)