Android - RecyclerViewer not populating data - android

I'm rather new to Android development and I'm trying to muddle my way through getting this working.
I tried scouring the web, but the tips I found were focused on making sure your getItemCount isn't returning 0, which it isn't, and making sure I attached the adapter to the RecyclerView, which I believe I have.
I'm hoping I'm just missing something dumb and this will be a quick fix, thanks in advance for any responses (and let me know if you need anymore info)!
Adapter:
public class MessageListAdapter extends RecyclerView.Adapter {
private static final int VIEW_TYPE_MESSAGE_SENT = 1;
private static final int VIEW_TYPE_MESSAGE_RECEIVED = 2;
private Context mContext;
private List<SocketMessage> mMessageList;
private String username;
public MessageListAdapter(Context context, List<SocketMessage> messageList, String username) {
mContext = context;
mMessageList = messageList;
this.username = username;
}
#Override
public int getItemCount() {
return mMessageList.size();
}
// Determines the appropriate ViewType according to the sender of the message.
#Override
public int getItemViewType(int position) {
SocketMessage message = (SocketMessage) mMessageList.get(position);
if (message.Username.contentEquals(this.username)) {
// If the current user is the sender of the message
return VIEW_TYPE_MESSAGE_SENT;
} else {
// If some other user sent the message
return VIEW_TYPE_MESSAGE_RECEIVED;
}
}
// Inflates the appropriate layout according to the ViewType.
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
if (viewType == VIEW_TYPE_MESSAGE_SENT) {
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_message_sent, parent, false);
return new SentMessageHolder(view);
} else if (viewType == VIEW_TYPE_MESSAGE_RECEIVED) {
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_message_received, parent, false);
return new ReceivedMessageHolder(view);
}
return null;
}
// Passes the message object to a ViewHolder so that the contents can be bound to UI.
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
SocketMessage message = (SocketMessage) mMessageList.get(position);
switch (holder.getItemViewType()) {
case VIEW_TYPE_MESSAGE_SENT:
((SentMessageHolder) holder).bind(message);
break;
case VIEW_TYPE_MESSAGE_RECEIVED:
((ReceivedMessageHolder) holder).bind(message);
}
}
public void add(SocketMessage socketMessage) {
mMessageList.add(socketMessage);
notifyDataSetChanged();
}
class MessageViewHolder {
public TextView name;
public TextView messageBody;
}
class ReceivedMessageHolder extends RecyclerView.ViewHolder {
TextView messageText, timeText, nameText;
ReceivedMessageHolder(View itemView) {
super(itemView);
messageText = (TextView) itemView.findViewById(R.id.text_message_body);
nameText = (TextView) itemView.findViewById(R.id.text_message_name);
}
void bind(SocketMessage message) {
messageText.setText(message.MessageText);
// Format the stored timestamp into a readable String using method.
nameText.setText(message.Username);
}
}
class SentMessageHolder extends RecyclerView.ViewHolder {
TextView messageText, timeText;
SentMessageHolder(View itemView) {
super(itemView);
messageText = (TextView) itemView.findViewById(R.id.text_message_body);
}
void bind(SocketMessage message) {
messageText.setText(message.MessageText);
}
}}
Activity OnCreate:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_socket_chat);
app = (HMCTHubApplication) getApplication();
socket = app.getSocket();
setContentView(R.layout.activity_socket_chat);
mMessageList = new ArrayList<SocketMessage>();
mMessageAdapter = new MessageListAdapter(this,mMessageList,app.getUsername());
messagesView = (RecyclerView) findViewById(R.id.reyclerview_message_list);
messagesView.setAdapter(mMessageAdapter);
messagesView.setLayoutManager(new LinearLayoutManager(this));
runOnUiThread(new Runnable() {
#Override
public void run() {
mMessageAdapter.add(new SocketMessage("test","this is a test msg"));
}
});
socket.on("receivedMessage",ReceivedMessage);
Button sendButton = (Button) findViewById(R.id.button_chatbox_send);
sendButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view){
EditText input = (EditText)findViewById(R.id.edittext_chatbox);
final SocketMessage message = new SocketMessage(app.getUsername(),input.getText().toString());
try{
socket.emit("ChatMessage", new ObjectMapper().writeValueAsString(message));
input.setText("");
runOnUiThread(new Runnable() {
#Override
public void run() {
mMessageAdapter.add(message);
}
});
}
catch(Exception ex){
Log.v("[ChatActivity]", "Fail on send message");
Log.v("[ChatActivity]",ex.getMessage());
}
}
});
}
Activity Layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="dotsoflight.hmcthub.SocketChatActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/reyclerview_message_list"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
</android.support.v7.widget.RecyclerView>
<!-- A horizontal line between the chatbox and RecyclerView -->
<View
android:layout_width="0dp"
android:layout_height="2dp"
android:background="#dfdfdf"
android:layout_marginBottom="0dp"
app:layout_constraintBottom_toTopOf="#+id/layout_chatbox"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<LinearLayout
android:id="#+id/layout_chatbox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:minHeight="48dp"
android:background="#ffffff"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent">
<EditText
android:id="#+id/edittext_chatbox"
android:hint="Enter message"
android:background="#android:color/transparent"
android:layout_gravity="center"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:maxLines="6"/>
<Button
android:id="#+id/button_chatbox_send"
android:text="SEND"
android:textSize="14dp"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:layout_width="64dp"
android:layout_height="48dp"
android:gravity="center"
android:layout_gravity="bottom" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
EDIT: I don't believe this question is related, as I'm calling this from an Activity not a fragment, I took a look at the answers but none seem to apply as they're using a fragment.
EDIT2: Levi found the problems! I had to set the LayoutManager prior to setting the Adapter and add the following to the bottom of my RecyclerView layout:
app:layout_constraintBottom_toBottomOf="parent"
As I was telling it to fit the height constraint while not setting a bottom constraint.

Set the adapter AFTER the layout manager:
messagesView.setLayoutManager(new LinearLayoutManager(this));
messagesView.setAdapter(mMessageAdapter);
EDIT:
There's no constraint to the bottom of your recycler view, but you set the height to match constraint. You need to constraint both top and bottom to something in this case:
app:layout_constraintBottom_toBottomOf="parent"

Related

not getting id of a clicked child item inside RecyclerView item layout

I have implemented a RecyclerView inside a ConstraintLayout. I am having one child image element inside the layout. But when I click the child image, it always returns the ConstraintLayout, not the clicked image.
Could you please tell me why this is happening, what is the solution for this ?
I separately did bind listener to image, it is working but not able to get the RecyclerItem object. I need RecyclerItem object for the position to proceed.
I implemented it by binding elements via onBindViewholder method in Adapter. Below are the codes
customAdapter = new GridViewAdapter(recyclerItems, 1, this.getContext().getPackageName(),
new GridViewAdapter.OnItemClickListener(){
#Override
public void onItemClick(RecyclerItem item) {
CommonUtil.addFragment("REP", Constants.CONTAINER_HOME,
new ModifyFragment(), getActivity(), null);
}
}, R.layout.rec_view_item_stock, Constants.V_SPAN_LIST_8);
RecyclerView recyclerView = view.findViewById(R.id.stockListRecView);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setLayoutManager(new GridLayoutManager(this.getContext(), 1));
recyclerView.setAdapter(customAdapter);
//Adapter
public class GridViewAdapter extends RecyclerView.Adapter<GridViewAdapter.ViewHolder>{
private List<RecyclerItem> dataItems;
private int hSpan = 1;
private String packageName;
private final OnItemClickListener listener;
private int inflator;
private int vSpan;
public interface OnItemClickListener {
void onItemClick(RecyclerItem item);
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private final ConstraintLayout constraintLayout;
private final TextView textView;
private final ImageView imageView;
private Object obj;
public ViewHolder(View view) {
super(view);
constraintLayout = (ConstraintLayout) view.findViewById(R.id.rec_content_layout);
textView = constraintLayout.findViewById(R.id.recTextView);
imageView = constraintLayout.findViewById(R.id.recImage);
}
public void bind(final RecyclerItem item, final OnItemClickListener listener) {
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(item);
}
});
}
public TextView getTextView() {
return textView;
}
public ImageView getImageView() {
return imageView;
}
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
}
public GridViewAdapter(List<RecyclerItem> items, int spanCount, String packageName, OnItemClickListener listener,
int inflator, int vSpan) {
dataItems = items;
this.hSpan = spanCount;
this.packageName = packageName;
this.listener = listener;
this.inflator = inflator;
this.vSpan = vSpan;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int gridType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(inflator, viewGroup, false);
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.width = (viewGroup.getResources().getDisplayMetrics().widthPixels / hSpan) - 24;
if(Constants.V_SPAN_GRID == vSpan) {
layoutParams.height = layoutParams.width;
} else {
layoutParams.height = (viewGroup.getResources().getDisplayMetrics().widthPixels / vSpan);
}
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
viewHolder.getTextView().setText(dataItems.get(position).getText());
int imgId = viewHolder.getImageView().getResources().getIdentifier(
dataItems.get(position).getImageName(), "drawable", packageName);
viewHolder.getImageView().setImageResource(imgId);
viewHolder.setObj(dataItems.get(position));
viewHolder.bind(dataItems.get(position), listener);
}
#Override
public int getItemCount() {
return dataItems.size();
}
//item layout
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/rec_content_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_marginTop="8dp"
android:layout_marginLeft="4dp"
android:padding="8dp"
android:background="#drawable/border_top_bottom" >
<androidx.constraintlayout.widget.Guideline
android:id="#+id/viewstock_gline_1_v"
android:layout_width="1dp"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.6"/>
<ImageView
android:id="#+id/recImage"
android:background="#color/colorPrimaryDark"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp" />
<TextView
android:id="#+id/recTextView"
app:layout_constraintLeft_toRightOf="#+id/recImage"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp" />
<ImageView
android:id="#+id/editstock_image"
android:src="#drawable/ic_edit_stock"
android:background="#color/colorPrimaryDark"
app:layout_constraintRight_toLeftOf="#+id/deletestock_image"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp" />
<ImageView
android:id="#+id/deletestock_image"
android:src="#drawable/ic_delete_stock"
android:background="#color/colorPrimaryDark"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp" />
</androidx.constraintlayout.widget.ConstraintLayout>```
Try this!
public void bind(final RecyclerItem item, final OnItemClickListener listener, TextView itemTextView) {
itemTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(item);
}
});
}
Pass every item text view instance from the view holder or fro onBindViewHolder itself implement onclick listener

Android Studio Constraintlayout align to the right programatically

I'm making a chat app and I'm having some trouble with the layout of my messages. I want the messages send by the logged in user to be aligned to the right of the layout and the messages send by other group members to be aligned to the left.
This is my xml file:
<android.support.constraint.ConstraintLayout
android:id="#+id/container_message"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp">
<ImageView
android:id="#+id/user_image"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="8dp"
android:src="#color/colorBlack"
app:layout_constraintBottom_toBottomOf="#+id/container_message_text"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="#+id/date_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:fontFamily="#font/rubik_light"
android:text="19 juni, 00:32"
android:textSize="10sp"
app:layout_constraintStart_toStartOf="#+id/container_message_text"
app:layout_constraintTop_toBottomOf="#+id/container_message_text" />
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/container_message_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="48dp"
android:paddingStart="12dp"
android:paddingTop="12dp"
android:paddingEnd="12dp"
app:cardBackgroundColor="#color/colorTextWhite"
app:cardCornerRadius="16dp"
app:cardElevation="0dp"
app:layout_constraintStart_toStartOf="parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingStart="12dp"
android:paddingTop="7dp"
android:paddingEnd="12dp"
android:paddingBottom="7dp">
<TextView
android:id="#+id/message_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="#font/rubik"
android:textSize="16sp"
android:maxWidth="240dp" />
</FrameLayout>
</android.support.v7.widget.CardView>
Picture of the current layout:
I need the purple messages to be aligned to the right, how can this be done programmatically?
You should better try chat layout using two different layouts for sender's message and yours message and if you are using recyclerview then the following adapter might help you.
public class MessageListAdapter extends RecyclerView.Adapter {
private static final int VIEW_TYPE_MESSAGE_SENT = 1;
private static final int VIEW_TYPE_MESSAGE_RECEIVED = 2;
private Context mContext;
private List<UserMessage> mMessageList;
public MessageListAdapter(Context context, List<UserMessage> messageList) {
mContext = context;
mMessageList = messageList;
}
#Override
public int getItemCount() {
return mMessageList.size();
}
// Determines the appropriate ViewType according to the sender of the message.
#Override
public int getItemViewType(int position) {
UserMessage message = (UserMessage) mMessageList.get(position);
if (message.getSender().getUserId().equals(currentUserId)) {
// If the current user is the sender of the message
return VIEW_TYPE_MESSAGE_SENT;
} else {
// If some other user sent the message
return VIEW_TYPE_MESSAGE_RECEIVED;
}
}
// Inflates the appropriate layout according to the ViewType
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
if (viewType == VIEW_TYPE_MESSAGE_SENT) {
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_message_sent, parent, false);
return new SentMessageHolder(view);
} else if (viewType == VIEW_TYPE_MESSAGE_RECEIVED) {
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_message_received, parent, false);
return new ReceivedMessageHolder(view);
}
return null;
}
// Passes the message object to a ViewHolder so that the contents can be bound to UI.
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
UserMessage message = (UserMessage) mMessageList.get(position);
switch (holder.getItemViewType()) {
case VIEW_TYPE_MESSAGE_SENT:
((SentMessageHolder) holder).bind(message);
break;
case VIEW_TYPE_MESSAGE_RECEIVED:
((ReceivedMessageHolder) holder).bind(message);
}
}
private class SentMessageHolder extends RecyclerView.ViewHolder {
SentMessageHolder(View itemView) {
super(itemView);
//bind views
}
void bind(UserMessage message) {
//set values
}
}
private class ReceivedMessageHolder extends RecyclerView.ViewHolder {
ReceivedMessageHolder(View itemView) {
super(itemView);
//bind views
}
void bind(UserMessage message) {
//set values
}
}
}

I am building a chat application and not able to get the right and left styling

That is when the sender from one device sends message,it should appear on the right hand side and when the other device gets the message it should appear on the left hand side.
My java class: This is the function I am calling
private void chatRowStyling(boolean isItMe, ViewHolder holder){
if (isItMe){
holder.layoutParams.gravity = Gravity.END;
holder.chatBody.setTextColor(Color.BLUE);
holder.senderName.setBackgroundResource(R.drawable.speech_bubble_green);
}else{
holder.layoutParams.gravity = Gravity.START;
holder.chatBody.setTextColor(Color.GREEN);
holder.senderName.setBackgroundResource(R.drawable.speech_bubble_orange);
}
Log.i("TAG","error :" + mySnapShot);
holder.senderName.setLayoutParams(holder.layoutParams);
holder.chatBody.setLayoutParams(holder.layoutParams);
}
In the Screenshot, all the messages appear on the right side, whereas I want one to be on right and another to be on left from different users.
This is my XML code :
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/singleMessageContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:text="#string/sender"
android:textColor="#2980b9"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="#+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_margin="5dip"
android:padding="12dp"
android:text="#string/author"
android:textColor="#2c3e50" />
</LinearLayout>
The best way to do it would be to implement RecyclerView with separate view types, that way you could adjust layout however you want without some shady workaround. Here is example to do it.
Reference : How to create RecyclerView with multiple view type?
EDIT:
Convinced by comments I decided to add some more explanation.
You could create two separate layouts, one for your messages:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/tvAuthor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"/>
<TextView
android:id="#+id/tvMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/tvAuthor"
android:layout_alignParentRight="true"/>
</RelativeLayout>
and the other one for messages from friend:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/tvAuthor"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/tvMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/tvAuthor" />
</RelativeLayout>
Then you can create a class for your messages:
public class Message {
private String message;
private String author;
public Message(String message, String author) {
this.message = message;
this.author = author;
}
public String getMessage() {
return message;
}
public String getAuthor() {
return author;
}
}
Next step would be to create adapter for your RecyclerView that will use two seperate ViewHolders, one for your messages and the other for messages from your friend. Inside OnCreateViewHolder you can choose which layout you want to display for each message. Then in OnBindViewHolder, you can fill TextViews with correct message data.
public class MessageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<Message> messages;
private final static int TYPE_FROM_FRIEND = 1;
private final static int TYPE_TO_FRIEND = 2;
public MessageAdapter(ArrayList<Message> messages) {
this.messages = messages;
}
public int getItemViewType(int position) {
if (messages.get(position).getAuthor().equals("Me")) {
return TYPE_TO_FRIEND;
} else {
return TYPE_FROM_FRIEND;
}
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
int layout = 0;
RecyclerView.ViewHolder viewHolder;
switch (viewType){
case TYPE_TO_FRIEND:
layout = R.layout.view_message_to_friend;
View toFriendView = LayoutInflater
.from(parent.getContext())
.inflate(layout, parent, false);
viewHolder=new ToFriendViewHolder(toFriendView);
break;
case TYPE_FROM_FRIEND:
layout = R.layout.view_message_from_friend;
View fromFriendView = LayoutInflater
.from(parent.getContext())
.inflate(layout, parent, false);
viewHolder = new FromFriendViewHolder(fromFriendView);
break;
default:
viewHolder = null;
break;
}
return viewHolder;
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
int viewType=holder.getItemViewType();
switch (viewType){
case TYPE_TO_FRIEND:
((ToFriendViewHolder)holder).tvMessage.setText(messages.get(position).getMessage());
((ToFriendViewHolder)holder).tvAuthor.setText(messages.get(position).getAuthor());
break;
case TYPE_FROM_FRIEND:
((FromFriendViewHolder)holder).tvMessage.setText(messages.get(position).getMessage());
((FromFriendViewHolder)holder).tvAuthor.setText(messages.get(position).getAuthor());
break;
}
}
private class ToFriendViewHolder extends RecyclerView.ViewHolder {
private TextView tvAuthor;
private TextView tvMessage;
public ToFriendViewHolder(View view) {
super(view);
tvAuthor = (TextView) view.findViewById(R.id.tvAuthor);
tvMessage = (TextView) view.findViewById(R.id.tvMessage);
}
}
private class FromFriendViewHolder extends RecyclerView.ViewHolder {
private TextView tvAuthor;
private TextView tvMessage;
public FromFriendViewHolder(View view) {
super(view);
tvAuthor = (TextView) view.findViewById(R.id.tvAuthor);
tvMessage = (TextView) view.findViewById(R.id.tvMessage);
}
}
#Override
public int getItemCount() {
return messages.size();
}
}
Finally you can set RecyclerView's adapter in your activity:
public class MainActivity extends AppCompatActivity {
private RecyclerView rvMain;
private ArrayList<Message> messages = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rvMain = (RecyclerView) findViewById(R.id.rvMain);
rvMain.setLayoutManager(new LinearLayoutManager(this));
messages.add(new Message("Hello", "Me"));
messages.add(new Message("Hi", "Friend"));
messages.add(new Message("How are you?", "Me"));
messages.add(new Message("I'm fine and you?", "Friend"));
MessageAdapter adapter = new MessageAdapter(messages);
rvMain.setAdapter(adapter);
}
}
You can achieve it by setting the view gravity not the LayoutParams with something like this:
if(isIfMe) {
holder.linearLayout.setGravity(Gravity.END);
holder.tvAuthor.setGravity(Gravity.END);
} else {
holder.linearLayout.setGravity(Gravity.END);
holder.tvAuthor.setGravity(Gravity.END);
}

RecyclerView does not display items

I am using RecyclerView in Android with a model class that has title and details. Nothing is showing. Even after log inside Adapter nothing is shown in Android Monitor.
MainActivity.class
public ArrayList<Menu> menu_list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_menu);
initUi();
}
public void initUi(){
RecyclerView menu_recycler = (RecyclerView) findViewById(R.id.main_menu_recycler_view);
//set the layout manager
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation( linearLayoutManager.VERTICAL );
menu_recycler.setLayoutManager( linearLayoutManager );
//set adapter
MainMenuAdapter mainMenuAdapter = new MainMenuAdapter( getMenulist() );
menu_recycler.setAdapter( mainMenuAdapter );
}
public ArrayList<Menu> getMenulist() {
menu_list = new ArrayList<Menu>();
menu_list.add( new Menu("About Us", " Learn more about our values, mission and vision ") );
menu_list.add( new Menu("Services ", " In implementing its mandate, the Agency will provide the following to its external and internal customers:\n"));
menu_list.add( new Menu("Stakeholders", " Who are the key players, Find out more") );
menu_list.add( new Menu("Learn about Counterfeits", "Gain more insight on counterfeit products"));
return menu_list;
}
and here is my adapter
public class MainMenuAdapter extends RecyclerView.Adapter<MainMenuAdapter.MyViewHolder> {
public List<Menu> list_of_menus;
public MainMenuAdapter( List<Menu> list_of_menus){
this.list_of_menus = list_of_menus;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.row,parent, false);
return new MyViewHolder(v);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Menu menu = list_of_menus.get(position);
Log.e("MENU IN ADAPTER TITLE", menu.title);
holder.title_text.setText( menu.title );
holder.details_text.setText( menu.details );
}
#Override
public int getItemCount() {
return 0;
}
/*
View Holder class
* */
public class MyViewHolder extends RecyclerView.ViewHolder{
public TextView title_text, details_text;
public MyViewHolder(View itemView) {
super(itemView);
title_text = (TextView) itemView.findViewById(R.id.menu_title);
details_text = (TextView) itemView.findViewById(R.id.menu_details);
}
}
}
And the Model Class
public class Menu {
public String title, details;
public Menu(String title, String details){
this.details = details;
this.title = title;
}
}
And the layout file main_activity
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.maos.aca.MainMenuActivity">
<android.support.v7.widget.RecyclerView
android:layout_width="334dp"
android:layout_height="453dp" app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="8dp" app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="8dp" android:layout_marginLeft="8dp"
app:layout_constraintLeft_toLeftOf="parent" android:layout_marginRight="8dp"
app:layout_constraintRight_toRightOf="parent" android:id="#+id/main_menu_recycler_view"
android:scrollbars="vertical"/>
</android.support.constraint.ConstraintLayout>
And finally the row
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/menu_title"
android:textStyle="bold"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/app_name"
android:id="#+id/menu_details"/>
</LinearLayout>
I know this question has been asked before, but none of the answers helped me out.I'll appreciate any lead.
You need to change the getItemCount() method to this:
#Override
public int getItemCount() {
return list_of_menus.size();
}
The RecyclerView will not display any elements if you are reporting that its size is zero.
Change this:
#Override
public int getItemCount() {
return 0;
}
To this:
#Override
public int getItemCount() {
return list_of_menus.size();
}

How to make two Recyclerview in one Layout

i already success to make one Recyclerview and i want to add new Recyclerview Horizontal on top. i will explain in my code :
<android.support.v7.widget.RecyclerView
android:id="#+id/arrayListUser"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:divider="#color/white">
</android.support.v7.widget.RecyclerView>
<android.support.v7.widget.RecyclerView
android:id="#+id/arrayList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:divider="#color/white">
</android.support.v7.widget.RecyclerView>
id:arrayList is my first Recyclerview have name xml feeds_listview
id:arrayListUser is my new Recyclerview, i want make this Recyclerview Horizontal
xml for new Recylerview is feeds_listviewUser
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/profil"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginBottom="5dp"
android:layout_marginTop="30dp"
android:layout_gravity="center"
android:src="#drawable/cthprofil" />
<TextView
android:id="#+id/fullName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_marginTop="5dp"
android:layout_marginBottom="20"
android:text="Megi Fernanda"
android:textSize="17sp"
android:textColor="#color/colordefault"
android:textStyle="bold" />
</LinearLayout>
and this is my class adapter
public class FeedsCustomAdapter extends RecyclerView.Adapter<FeedsCustomAdapter.ViewHolder> {
private Context context;
private List<FeedsAdapter> feeds_list;
private ArrayList<Feeds> mFeedsList = new ArrayList<Feeds>();
private OnItemClickListener mListener;
private OnItemClickListener mListener2;
public FeedsCustomAdapter(Context context, ArrayList<Feeds> mFeedsList) {
this.context = context;
this.mFeedsList = mFeedsList;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.feeds_listview, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Feeds feed = getFeeds().get(position);
int textColor = context.getResources().getColor(R.color.btn_next);
int textColor2 = context.getResources().getColor(R.color.text_color_black);
holder.fullName.setText(feed.user.fullName);
holder.location.setText(feed.user.location);
holder.topic.setText(Html.fromHtml( "Menyelesaikan Tantangan " + " <font color = '" + String.valueOf(textColor2) + "'>" + feed.topic + "</font>" ) );
Picasso.with(context)
.load(feed.user.avatar)
.into(holder.profile);
PrettyTime prettyTime = new PrettyTime();
String times = prettyTime.format(DateUtil.timeMilisTodate(feed.timestamp * 1000));
holder.times.setText(times);
}
#Override
public int getItemCount() {
return mFeedsList.size();
}
public ArrayList<Feeds> getFeeds() {
return mFeedsList;
}
public void setComplete(int position) {
mFeedsList.get(position).isComplete = 1;
}
public boolean last() {
boolean result = false;
int total = mFeedsList.size();
for (int i = 0; i < mFeedsList.size(); i++) {
if (mFeedsList.get(i).isComplete == 1) {
total--;
}
}
if (total == 1) {
result = true;
}
return result;
}
class ViewHolder extends RecyclerView.ViewHolder {
public TextView fullName;
public TextView location;
public TextView topic;
public ImageView profile;
public TextView times;
public ViewHolder(View itemView) {
super(itemView);
fullName = (TextView) itemView.findViewById(R.id.fullName);
location = (TextView) itemView.findViewById(R.id.location);
topic = (TextView) itemView.findViewById(R.id.topic);
profile = (ImageView) itemView.findViewById(R.id.profil);
times = (TextView) itemView.findViewById(R.id.times);
profile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mListener2 != null){
mListener2.onItemClick2(v ,getPosition());
}
}
});
topic.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mListener != null){
mListener.onItemClick(v ,getPosition());
}
}
});
}
}
public void setClickListener(OnItemClickListener clickListener) {
this.mListener = clickListener;
}
public void setClickListenerProfile(OnItemClickListener clickListener2){
this.mListener2 = clickListener2;
}
public interface OnItemClickListener {
public abstract void onItemClick(View view, int position);
public abstract void onItemClick2(View view, int position);
}
so, in my code i success to display first recylerview with my first xml and i want add new recylerview horizontal with new xml feeds_listviewUser
You can use LinearLayout to wrap both recyclerView.
<android.support.v7.widget.RecyclerView
android:id="#+id/arrayListUser"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#color/white">
</android.support.v7.widget.RecyclerView>
<android.support.v7.widget.RecyclerView
android:id="#+id/arrayList"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:divider="#color/white">
</android.support.v7.widget.RecyclerView>
And assign horizontal layout manager to one recyclerview and vertical layout manager to other
LinearLayoutManager userManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
arrayListUser.setLayoutManager(userManager);
LinearLayoutManager listManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
arrayList.setLayoutManager(listManager);
Put your recyclerviews in Relative layout.
First add horizontal recyclerView to alignParentTop true and fix height according to visibility of feeds_listviewUser next add vertical recyclerView with layout_below horizontal recyclerview id.

Categories

Resources