在Recycleview上处理大量数据的最佳方法是什么

时间:2017-06-05 15:04:50

标签: android sqlite android-recyclerview adapter

我需要在RecycleView上加载一长串数据(5000-1000),RecycleView的每个项目都有很多细节,因此5 TextView,1 {{ 1}}和ImageView。所有数据都存储在ProgressBar上。 加载包含所有数据的SQLite DB并将它们设置到适配器是否更好?或者更好地在适配器上加载数据? 请考虑我在适配器上还有其他事情要做,例如重新搜索图像(使用ArrayList<Object>)。 任何建议或考虑都会有所帮助!

谢谢

4 个答案:

答案 0 :(得分:1)

您可以尝试仅显示部分数据,并使用Recycler View's OnScroll Listener加载并在用户到达回收站视图结束时显示更多内容(基本上是分页)。这样,您就不必支付一次加载所有数据的完整有效负载。

希望这有帮助!

答案 1 :(得分:0)

您可以尝试使用cursorRecyclarViewAdapter

https://gist.github.com/skyfishjy/443b7448f59be978bc59

public class MyRecyclerAdapter extends Adapter<MyRecyclerAdapter.ViewHolder> {

// Because RecyclerView.Adapter in its current form doesn't natively 
// support cursors, we wrap a CursorAdapter that will do all the job
// for us.
CursorAdapter mCursorAdapter;

Context mContext;

public MyRecyclerAdapter(Context context, Cursor c) {

    mContext = context;

    mCursorAdapter = new CursorAdapter(mContext, c, 0) {

        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            // Inflate the view here
        }

        @Override
        public void bindView(View view, Context context, Cursor cursor) {
            // Binding operations
        }
    };
}

public static class ViewHolder extends RecyclerView.ViewHolder {
    View v1;

    public ViewHolder(View itemView) {
        super(itemView);
        v1 = itemView.findViewById(R.id.v1);
    }
}

@Override
public int getItemCount() {
    return mCursorAdapter.getCount();
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    // Passing the binding operation to cursor loader
    mCursorAdapter.getCursor().moveToPosition(position); //EDITED: added this line as suggested in the comments below, thanks :)
    mCursorAdapter.bindView(holder.itemView, mContext, mCursorAdapter.getCursor());

}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    // Passing the inflater job to the cursor-adapter
    View v = mCursorAdapter.newView(mContext, mCursorAdapter.getCursor(), parent);
    return new ViewHolder(v);
}
}

答案 2 :(得分:0)

如果您正在使用回收站视图,那么我猜它实际上是加载大型列表的最佳方法(对我而言)...我认为这两种方法(存储Arraylist并将数据发送到适配器)都有效在某些情况下,但回收站视图会破坏已滚动的数据。但我认为许多开发人员使用的最佳方式和最有效的方法是立即设置屏幕上显示的数据量限制,然后在滚动侦听器上使用以加载更多,然后回收器视图也可以完成工作!

在这里查看非常完美

Android Endless List

答案 3 :(得分:0)

你可以通过 Android Room & Paging 组件来实现 我尝试加载数据记录计数>10m

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        binding.setViewModel(new ViewModelProvider(this).get(ViewModel.class));
        binding.setLifecycleOwner(this);
    }


    public static class ViewModel extends AndroidViewModel {
        public final List<Contact> contactList = new ArrayList<>();
        private final ContactDatabase database = Room.databaseBuilder(getApplication(), ContactDatabase.class, "contact.db")
                .fallbackToDestructiveMigration()
                .allowMainThreadQueries()
                .build();
        public final LiveData<PagedList<Contact>> pagedListLiveData = new LivePagedListBuilder<>(database.getContactDao().getAllContact3(), 1000).build();

        public ViewModel(@NonNull Application application) {
            super(application);
        }
    }
}

房间数据库实体类

@Entity
public class Contact {

    @PrimaryKey(autoGenerate = true)
    public int _id;

    public int _accountId;

    public int photo_id;

    public String display_name;
    public String display_name_alt;
    public String display_name_source;

    public int starred;
    public int pinned;

    public String phonetic_name;
    public String phonetic_name_style;

    public int deleted;
    public int dirty;
}

房间数据库道

@Dao
public interface ContactDao {

    @Query("SELECT * FROM contact")
    List<Contact> getAllContact();

    @Query("SELECT * FROM contact")
    LiveData<List<Contact>> getAllContact2();

    @Insert
    void insertAll(List<Contact> contacts);

    @Query("SELECT * FROM contact")
    DataSource.Factory<Integer, Contact> getAllContact3();

    @Query("SELECT * FROM contact")
    PositionalDataSource<Contact> getAllContact4();

}

布局

<?xml version="1.0" encoding="utf-8"?>
<layout>

    <data>

        <variable
            name="viewModel"
            type="com.xxx.hugedatabaserecordtest.MainActivity.ViewModel" />
    </data>

    <androidx.constraintlayout.widget.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=".MainActivity">

        <androidx.recyclerview.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            app:itemTemplate="@{@layout/contact_list_item_template}"
            app:items="@{viewModel.pagedListLiveData}"
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>