I used a working RecyclerView as a template for another, but I made some sort of mistake in its implementation and I can't find it. Here is the code that initializes the view:
mMessageThreadList = new ArrayList<>();
mRecyclerView = findViewById(R.id.chat_list_recycler_view);
private void initRecyclerView() {
Log.d(TAG, "initRecyclerView Called");
//Initializes and sets up adapter
mAdapter = new ChatListRecyclerViewAdapter(mThreadList);
mRecyclerView.setAdapter(mAdapter);
Query query = mThreadCollection;
query.addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#Nullable QuerySnapshot queryDocumentSnapshots, #Nullable FirebaseFirestoreException e) {
for (DocumentChange documentChange : queryDocumentSnapshots.getDocumentChanges()) {
switch (documentChange.getType()) {
case ADDED:
Thread thread = documentChange.getDocument().toObject(Thread.class);
Log.d(TAG, "Last Message: " + thread.getLastMessage().getMessage());
mThreadList.add(thread);
mAdapter.notifyDataSetChanged();
}
}
}
});
}
Note that the print log statement in the SnapshotListener does contain a value when printed so the information is returning from Firebase, it's just not displaying. Which makes me think my problem is with my Adapter/Viewholder:
public class ChatListRecyclerViewAdapter extends RecyclerView.Adapter<ChatListRecyclerViewAdapter.ChatListViewHolder> {
private List<Thread> threadList;
ChatListRecyclerViewAdapter(List<Thread> threadList) {
this.threadList = threadList;
}
#NonNull
#Override
public ChatListViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_list_row, parent, false);
return new ChatListViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ChatListViewHolder holder, int position) {
// This method fills fields with data for each list item
Log.d(TAG, "onBindViewholder called");
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MMM hh:mm a");
final Thread thread = threadList.get(position);
char initial = thread.getPartnerName().charAt(0);
char uppercaseInitial = Character.toUpperCase(initial);
Log.d(TAG, thread.getLastMessage() + " " + thread.getPartnerID());
holder.partnerName.setText(thread.getPartnerName());
holder.authorInitial.setText(uppercaseInitial);
holder.lastMessageText.setText(thread.getLastMessage().getMessage());
holder.lastMessageTime.setText(simpleDateFormat.format(thread.getLastMessage().getTimestamp()));
}
#Override
public int getItemCount() {
return threadList.size();
}
//Viewholder stores the information about the layout and content of each list item, and serves as a template for each item of a RecyclerView
public class ChatListViewHolder extends RecyclerView.ViewHolder {
TextView partnerName;
TextView authorInitial;
TextView lastMessageText;
TextView lastMessageTime;
LinearLayout listTextHolder;
public ChatListViewHolder(View itemView) {
super(itemView);
partnerName = itemView.findViewById(R.id.partner_name);
authorInitial = itemView.findViewById(R.id.partner_initial);
lastMessageText = itemView.findViewById(R.id.last_message);
lastMessageTime = itemView.findViewById(R.id.last_message_time);
listTextHolder = itemView.findViewById(R.id.list_text_holder);
}
}
}
chat_list_row.xml file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/single_thread_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:background="#color/colorPrimaryDark">
<TextView
android:id="#+id/partner_initial"
android:background="#drawable/chat_list_circle"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_alignParentStart="true"
android:gravity="center"
android:text="A"
android:textSize="36sp"
tools:ignore="HardcodedText" />
<TextView
android:id="#+id/last_message_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:padding="5dp"
android:fontFamily="#font/nunito_extralight"
android:text="#string/sample_time"
android:textColor="#android:color/darker_gray"
android:textSize="12sp"
android:typeface="normal" />
<LinearLayout
android:id="#+id/list_text_holder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="#id/partner_initial"
android:layout_centerVertical="true"
android:orientation="vertical">
<TextView
android:id="#+id/partner_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginStart="5dp"
android:fontFamily="#font/nunito"
android:text="#string/sample_name"
android:textColor="#color/white"
android:textSize="14sp"
android:textStyle="bold"
android:typeface="sans" />
<TextView
android:id="#+id/last_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:fontFamily="#font/nunito_extralight"
android:gravity="start"
android:text="#string/sample_message"
android:textColor="#android:color/darker_gray"
android:textSize="12sp"
android:typeface="normal" />
</LinearLayout>
</RelativeLayout>
Edit: Layout of the Activity that RecyclerView appears in. I also edit above code to show where the variable is attached to the view:
<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="fill_parent"
android:layout_height="fill_parent"
android:background="#color/colorPrimaryDark"
android:paddingLeft="0dp"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingRight="0dp"
android:paddingBottom="0dp"
tools:context="org.andrewedgar.theo.ChatListActivity">
<include
android:id="#+id/chat_list_toolbar"
layout="#layout/toolbar" />
<android.support.v7.widget.RecyclerView
android:id="#+id/chat_list_recycler_view"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/chat_list_toolbar" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/new_check_in_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:src="#drawable/ic_person_pin_circle_black_24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</android.support.constraint.ConstraintLayout>
Seems like you have missed to add layout manager of RecyclerView. Would you please add this and try again
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
Your recyclerview is not showing any data because the list in adapter is still empty. After fetching data from firebase you are adding to mThreadList, which is still with activity and not adapter. To update the list in adapter you can add a method in adapter class and pass the list to adapter and notifyDataseChanged there.
Activity:
//after firebase task...
mAdapter.updateData(mThreadList);
Adapter: add new method
void updateData(List<Thread> threadList){
this.threadList = threadList;
notifyDatasetChanged(); //notify adapter that new list is added
}
Related
I am trying to show the items into Recycler View in Grid Layout Manager.
My list item xml file is
<?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"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.v7.widget.CardView
app:cardElevation="3dp"
app:cardUseCompatPadding="true"
app:cardCornerRadius="10dp"
android:layout_margin="10dp"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="#+id/cardView">
<LinearLayout
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:id="#+id/itemLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="#+id/iv_icon"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginBottom="3dp"
android:layout_marginLeft="1dp"
android:layout_marginRight="1dp"
android:layout_marginTop="10dp"
android:adjustViewBounds="true"
android:paddingBottom="5dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:scaleType="fitCenter"
android:src="#mipmap/health_2" />
<TextView
android:id="#+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:ellipsize="end"
android:ems="5"
android:gravity="center"
android:lines="2"
android:maxEms="5"
android:maxLines="2"
android:text="Health" />
</LinearLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>
And my code snippet is :
MainActivity :
mLayoutManager = new GridLayoutManager(MainActivity.this, 3);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(mLayoutManager);
adapter = new MyAdapter (MainActivity.this,
arrayList);
recyclerView.setAdapter(adapter);
MyAdapter :
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
model = arraylist.get(position);
holder.itemIcon.setImageResource(model.getIconName());
}
I am setting the icon name to model for the list in this way :
model.setIconName(R.mipmap.health_2);
Model Class :
public class DashBoardModel {
String itemName;
int iconName;
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public int getIconName() {
return iconName;
}
public void setIconName(int iconName) {
this.iconName = iconName;
}
}
My question is after doing these things , i am getting the output list as shown in the image below which is not the expected icon to be seen, How to resolve this ?
you could use the glide library com.github.bumptech.glide:glide:+ to dynamically load the icons into the image view, like so:
//assuming the getIconName method return an int, i.e R.mipmap.whatever
Glide.with(mContext).load(model.getIconName()).into(holder.itemIcon);
I have this same issue. Although I don't know why setting the image from the adapter doesn't work, I resolved it by posting a callback on ImageView's Handler.
#Override
fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
holder.itemIcon.post {
holder.itemIcon.setImageResource(...)
}
}
Am having a doubt regarding how to make the horizontal view to touch the textview while populating in recyclerview , Now let me explain briefly i having a horizontal recyclerview in that adapter view holder i have horizontal view at the end of the textview which is center vertical to that textview, so when items are added each view must touch the textview like vertical dotted timeline but the view is not touching the textview as shown in the below image.
Now let me post what i have tried so far
This is the layout that holding recyclerview:
<RelativeLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android" >
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/recyclerview"/>
</RelativeLayout>
Here am using that recyclerview in activity:
Recyclerview recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
recyclerView.setHasFixedSize(true);
TrackingAdapter mAdapter = new TrackingAdapter(this.taskLogModelList,mTaskModel.getTaskID(),fm,String.valueOf(mLastLocation.getLatitude()),String.valueOf(mLastLocation.getLongitude()));
recyclerView.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
Here is the adapter am using :
public class TrackingAdapter extends RecyclerView.Adapter<TrackingAdapter.ViewHolder> {
private List<TaskLogModel> taskStatusFlowModels;
private D2DKnocks appclass;
private String Lat,Long;
private FragmentManager fragmentManager;
private String TaskID;
DateFormat date,msimpleDateformat;
public TrackingAdapter(List<TaskLogModel> taskStatusFlowModels,String TaskID,FragmentManager context,String Lat,String Long) {
this.taskStatusFlowModels = taskStatusFlowModels;
this.fragmentManager=context;
date=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
msimpleDateformat = new SimpleDateFormat("hh.mm a");
this.Lat=Lat;
this.TaskID=TaskID;
this.Long=Long;
appclass=((D2DKnocks)D2DKnocks.getContext());
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private AvertaTextview txt_time;
private Rubik txt_delivered;
// private AvertaButton btn_start;
private RelativeLayout layout;
private View view_right;
public ViewHolder(View itemView) {
super(itemView);
txt_time = itemView.findViewById(R.id.txt_time);
// btn_start=itemView.findViewById(R.id.start);
layout=itemView.findViewById(R.id.layout);
txt_delivered = itemView.findViewById(R.id.txt_delivered);
view_right = (View) itemView.findViewById(R.id.right_view_line);
layout.setOnClickListener(this);
}
#Override
public void onClick(View view) {
TaskLogModel taskLogModel=taskStatusFlowModels.get(getAdapterPosition());
if(taskLogModel.getTaskStatusID()==0){
TaskStatusDialog taskStatusDialog=new TaskStatusDialog();
Bundle bundle=new Bundle();
bundle.putInt("Size",taskStatusFlowModels.size());
bundle.putString("Lat",Lat);
bundle.putString("Long",Long);
bundle.putString("TaskID",TaskID);
taskStatusDialog.setArguments(bundle);
taskStatusDialog.show(fragmentManager,"show");
}
}
}
#Override
public TrackingAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_view_assignment_status, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(TrackingAdapter.ViewHolder holder, int position) {
if (taskStatusFlowModels.get(position).getTaskStatusID() > 0) {
StatusModel statusFlowModel = getStatusName(taskStatusFlowModels.get(position).getTaskStatusID());
holder.txt_delivered.setText(statusFlowModel.getStatus());
holder.txt_delivered.setBackgroundResource(R.drawable.btn_arrived_bg);
try {
Date uppdateDate=date.parse(taskStatusFlowModels.get(position).getUpdateDateTime());
String updatedDate=msimpleDateformat.format(uppdateDate);
String[] each = updatedDate.split(" ");
String str = each[1].replace("AM", "am").replace("PM","pm");
// SpannableString ss1= new SpannableString(each[0]);
// SpannableString ss2=new SpannableString(each[1]);
// ss1.setSpan(new AbsoluteSizeSpan(20), 0, each[0].length(), SPAN_INCLUSIVE_INCLUSIVE);
// ss2.setSpan(new AbsoluteSizeSpan(15), 0, each[1].length(), SPAN_INCLUSIVE_INCLUSIVE);
// CharSequence finalText = TextUtils.concat(ss1, " ", ss2);
holder.txt_time.setText(each[0]+" "+str);
} catch (ParseException e) {
e.printStackTrace();
}
GradientDrawable gradientDrawable = (GradientDrawable) holder.txt_delivered.getBackground();
gradientDrawable.setColor(Color.parseColor(statusFlowModel.getStatusColor()));
} else {
holder.txt_delivered.setText("Choose");
holder.txt_delivered.setBackgroundResource(R.drawable.btn_choose_bg);
holder.txt_delivered.setTextColor(Color.parseColor("#b1b1b1"));
}
if(taskStatusFlowModels.size()-1==position){
holder.view_right.setVisibility(View.GONE);
}
else {
holder.view_right.setVisibility(View.VISIBLE);
}
}
public StatusModel getStatusName(Integer statusID){
for (int i=0;i<appclass.getStatusModelist().size();i++){
if (appclass.getStatusModelist().get(i).getStatusID().equals(statusID)){
return appclass.getStatusModelist().get(i);
}
}
return null;
}
#Override
public int getItemCount() {
return taskStatusFlowModels.size();
}
}
And below is the view holder layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="vertical">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/layout">
<com.trident.Hawkersky.service.CustomFonts.AvertaTextview
android:id="#+id/txt_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:drawableLeft="#drawable/ic_checked"
android:drawablePadding="10dp"
android:layout_centerHorizontal="true"
android:gravity="center"
android:text="10.00 am"
android:textColor="#444444"
android:textSize="12sp"
/>
<View
android:id="#+id/vertical_line"
android:layout_width="30dp"
android:layout_height="20dp"
android:layout_centerHorizontal="true"
android:layout_below="#+id/txt_time"
android:background="#drawable/vertical_dotted_line"
android:layerType="software"
android:visibility="visible" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_below="#+id/vertical_line"
android:layout_height="wrap_content">
<com.trident.Hawkersky.service.CustomFonts.Rubik
android:id="#+id/txt_delivered"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="#dimen/thirty"
android:layout_marginBottom="5dp"
android:singleLine="true"
android:padding="#dimen/seven"
android:background="#drawable/btn_delivered_bg"
android:gravity="center"
android:text="Delivered"
android:textAllCaps="true"
android:textColor="#FFF"
android:textSize="13sp"
android:textStyle="bold" />
<View
android:id="#+id/right_view_line" <--- this is the view
android:layout_width="#dimen/hundred"
android:layout_height="5dp"
android:layout_alignBottom="#+id/txt_delivered"
android:layout_gravity="center_vertical"
android:layout_marginBottom="12dp"
android:layout_toEndOf="#+id/txt_delivered"
android:layout_toRightOf="#+id/txt_delivered"
android:background="#drawable/dotted"
android:layerType="software"
android:visibility="visible" />
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
Now what i need is i need that view to attach to the textview , but am getting like image above how to solve it.
Please try this and let know if you need further modifications.
<?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"
android:id="#+id/layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="vertical">
<com.trident.Hawkersky.service.CustomFonts.AvertaTextview
android:id="#+id/txt_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginLeft="5dp"
android:layout_marginStart="5dp"
android:drawableLeft="#drawable/ic_checked"
android:drawablePadding="10dp"
android:gravity="center"
android:text="10.00 am"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="#+id/txt_delivered"
app:layout_constraintRight_toRightOf="#+id/txt_delivered"
android:textColor="#444444"
android:textSize="12sp"
/>
<View
android:id="#+id/vertical_line"
android:layout_width="30dp"
android:layout_height="20dp"
app:layout_constraintLeft_toLeftOf="#+id/txt_delivered"
app:layout_constraintRight_toRightOf="#+id/txt_delivered"
android:layout_below="#+id/txt_time"
android:layout_centerHorizontal="true"
app:layout_constraintTop_toBottomOf="#+id/txt_time"
android:background="#color/colorPrimaryDark"
android:layerType="software"
android:visibility="visible"/>
<com.trident.Hawkersky.service.CustomFonts.Rubik
android:id="#+id/txt_delivered"
android:layout_width="wrap_content"
android:layout_height="#dimen/thirty"
android:layout_marginBottom="5dp"
android:background="#drawable/btn_delivered_bg"
android:gravity="center"
app:layout_constraintTop_toBottomOf="#+id/vertical_line"
android:padding="#dimen/seven"
android:singleLine="true"
android:text="Delivered"
android:textAllCaps="true"
android:textColor="#FFF"
android:textSize="13sp"
android:textStyle="bold"/>
<View
android:id="#+id/right_view_line"
android:layout_width="100dp"
android:layout_height="5dp"
app:layout_constraintTop_toTopOf="#+id/txt_delivered"
app:layout_constraintBottom_toBottomOf="#+id/txt_delivered"
app:layout_constraintLeft_toRightOf="#+id/txt_delivered"
android:background="#drawable/dotted"
android:layerType="software"
android:visibility="visible"/>
</android.support.constraint.ConstraintLayout>
Sorry, I had to use ConstraintLayout. If you haven't been using it before, please add this implementation 'com.android.support.constraint:constraint-layout:1.0.2'1 to your module level build.gradle.
I've followed a few different docs to pull together my first Firebase Recycler View:
The two main ones:
Here and here.
I'm using a Message object (included further down) with the Firebase Recycler View. For some reason the data is not displaying. Judging from my log outputs, nothing in the adaptor is being called. Here is the activity code that sits in my onCreate():
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_message_details);
RecyclerView mRecyclerView;
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
Query query = myMessagesRef.child(RoomID)
.orderByKey()
.limitToLast(50);
FirebaseRecyclerOptions<Message> options =
new FirebaseRecyclerOptions.Builder<Message>()
.setQuery(query, Message.class)
.build();
FirebaseRecyclerAdapter adapter = new FirebaseRecyclerAdapter<Message, ChatHolder>(options) {
#Override
public ChatHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// Create a new instance of the ViewHolder, in this case we are using a custom
// layout called R.layout.message for each item
final View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recycler_item, parent, false);
return new ChatHolder(view);
}
#Override
protected void onBindViewHolder(ChatHolder holder, int position, Message model) {
//super.onBindViewHolder(holder, position);
Log.w(TAG, "Some Info on messages 2 " + model.MessageText);
holder.bindChat(model);
}
};
mRecyclerView.setAdapter(adapter);
}
Here is my ViewHolder:
static class ChatHolder extends RecyclerView.ViewHolder{
TextView mtext;
//Context mContext;
public ChatHolder(View v) {
super(v);
mtext = (TextView) v.findViewById(com.example.administrationuser.piclo.R.id.textView13);
}
public void bindChat(Message mess){
mtext.setText(mess.MessageText);
}
}
Here is my Message object that I am passing to both Firebase and the adaptor (the data that I input syncs to Firebase with no issue, and my query to firebase gets the data in correct format):
public static class Message {
public String UserID;
public String UserName;
public String MessageText;
public Message() {} // Needed for Firebase
public Message(String UserID, String UserName, String MessageText) {
this.UserID = UserID;
this.UserName = UserName;
this.MessageText = MessageText;
}
}
Here is my Activity Layout XML (with name: activity_message_details.xml):
(note the recycler view near the bottom):
<?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="com.example.administrationuser.piclo.MessageDetails">
<LinearLayout
android:layout_width="395dp"
android:layout_height="643dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:orientation="vertical"
tools:layout_editor_absoluteY="8dp"
tools:layout_editor_absoluteX="8dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="150dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<EditText
android:id="#+id/editText3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:text="Name"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<Button
android:id="#+id/button9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="Button"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:onClick="onClick"/>
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawSelectorOnTop="false"
/>
</LinearLayout>
</android.support.constraint.ConstraintLayout>
Finally, here is my View layout XML (with name: recycler_item.xml):
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView13"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView" />
</FrameLayout >
There were two things that needed fixing.
1) Adding in the adapter.startListening(); (as mentioned by Elvin No Matter). In my case I added this just below the mRecyclerView.setAdapter(adapter); near the end of my onCreate.
2) Enclosing my View Layout XML in a <android.support.v7.widget.LinearLayoutCompat>. See my new View Holder, with some other irrelevant changes to the buttons:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.LinearLayoutCompat
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="wrap_content"
android:layout_height="wrap_content"
>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp">
<TextView
android:id="#+id/textView13"
android:layout_width="285dp"
android:layout_height="24dp"
android:text="TextView"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:layout_editor_absoluteX="-6dp" />
<TextView
android:id="#+id/textView14"
android:layout_width="123dp"
android:layout_height="24dp"
android:layout_alignParentTop="true"
android:layout_marginRight="8dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="#+id/textView13"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="154dp" />
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.LinearLayoutCompat>
according to readme
The FirestoreRecyclerAdapter uses a snapshot listener to monitor
changes to the Firestore query. To begin listening for data, call the
startListening() method. You may want to call this in your onStart()
method. Make sure you have finished any authentication necessary to
read the data before calling startListening() or your query will fail.
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
and
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
Fragment has ViewPager, in ViewPager we are swiping between two fragments(let's name it sub-fragment). And first and second sub-fragment has got RecyclerView.
I doesn't know what's going on because I've create RecyclerView exactly in the same way in other fragment and It is workking well.
recycler_view_item: (I'm sure that this item is appriopriate and its ids are compatible with Adapter class
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorHeaderText"
android:weightSum="100"
android:layout_marginBottom="4dp"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp">
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="20"
android:weightSum="50">
<TextView
android:text="Client"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:id="#+id/textView8"
android:layout_weight="15"
style="#style/ItemPaymentsHeaderTextView"
/>
<TextView
android:text="TextView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="#+id/clientinfo_item_client"
android:layout_weight="35"
style="#style/ItemPaymentsInfoTextView"/>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="25"
android:weightSum="50">
<TextView
android:text="Date"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:id="#+id/textView13"
android:layout_weight="15"
style="#style/ItemPaymentsHeaderTextView"
/>
<TextView
android:text="TextView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="#+id/clientinfo_item_date"
android:layout_weight="35"
style="#style/ItemPaymentsInfoTextView"/>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="27"
android:weightSum="50">
<TextView
android:text="Payment amount"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:id="#+id/textView9"
android:layout_weight="15"
style="#style/ItemPaymentsHeaderTextView"
/>
<TextView
android:text="TextView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="#+id/clientinfo_item_totalamount"
android:layout_weight="35"
style="#style/ItemPaymentsInfoTextView"/>
</LinearLayout>
<!--TODO jak bedzie po wszystkim to wyrzucic TYP ( określony w TabLayout)-->
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="20"
android:weightSum="50">
<TextView
android:text="Type"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:id="#+id/textView10"
android:layout_weight="15"
style="#style/ItemPaymentsHeaderTextView"
/>
<TextView
android:text="Purchase"
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="#+id/clientinfo_item_type"
android:layout_weight="35"
style="#style/ItemPaymentsInfoTextView"/>
</LinearLayout>
<ImageButton
android:layout_width="0dp"
android:layout_height="wrap_content"
app:srcCompat="#drawable/arrow_expand_24"
android:id="#+id/clientinfo_item_downarrow"
android:background="#color/icon_transparent"
android:layout_weight="5"
android:scaleType="fitCenter"
android:elevation="0dp"
android:layout_gravity="center_vertical|clip_horizontal"/>
FrameLayout that contain ViewPager and TabLayout
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.debtors.Fragments.FragmentSingleClientInfo">
<android.support.design.widget.TabLayout
android:id="#+id/clientsinfo_tabs"
style="#style/CategoryTab"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v4.view.ViewPager
android:id="#+id/clientsinfo_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
onCreateView - method where I create RecyclerView
listOfPayments that I am passing to AdapterClientInfo is not null.
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
listOfPayments = getPaymentsByClientId(clientsID);
for( Payment p : listOfPayments ){
Log.i(TAG, "onCreateView: payment : " + p.toString(true));
}
View rootView = inflater.inflate(R.layout.recycler_view_with_viewpager,container, false);
AdapterClientInfo adapterClientInfo = new AdapterClientInfo(getContext(),listOfPayments);
RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view_with_viewpager);
setupRecyclerView(recyclerView);
recyclerView.setAdapter(adapterClientInfo);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
return rootView;
}
In above method I inflate layout.recycler_view_with_viewpager:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingTop="55dp"
android:id="#+id/recycler_view_with_viewpager"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
And in AdapterClientInfo only constructor is calling while creating instance and any of other method doesn't work, nothing is called.
AdapterClientInfo:
public class AdapterClientInfo extends RecyclerView.Adapter<AdapterClientInfo.MyViewHolder> {
private static final String TAG = AdapterClientInfo.class.getSimpleName();
List<Payment> listOfPayments = new ArrayList<>();
Context context;
public AdapterClientInfo(Context context, List<Payment> list) {
Log.i(TAG, "AdapterClientInfo: ");
this.context = context;
this.listOfPayments = list;
Log.i(TAG, "AdapterClientInfo: size of list : " + list.size());
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Log.i(TAG, "onCreateViewHolder: ");
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_clients_info_payments, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Log.i(TAG, "onBindViewHolder: START");
Payment payment = listOfPayments.get(position);
Log.i(TAG, "onBindViewHolder: payment " + payment.toString());
String clientName = getClientByID(payment.getPaymentClientID()).getClientName();
String[] dateArray = payment.getPaymentDate().split(" ");
String dateString = dateArray[0];
holder.textViewClient.setText(clientName);
holder.textViewDate.setText(dateString);
holder.textViewPaymentAmount.setText(String.valueOf(payment.getPaymentAmount()));
if(payment.isPaymentGotOrGiven())//if tru
holder.textViewType.setText("Received");
else
holder.textViewType.setText("Given");
Log.i(TAG, "onBindViewHolder: END");
}
#Override
public int getItemCount() {
Log.i(TAG, "getItemCount: " + listOfPayments.size());
return listOfPayments.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView textViewClient, textViewPaymentAmount, textViewDate, textViewType;
public MyViewHolder(View itemView) {
super(itemView);
Log.i(TAG, "MyViewHolder: ");
textViewClient = (TextView) itemView.findViewById(R.id.clientinfo_item_client);
textViewPaymentAmount = (TextView) itemView.findViewById(R.id.clientinfo_item_totalamount);
textViewDate = (TextView) itemView.findViewById(R.id.clientinfo_item_date);
textViewType = (TextView) itemView.findViewById(R.id.clientinfo_item_type);
}
}
private Client getClientByID(long ID){
DatabaseClients dbClients = new DatabaseClients(context);
Client client = dbClients.getClientByID(ID);
return client;
}
}
I'm sure that listOfPayments's size is more than 0 so getItemCount return more than zero
Logs show that only Constructor is calling
I think that it is simple mistake but I can't notice that...
Problem was causing by method in ViewPagerAdapter. I don't know if it was autogenerated, I copied it accidentally or .. I don't know but deleting this method helped.
#Override
public boolean isViewFromObject(View view, Object object) {
return false;
}
In my project i have a recycler view which contains a text view in every row. when i select a text view in a row text views in some random rows are also selected and also whatever is typed into it, it is also showing in those rows.Here is my code.
onBindViewHolder
public void onBindViewHolder(final MainContentViewHolder holder, int position) {
Log.e("Sony","onBindViewHolder");
Item currentItem = items.get(position);
if (currentItem.imageURL != null) {
imageLoader.get(currentItem.imageURL, new ImageLoader.ImageListener() {
#Override
public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
Log.e("Sony","onResponseImage");
holder.itemImage.setImageBitmap(response.getBitmap());
}
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Sony","onErrorImage");
holder.itemImage.setImageResource(R.drawable.default_product);
}
});
}
//holder.itemImage.setImageBitmap(BitmapFactory.decodeStream((InputStream) new URL().getContent());
holder.itemPrice.setText(currentItem.price + "");
holder.itemName.setText(currentItem.itemName);
}
ViewHolder
public MainContentViewHolder(View itemView) {
super(itemView);
itemImage = (ImageView) itemView.findViewById(R.id.imgItemPic);
itemName = (TextView) itemView.findViewById(R.id.lblItemName);
itemPrice = (TextView) itemView.findViewById(R.id.lblItemPrice);
txtQty = (EditText) itemView.findViewById(R.id.txtQty);
btnAddToCart = (Button) itemView.findViewById(R.id.btnAddToCart);
btnAddToCart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Item item = items.get(getPosition());
CartMessageHandler.showToastMessage(context, item.itemName + " : " + item.price, Toast.LENGTH_LONG);
}
});
}
activity onCreate
mainListView = (RecyclerView) findViewById(R.id.recyclerList);
mainListView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));
recyclerViewListAdapter = new MainContentRecyclerAdapter(this);
mainListView.setAdapter(recyclerViewListAdapter);
getData("fruits%20&%20vegetables");
mainListView.setLayoutManager(new LinearLayoutManager(this));
Custom Row for recyclerView
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/cardItemHolderRoot"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/imgItemPic"
android:layout_width="#dimen/itemImageDimen"
android:layout_height="#dimen/itemImageDimen"
android:layout_centerVertical="true"
android:contentDescription="#string/productImage"
android:src="#drawable/default_product"
android:elevation="2dp"
android:focusableInTouchMode="false"
android:layout_marginTop="#dimen/loginWidgetTopMargin" />
<LinearLayout
android:layout_toRightOf="#+id/imgItemPic"
android:paddingLeft="10dp"
android:id="#+id/cardItemHolder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/lblItemName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/loginWidgetTopMargin"
android:text="Item Name"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/lblItemPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/loginWidgetTopMargin"
android:text="Rs.250"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#color/primaryColor" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/loginWidgetTopMargin"
android:orientation="horizontal">
<TextView
android:id="#+id/lblItemQty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="#string/quantity"
android:textAppearance="?android:attr/textAppearanceSmall" />
<EditText
android:id="#+id/txtQty"
android:layout_width="75dp"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="number" />
</LinearLayout>
<Button
android:id="#+id/btnAddToCart"
android:layout_width="wrap_content"
android:layout_marginLeft="5dp"
android:layout_height="wrap_content"
android:drawableLeft="#drawable/cart_a16"
android:text="#string/addToCart" />
</LinearLayout>
what is wrong in my code? Can anyone suggest a way to fix this
RecyclerView reuses row views that was created earlier. That's why you see earlier typed text in random rows of your RecyclerView: you simply don't reset row view stuff state in onBindViewHolder.
So to avoid bug you should reset components state in onBindViewHolder: clear txtQty and etc. In case of expensive or heavyweight data documentation is recommended releasing this data with setRecyclerListener(..).