Reputation: 43
I am using a FirebaseRecyclerAdapter to get data from Firebase and fill up a recycler view. The code works fine, but when I start to scroll, the recycler view calls the PopulateViewHolder method with every scroll which makes the scrolling lag alot and sometimes I lose some of the data at the beginning of the recycler view.
my code is:
final FirebaseRecyclerAdapter<Post, PostsViewHolder> adapt = new FirebaseRecyclerAdapter<Post, PostsViewHolder>(Post.class, R.layout.layout_cardview, PostsViewHolder.class, mRef) {
@Override
protected void populateViewHolder(PostsViewHolder viewHolder, Post model, int position) {
Log.i("CHECK", "POPULATEVIEWHOLDER");
test.setLongitude(model.getLongitude());
Log.d("LONGITUDE", model.getLongitude() + "");
test.setLatitude(model.getLatitude());
Log.d("LATITUDE", test.getLatitude() + "");
try {
if ((location.distanceTo(test) / 1000.0) < 10) {
viewHolder.Content.setText(model.getContent());
viewHolder.Time.setText(model.getTime());
} else {
viewHolder.delete();
}
}catch(Exception e){
Toast.makeText(getApplicationContext(), "Please Make sure Location is enabled", Toast.LENGTH_LONG).show();
}
}
};
adapt.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
rv.getLayoutManager().smoothScrollToPosition(rv,null,positionStart);
}
});
The PostsViewHolder is:
public static class PostsViewHolder extends RecyclerView.ViewHolder{
TextView Content;
TextView Time;
CardView cv;
public PostsViewHolder(View v) {
super(v);
Content = (TextView) v.findViewById(R.id.textview_descriptionBrief);
cv = (CardView) v.findViewById(R.id.post_cardview);
Time = (TextView) v.findViewById(R.id.textView_time);
}
public void delete(){
cv.setLayoutParams(new RecyclerView.LayoutParams(0,0));
}
}
and the Post class model contains the getters and setters and fields for each post.
the XML for the list is:
<RelativeLayout
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:id="@+id/activity_lookup"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorWhite"
tools:context="com.app.postit.postit.LookupActivity">
<!--<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:id="@+id/toolbar_lookupActivity">
</android.support.v7.widget.Toolbar>-->
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:id="@+id/recyclerview_lookupActivity"
/>
<android.support.design.widget.FloatingActionButton
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="10dp"
android:layout_marginBottom="10dp"
android:id="@+id/button_floatingButton"
android:scaleType="center"
app:backgroundTint="@color/colorWhite"
app:fabSize="mini"
android:src="@drawable/ic_add_circle_blue_48dp"
app:elevation="5dp"
/>
The layout manager is a linear layout manager and the method containing the adapter is only called once in the onCreatemethod.
Upvotes: 4
Views: 1006
Reputation: 365158
It is correct.
The populateViewHolder
method is called by onBindViewHolder
method.
You can check the official javadoc.
This method is called by RecyclerView
to display the data at the specified position.
As you scroll you will start getting view holders that were used for rows that went off screen and you have to replace old data that they held with new data.
To do it this method is called.
Check your code.
If there are some time consuming methods (for example if you loading images) in this step, you should use asynchronous tasks.
Upvotes: 2