Adapter only shows the first item [duplicate] - android

I am facing a strange error where recyclerview is showing only a single item. Below is code for my recyclerview adapter :
public class ChatAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
List<chat> chats;
String username;
final int My=0,Their=1;
public ChatAdapter(List<chat> chats) {
this.chats = chats;
this.username = PushApp.getApp().getSPF().getStringData(Constants.ANAME);
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder;
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType) {
case My:
View v1 = inflater.inflate(R.layout.my_chat_child, parent, false);
viewHolder = new MyChatHolder(v1);
break;
case Their:
View v2 = inflater.inflate(R.layout.their_chat_child, parent, false);
viewHolder = new TheirMessageHolder(v2);
break;
default:
View v = inflater.inflate(R.layout.my_chat_child, parent, false);
viewHolder = new MyChatHolder(v);
break;
}
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case My:
MyChatHolder myChatHolder = (MyChatHolder) holder;
myChatHolder.setMyMessage(chats.get(position).getMessage());
break;
case Their:
TheirMessageHolder theirMessageHolder = (TheirMessageHolder) holder;
theirMessageHolder.setTheirChat(chats.get(position).getFrom(), chats.get(position).getMessage());
break;
}
}
#Override
public int getItemViewType(int position) {
if(username.equalsIgnoreCase(chats.get(position).getFrom()))
return My;
return Their;
}
#Override
public int getItemCount() {
return chats.size();
}}
I have already used this code in other app and its working perfectly. I have checked the chats data which is also perfect.
Here's link to git repo layout files:
layout files

Don't use match_parent for height for your item view. One item fills whole screen vertically so you don't see another.

when you are creating row.xml for recyclerview should follow these things:
Always use "wrap_content" for the height of the row otherwise in "match_parent" it will occupy the whole screen for a single row.
You can also take the height in dp.

My mistake was I accidentally used:
LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
instead of:
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)

content_main.xml as follows
android:layout_width="match_parent"
android:layout_height="match_parent"
IN row_list.xml file make following changes
android:layout_width="match_parent"
android:layout_height="wrap_content"
I make above changes it runs.

Try changing the layout used in your item view to FrameLayout. Here is an example.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/item"
android:layout_width="match_parent"
android:layout_height="?listPreferredItemHeight"
android:clickable="true"
android:focusable="true"
android:foreground="?selectableItemBackground">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"/>
</FrameLayout>

After checking the log make sure multiple items are added in the list but in UI its showing only 1 item means check this properties.
In item_xml file change property to
Correct Approach
android:layout_width="match_parent"
android:layout_height="wrap_content"
wrong Approach
android:layout_width="match_parent"
android:layout_height="match_parent"

I have this issue today, and after 1001 minutes, I find out this come from this line inside RecyclerView:
android:layout_marginTop="10dp"
My RecyclerView was put inside NestedScrollView, I think that is the indirect cause.
So I put here for anyone else meet the same issue. here the image

1) if your recyclerview is vertical then set height of recyclerview match_parent and row_item.xml height also match_parent
2) if your recyclerview is horizontal then set Width of recyclerview match_parent and row_item.xml Width also match_parent
for ex:-
Horizontal RecyclerView
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="60dp"
android:layout_marginRight="60dp" />
row_item.xml
<TextView
android:layout_width="match_parent"
android:layout_height="180dp"
android:layout_marginBottom="5dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="5dp"
android:background="#drawable/rect"
android:gravity="center"
android:maxLines="2"
android:padding="10dp"
android:textColor="#color/white"
android:textSize="25sp" />

Related

View.GONE leaves empty space

I get 2 types of data with Firebase and with RadioButton I sort the displayed data. Everything seems to work, but still there is an empty space when one of the data types is hidden. Tell me how to hide / show data correctly.
That's what I get
Adapter:
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int
viewType) {
switch (viewType) {
case Person.PersonType.TYPE_1:
View userType1 = LayoutInflater.from(parent.getContext())
.inflate(R.layout.driver_row, parent, false);
return new PersonType1ViewHolder(userType1);
case Person.PersonType.TYPE_2:
View userType2 = LayoutInflater.from(parent.getContext())
.inflate(R.layout.fare_row, parent, false);
return new PersonType2ViewHolder(userType2);
}
return super.onCreateViewHolder(parent, viewType);
}
#Override
protected void populateViewHolder(RecyclerView.ViewHolder viewHolder,
Person model,
int position) {
if (viewHolder instanceof PersonType1ViewHolder) {
((PersonType1ViewHolder) viewHolder).time.setText("Full time: " +
model.getTime());
if (activate) {
viewHolder.itemView.setVisibility(View.GONE);
} else {
viewHolder.itemView.setVisibility(View.VISIBLE);
}
return;
}
if (viewHolder instanceof PersonType2ViewHolder) {
((PersonType2ViewHolder) viewHolder).time.setText("Full time2: " +
model.getTime());
if (activate2) {
viewHolder.itemView.setVisibility(View.GONE);
} else {
viewHolder.itemView.setVisibility(View.VISIBLE);
}
private class PersonType1ViewHolder extends RecyclerView.ViewHolder {
TextView time;
PersonType1ViewHolder(View itemView) {
super(itemView);
time = itemView.findViewById(R.id.tv_time);
}
}
private class PersonType2ViewHolder extends RecyclerView.ViewHolder {
TextView time;
PersonType2ViewHolder(View itemView) {
super(itemView);
time = itemView.findViewById(R.id.tv_time_two);
}
}
Row layouts are the same - wrap_content
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
MainActivity XML
<RelativeLayout 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="wrap_content"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv_trip_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#id/radio_button_group" />
<Button
android:id="#+id/add_trip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:onClick="addTrip"
android:text="add" />
<RadioGroup
android:id="#+id/radio_button_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#id/add_trip"
android:layout_centerHorizontal="true"
android:orientation="horizontal">
<RadioButton
android:id="#+id/rb_all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="all" />
<RadioButton
android:id="#+id/rb_driver"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="driver" />
<RadioButton
android:id="#+id/rb_fare"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="fare" />
</RadioGroup>
</RelativeLayout>
I don’t know how correct this is, but I just programmatically set the parameters
viewHolder.itemView.setLayoutParams(new RecyclerView.LayoutParams(0, 0));
I also encountered issue like this, turns out it's the problem with the override method getItemCount() in the adapter. I guess if you specified the number of getItemCount(), RecyclerView will reserve a place for the ViewHolder even if you hide it. This is the code of how i solve it.
override fun getItemViewType(position: Int): Int {
when {
!importantImages.isNullOrEmpty() && !otherImages.isNullOrEmpty() -> {
return when (position) {
0 -> Important.ordinal
else -> Other.ordinal
}
}
otherImages.isNullOrEmpty() -> {
return Important.ordinal
}
importantImages.isNullOrEmpty() -> {
return Other.ordinal
}
}
return 0
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (ViewType.values()[viewType]) {
Important -> {
val layoutInflater = LayoutInflater
.from(parent.context)
.inflate(R.layout.layout_important_list, parent, false)
ImportantViewHolder(layoutInflater)
}
Other -> {
val layoutInflater = LayoutInflater
.from(parent.context)
.inflate(R.layout.layout_other_list, parent, false)
OtherViewHolder(layoutInflater)
}
}
}
override fun getItemCount(): Int = when {
!importantImages.isNullOrEmpty() && !otherImages.isNullOrEmpty() -> {
2
}
importantImages.isNullOrEmpty() && otherImages.isNullOrEmpty() -> {
0
}
else -> {
1
}
}
Hope it helps! :)
I have this problem too, I found that if add a container outside with wrap_content, then it works.
<FrameLayout 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="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/v_root"
android:layout_width="match_parent"
android:layout_height="48dp">
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
In java code:
v_root.setVisibility(View.GONE);
v_root in code means your old view root.
1.Why does it happen?
viewHolder.itemView.setVisibility(View.GONE); This will not work in RecyclerView.
itemView is a child view in RecyclerView. Unlike the other ViewGroup (FrameLayout,etc), RecyclerView ignores childen's visibility during layout process.
2.How to solve it?
Option1 Use a regular view group such as FrameLayout to wrap your real layout, and hide your real layout: findViewById(R.id.layout_to_hide).setVisibility(View.GONE)
<FrameLayout android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout android:id="#+id/layout_to_hide"
android:layout_width="match_parent"
android:layout_height="wrap_content">
//Put here your views
</LinearLayout>
</FrameLayout>
Option2 Change the itemView’s heigh to 0 so we can't see it
holder.itemView.setLayoutParams(new RecyclerView.LayoutParams(0, 0));
Option3 If this item shouldn't be in List, then simply don't let it in adapter data, or remove it.
3.Learn more
1. Why the other view group such as FrameLayout works fine with children's visibibilty?
They don't compute the child's layout params if it's GONE
2. Why RecyclerView doesn't?
RecyclerView still compute the child's layout params if it's GONE so it still occupies spaces.
The question is not very clear.
But I can assure you that with View.GONE, the view becomes invisible without leaving spaces. While with View.INVISIBLE, the view leaves an invisible space.
If it doesn't work, it means that something is wrong with your layout.

How do I not recycle only the first 2 views of my recyclerview or any items?

I am using a recyclerview for displaying and broadcasting videos of users. However, when I scroll through the recycler view, I see my first view, which has my video gets recycled hence why it's not visible to other users. Is there a way I can make sure that the first view is not recycled so I dont have to worry about my video view getting resetrecycled every single time I scroll through my list?
Here's my code :
In my fragment...
...
<android.support.v7.widget.RecyclerView
android:id="#+id/videoList"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="invisible"
app:layout_constraintBottom_toTopOf="#+id/myButtonContainer"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/myoldContainer">
...
and the corresponding adapter...
public class GroupAdapter extends RecyclerView.Adapter<GroupAdapter.myViewHolder> {
private CopyOnWriteArrayList<Person> persons;
private Context mContext;
public GroupAdapter(#NonNull final CopyOnWriteArrayList<Person> persons , Context context) {
this.persons = persons;
this.mContext= context;
for (Person person : this.persons) {
//get names
}
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View layout = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_person, parent, false);
final MyViewHolder viewHolder = new MyViewHolder(layout);
return viewHolder;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
final Person person = person.get(position);
final Participant participant = person.getParticipant();
if (person.getName() != null) {
holder.personName.setText(person.getName());
}
if (person.getImage() != null) {
holder.personImage.setImageBitmap(person.getImage());
} else {
holder.personImage.setImageResource(R.drawable.default_profile);
}
holder.personImage.setVisibility(View.INVISIBLE);
holder.personImage.setVisibility(View.VISIBLE);
final VideoView videoView;
if (participant.isMe) {
videoView = participant.videoStreamer.videoView;
} else {
videoView = participant.videoPlayer.videoView;
}
if (holder.personVideo.getChildCount() != 0) {
holder.personVideo.removeAllViews();
}
if (videoView.getParent() != null) {
ViewGroup parent = (ViewGroup) videoView.getParent();
parent.removeView(videoView);
}
holder.personVideo.addView(videoView, myViewHolder.videoLayoutParams);
if (person.isVideoPaused()) {
holder.personVideo.setVisibility(View.INVISIBLE);
holder.personImage.setVisibility(View.VISIBLE);
} else {
holder.personVideo.setVisibility(View.VISIBLE);
holder.personImage.setVisibility(View.INVISIBLE);
}
}
#Override
public int getItemCount() {
return persons.size();
}
public static final class MyViewHolder extends RecyclerView.ViewHolder {
#BindView(R.id.personVideo)
public ViewGroup personVideo;
#BindView(R.id.personImage)
public ImageView personImage;
#BindView(R.id.personName)
public TextView personName;
protected static FrameLayout.LayoutParams videoLayoutParams = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
);
public MyViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
Here's how I am setting it in my fragment:
LinearLayoutManager manager = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
videoAdapter = new VideoAdapter(myHelper.getPeople(), getContext());
videoList.setLayoutManager(manager);
videoList.setAdapter(videoAdapter);
item_person:
<?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"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="0dp"
android:background="#drawable/person_border"
xmlns:app="http://schemas.android.com/apk/res-auto">
<RelativeLayout
android:id="#+id/personContainer"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent">
<FrameLayout
android:id="#+id/personVideo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/black" />
<ImageView
android:id="#+id/personImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/black"
android:src="#drawable/default_profile" />
<TextView
android:id="#+id/personName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#AA555555"
android:gravity="center_horizontal|bottom"
android:textColor="#color/green"
android:textSize="12sp"
android:lines="1"
android:ellipsize="end"
tools:text="androiduser#gmail.com"
android:layout_alignParentBottom="true" />
</RelativeLayout>
</android.support.constraint.ConstraintLayout>
fragment with recycle view: xml
<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">
<RelativeLayout>
....
</RelativeLayout>
<include containers>...</include>
...
<android.support.v7.widget.RecyclerView
android:id="#+id/personList"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="invisible"
>
</android.support.v7.widget.RecyclerView>
</android.support.constraint.ConstraintLayout>
I don't think that "not recycling" the video view will actually stop it from being destroyed when you scroll. It's not the recycling is the problem but the view unbinding.
I think such complex component such as VideoView should not be inside the RecyclerView at all.. You can try adding it as a static content on top, which most likely will solve the issue. You can use a NestedScrollView for that. Take a look here: Recyclerview inside scrollview- How to scroll whole content?
If you still think you want to keep it in the RecyclerView and disable the recycling, do the following.
Create a separate view type for your video view items. Here is an example:
https://stackoverflow.com/a/26573338/3086818. Treat your video view item as a header view from the example.
Once you do this, there is a RecycledViewPool class which manages the recycling of items inside a RecyclerView. You can tell it which views to recycle and which not. By default it recycles all views. To disable recycling for your video view items use your new view type like this:
recyclerView.getRecycledViewPool().setMaxRecycledViews(TYPE_VIDEO_VIEW, 0);
where TYPE_VIDEO_VIEW is the new type that you created using the previous example. The number 0 tells the RecyclerView how many items to recycle - in this case it's 0, meaning "do not recycle". More info about this here: https://stackoverflow.com/a/36313437/3086818.
I hope this helps.. Good luck!
The answer is yes, you can actually do that.
Since you said "The first item" so you simply add a check.
if(position == 0)
{
holder.setIsRecyclable(false); //This line prevents the row from recycling
}

Wrong dimension on recyclerview grid first row

I am trying to list items on my recycler view using the grid layout manager with two columns.
However, the first row of the grid seems to be having width issues.
When I scroll down until the first row is invisible, then scrolled back up, it will fix itself and show the correct width.
My items are retrieved from themoviedb API,
adapter.setMovieWrapper(body); // body contains data from the API
recyclerView.setLayoutManager(new GridLayoutManager(this, 2));
recyclerView.setAdapter(adapter);
Here is the layout code for the grid item:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="200dp"
android:padding="2dp"
android:orientation="vertical">
<ImageView
android:id="#+id/movie_thumbnail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerInside"
android:contentDescription="#string/movie_thumbnail_description"/>
<TextView
android:background="#drawable/bg_shade"
android:id="#+id/movie_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:textColor="#FFF"
android:ellipsize="end"
android:padding="8dp"/>
</FrameLayout>
Here is the adapter code:
public class MovieGridAdapter extends RecyclerView.Adapter<MovieGridItemViewHolder> {
MovieWrapper movieWrapper;
private Context context;
public MovieGridAdapter(Context context) {
this.context = context;
}
public MovieWrapper getMovieWrapper() {
return movieWrapper;
}
public void setMovieWrapper(MovieWrapper movieWrapper) {
this.movieWrapper = movieWrapper;
this.notifyDataSetChanged();
}
#Override
public MovieGridItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MovieGridItemViewHolder(
LayoutInflater.from(context)
.inflate(R.layout.movie_grid_item, parent, false)
);
}
#Override
public void onBindViewHolder(MovieGridItemViewHolder holder, int position) {
Movie movie = movieWrapper.getResults().get(position);
Uri uri = Uri.parse("https://image.tmdb.org/t/p/w185");
uri = uri.buildUpon().appendEncodedPath(movie.getPosterPath()).build();
Picasso.with(context)
.load(uri)
.into(holder.getThumbnail());
holder.getTitle().setText(movie.getTitle());
}
#Override
public int getItemCount() {
if (movieWrapper != null && movieWrapper.getResults() != null) {
return movieWrapper.getResults().size();
}
return 0;
}
}
and here is the activity that host the recycler view XML layout:
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.adityapurwa.popularmovies.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/movie_grid"
android:layout_width="match_parent"
android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>
</android.support.constraint.ConstraintLayout>
Anyone know what is causing this issue and how to resolve it?
Thanks!
There seems to be an issue with my ConstraintLayout hosting the RecyclerView, I changed it to FrameLayout and the issue disappeared. Even though the layout and the RecyclerView both have its dimension set to match_parent, somehow it fails to detect the dimension.
Note: Changing the dimension to be absolute (e.g 100dp) also solved the problem, however it makes the layout unresponsive.
I have used FrameLayout around Recyclerview but did not work, I used this work around solution like this, for first 2 items i added dummy items and hidden the views, this worked for me , although this is not a perfect solution

RecyclerView scrolling issue (Child items far away from each other)

Goodd day.I have simple recycler view with simplest dummy datas for test purpose,thus i have an weird issue to which the google did not find any solution or even an issue at all.On first launch the view is all good but as soon as i start to scrool,the child items are being as far from each other as no one can image...Really very and very far.But the issue is that the actual child items layout parameters are correct,only issue is that i dont know why RecyclerView decides to have each item heaps far away from each other.Please can you give me an help?Posting full code of my RecyclerView.
The view for recyclerView
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.ink.activities.HomeActivity"
tools:showIn="#layout/app_bar_home">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical" />
</RelativeLayout>
The Adapter.
public class FeedAdapter extends RecyclerView.Adapter<FeedAdapter.ViewHolder> {
private List<FeedModel> feedList;
private Context mContext;
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView title, content;
public ViewHolder(View view) {
super(view);
title = (TextView) view.findViewById(R.id.feedTitle);
content = (TextView) view.findViewById(R.id.feedContent);
}
}
public FeedAdapter(List<FeedModel> feedList, Context context) {
mContext = context;
this.feedList = feedList;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.feed_single_view, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
FeedModel feedModel = feedList.get(position);
holder.title.setText(feedModel.getTitle());
holder.content.setText(feedModel.getContent());
// animate(holder);
}
public void animate(RecyclerView.ViewHolder viewHolder) {
final Animation animAnticipateOvershoot = AnimationUtils.loadAnimation(mContext, R.anim.bounce_interpolator);
viewHolder.itemView.setAnimation(animAnticipateOvershoot);
}
#Override
public int getItemCount() {
return feedList.size();
}
}
I guess you won`t need holder as no view initiated with it.
The single child item view of RecyclerView adapter.
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:clickable="true"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="5dp"
app:cardElevation="10dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/feedTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:fontFamily="#string/appFont"
android:text="loading...."
android:textColor="#000000"
android:textSize="20sp" />
<TextView
android:id="#+id/feedContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/feedTitle"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
android:layout_marginTop="10dp" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
The initiation of actual parameters.
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mAdapter = new FeedAdapter(mFeedModelArrayList, this);
RecyclerView.ItemAnimator itemAnimator = new DefaultItemAnimator();
itemAnimator.setAddDuration(500);
itemAnimator.setRemoveDuration(500);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setItemAnimator(itemAnimator);
This code is as simple as it can get and it is important to mention that i am initiation all this inside the default NAVIGATION DRAWER ACTIVITY of android studio (the default templae inside content_main layout).So plaese can you give me any hint about the issue?
You're using
android:layout_width="match_parent"
android:layout_height="match_parent"
on your child item views. As of Support Library 23.2:
The RecyclerView widget provides an advanced and flexible base for creating lists and grids as well as supporting animations. This release brings an exciting new feature to the LayoutManager API: auto-measurement! This allows a RecyclerView to size itself based on the size of its contents. This means that previously unavailable scenarios, such as using WRAP_CONTENT for a dimension of the RecyclerView, are now possible. You’ll find all built in LayoutManagers now support auto-measurement.
Due to this change, make sure to double check the layout parameters of your item views: previously ignored layout parameters (such as MATCH_PARENT in the scroll direction) will now be fully respected.
Change your layout_height to wrap_content if you only want your items to be as large as needed. match_parent means they will be as large as the screen.

Recycler view showing single item

I am facing a strange error where recyclerview is showing only a single item. Below is code for my recyclerview adapter :
public class ChatAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
List<chat> chats;
String username;
final int My=0,Their=1;
public ChatAdapter(List<chat> chats) {
this.chats = chats;
this.username = PushApp.getApp().getSPF().getStringData(Constants.ANAME);
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder;
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType) {
case My:
View v1 = inflater.inflate(R.layout.my_chat_child, parent, false);
viewHolder = new MyChatHolder(v1);
break;
case Their:
View v2 = inflater.inflate(R.layout.their_chat_child, parent, false);
viewHolder = new TheirMessageHolder(v2);
break;
default:
View v = inflater.inflate(R.layout.my_chat_child, parent, false);
viewHolder = new MyChatHolder(v);
break;
}
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case My:
MyChatHolder myChatHolder = (MyChatHolder) holder;
myChatHolder.setMyMessage(chats.get(position).getMessage());
break;
case Their:
TheirMessageHolder theirMessageHolder = (TheirMessageHolder) holder;
theirMessageHolder.setTheirChat(chats.get(position).getFrom(), chats.get(position).getMessage());
break;
}
}
#Override
public int getItemViewType(int position) {
if(username.equalsIgnoreCase(chats.get(position).getFrom()))
return My;
return Their;
}
#Override
public int getItemCount() {
return chats.size();
}}
I have already used this code in other app and its working perfectly. I have checked the chats data which is also perfect.
Here's link to git repo layout files:
layout files
Don't use match_parent for height for your item view. One item fills whole screen vertically so you don't see another.
when you are creating row.xml for recyclerview should follow these things:
Always use "wrap_content" for the height of the row otherwise in "match_parent" it will occupy the whole screen for a single row.
You can also take the height in dp.
My mistake was I accidentally used:
LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
instead of:
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
content_main.xml as follows
android:layout_width="match_parent"
android:layout_height="match_parent"
IN row_list.xml file make following changes
android:layout_width="match_parent"
android:layout_height="wrap_content"
I make above changes it runs.
Try changing the layout used in your item view to FrameLayout. Here is an example.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/item"
android:layout_width="match_parent"
android:layout_height="?listPreferredItemHeight"
android:clickable="true"
android:focusable="true"
android:foreground="?selectableItemBackground">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"/>
</FrameLayout>
After checking the log make sure multiple items are added in the list but in UI its showing only 1 item means check this properties.
In item_xml file change property to
Correct Approach
android:layout_width="match_parent"
android:layout_height="wrap_content"
wrong Approach
android:layout_width="match_parent"
android:layout_height="match_parent"
I have this issue today, and after 1001 minutes, I find out this come from this line inside RecyclerView:
android:layout_marginTop="10dp"
My RecyclerView was put inside NestedScrollView, I think that is the indirect cause.
So I put here for anyone else meet the same issue. here the image
1) if your recyclerview is vertical then set height of recyclerview match_parent and row_item.xml height also match_parent
2) if your recyclerview is horizontal then set Width of recyclerview match_parent and row_item.xml Width also match_parent
for ex:-
Horizontal RecyclerView
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="60dp"
android:layout_marginRight="60dp" />
row_item.xml
<TextView
android:layout_width="match_parent"
android:layout_height="180dp"
android:layout_marginBottom="5dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="5dp"
android:background="#drawable/rect"
android:gravity="center"
android:maxLines="2"
android:padding="10dp"
android:textColor="#color/white"
android:textSize="25sp" />

Categories

Resources