RecyclerView doesn't display items until scrolling

This question has been asked multiple times, but these answers do not apply to me. I would like a more general answer as to what is causing this question in general.

I have a recyclerview in my activity layout. The recyclerview lines are a constraint layout with one image view and text:

<?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:layout_width="match_parent"
    android:layout_height="50dp"
    android:clickable="true">

    <ImageView
        android:id="@+id/file_icon"
        android:layout_width="50dp"
        android:layout_height="50dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <TextView
        android:text="File"
        android:id="@+id/file_name"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintLeft_toRightOf="@+id/file_icon"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>

</android.support.constraint.ConstraintLayout>

      

There are several elements in this string structure. I have configured the adapter correctly. However, when I launch my application, the text images displayed on the screen are not displayed until I scroll and scroll up. Basically, in order for these text images to be displayed, they must be discarded from the display and re-entered. Here is my adapter code:

public class FileViewAdapter extends RecyclerView.Adapter<FileViewAdapter.Viewholder> {

    private Context context;
    private List<File> files;

    public FileViewAdapter(Context context, List<File> files) {
        this.context = context;
        this.files = files;
    }

    public FileViewAdapter(Context context){

        this.context = context;
    }

    @Override
    public Viewholder onCreateViewHolder(ViewGroup viewGroup, int i) {
        LayoutInflater inflater = LayoutInflater.from(context);
        View layout = inflater.inflate(R.layout.file_list_item, viewGroup, false);
        return new Viewholder(layout);
    }

    @Override
    public void onBindViewHolder(Viewholder viewholder, int i) {
        File file = files.get(i);
        if (file.isDirectory()) {
            viewholder.fileIcon.setImageDrawable(
                    context.getResources().getDrawable(R.drawable.ic_folder_black_24dp));
            viewholder.wholeThing.setOnClickListener(null);
        } else {
            viewholder.fileIcon.setImageDrawable(
                    context.getResources().getDrawable(R.drawable.ic_insert_drive_file_black_24dp));
            viewholder.wholeThing.setOnClickListener(null);
        }
        viewholder.fileName.setText(file.getName());
    }


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

    public void clear() {
        files.clear();
        notifyDataSetChanged();
    }

    public void addAll(List<File> newFiles) {
        files.addAll(newFiles);
        notifyDataSetChanged();
    }

    class Viewholder extends RecyclerView.ViewHolder {
        View wholeThing;
        ImageView fileIcon;
        TextView fileName;

        public Viewholder(View itemView) {
            super(itemView);
            wholeThing = itemView;
            fileIcon = (ImageView) itemView.findViewById(R.id.file_icon);
            fileName = (TextView) itemView.findViewById(R.id.file_name);
        }
    }

}

      

EDIT: How do I call the adapter constructor on an activity.

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_file_viewer);    
    recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
}

@Override
public void onResume() {
     adapter = new Adapter(this, /*A list of File items*/);
     recyclerView.setAdapter(adapter);
     recyclerView.setLayoutManager(new LinearLayoutManager(this));
}

      

+4


source to share


4 answers


The problem from what I can see is that notifyDataSetChanged doesn't work in UiThread, so if you run urD's SetData method like this it will work.



 this.runOnUiThread(new Runnable() {
        public void run() {
            mAdapter.setNewData(newDataListForAdapter);
            mAdapter.notifyDataSetChanged();

        }
    });

      

+3


source


Try it. Hope this will be helpful.

RecyclerView recyclerView;
FileViewAdapter adapter;
List<File> files = new ArrayList<>();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_file_viewer);

    recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
    adapter = new FileViewAdapter(this, files);
    recyclerView.setAdapter(adapter);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
}

@Override
public void onResume() {
    super.onResume();

    files = getFiles();//fetch files
    adapter.notifyDataSetChanged();//update UI
}

public List<File> getFiles() {
    //fetch files
    //...
    return files;
}

      



By the way, I didn't find that the situation with you happened. There may be some errors in your code that you did not show us.

+2


source


As silly as it sounds, calling this line of code after setting the data for the recyclerView helped me with this problem:

recyclerView.smoothScrollToPosition(0)

      

PS: The technologies I've used may have something to do with this: RJava, Retrofit2, NavigationUI, Fragments, LiveData, and Databinding.

+2


source


If you are setting data in the constructor, the adapter may never be notified of the inserted data. Try adding notifyDataSetChanged () either at the bottom of the constructor or externally (or call the setData method)

0


source







All Articles