Bora
Bora

Reputation: 1858

RecyclerView doesn't show items until scrolling

This question has been asked a few times but those answers doesn't apply to me. I would like a more general answer about what causes this issue generally.

I have a recyclerview in my activity layout. Rows of the recyclerview is a constraint layout with one imageview and textview:

<?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>

I have several items to show in this row structure. I set up the adapter properly. However, when I run my application, textviews that are on the screen doesn't get shown, until I scroll-down and scroll-up again. Basically, in order for those textviews to be shown, they need to be discarded from display and enter again. 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 I am calling the constructor of adapter on 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));
}

Upvotes: 6

Views: 4347

Answers (4)

Amin Keshavarzian
Amin Keshavarzian

Reputation: 3963

As stupid as it might sound, calling this line of code after setting data for recyclerView, helped me for this issue:

recyclerView.smoothScrollToPosition(0)

PS: technologies that I was using that may have something to do with this were: RJava, Retrofit2, NavigationUI, Fragments, LiveData, and Databinding.

Upvotes: 5

Catluc
Catluc

Reputation: 1823

The problem from what i see is that the notifyDataSetChanged doesnt ocurr in the UiThread so if run ur setData method like this it will work.

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

        }
    });

Upvotes: 7

Relish Wang
Relish Wang

Reputation: 385

Please try this. I hope it 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 did not find the situation happened to you. There may be some other errors in you code you did not show to us.

Upvotes: 2

balsick
balsick

Reputation: 1201

if you're setting data on the constructor, it might be that the adapter never gets notified about data inserted. Try to add a notifyDataSetChanged () either at the bottom of the constructor or externally (or call your setData method)

Upvotes: 0

Related Questions