1

我正在尝试在我的应用程序中使用 Paging Library 使用 recyclerview 和 Room 实现无限滚动根据这篇文章:https ://developer.android.com/topic/libraries/architecture/paging/#database-examples

一些数据是在初始化时加载的,但是当用户滚动时,什么也没有发生,其余的数据没有被获取

我的道

@Dao
public interface MessageDao {
    .
    .
    .
    @Query("SELECT * FROM messages ORDER BY created DESC")
    DataSource.Factory<Integer, Message> getPagedMessage();
}

视图模型

public class SmsViewModel extends AndroidViewModel {

    private LiveData<PagedList<Message>> liveData;

    public SmsViewModel(@NonNull Application application) {
        super(application);

        DataSource.Factory<Integer, Message> factory = AppDatabase.getInstance(getApplication()).messageDao().getPagedMessage();

        PagedList.Config config = (new PagedList.Config.Builder())
                .setPageSize(10)
                .setInitialLoadSizeHint(20)
                .setPrefetchDistance(5)
                .setEnablePlaceholders(false)
                .build();
        liveData = new LivePagedListBuilder<>(factory, config).build();
    }

    public LiveData<PagedList<Message>> getLiveData() {
        return liveData;
    }
} 

适配器类

public abstract class BasePagedAdapter<T> extends PagedListAdapter<T, BasePagedAdapter.MyViewHolder> {

    private OnClickListener onClickListener;
    private OnLongClickListener onLongClickListener;

    public BasePagedAdapter(DiffUtil.ItemCallback<T> callback) {
        super(callback);
    }

    public void setOnClickListener(OnClickListener onClickListener) {
        this.onClickListener = onClickListener;
    }

    public void setOnLongClickListener(OnLongClickListener onLongClickListener) {
        this.onLongClickListener = onLongClickListener;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        ViewDataBinding binding = DataBindingUtil.inflate(layoutInflater, getLayoutIdForType(viewType), parent, false);
        return new MyViewHolder(binding);
    }

    @Override
    public void onBindViewHolder(@NonNull BasePagedAdapter.MyViewHolder holder, int position) {
        T t = getDataAtPosition(position);
        holder.bind(t);
    }

    public abstract T getDataAtPosition(int position);

    abstract @LayoutRes
    public int getLayoutIdForType(int viewType);

    class MyViewHolder extends RecyclerView.ViewHolder {
        private final ViewDataBinding binding;

        MyViewHolder(ViewDataBinding binding) {
            super(binding.getRoot());
            this.binding = binding;

            itemView.setOnClickListener(v -> {
                if (onClickListener != null) {
                    onClickListener.onClick(getAdapterPosition());
                }
            });

            itemView.setOnLongClickListener(view -> {
                if(onLongClickListener != null) {
                    onLongClickListener.onLongClick(getAdapterPosition());
                    return true;
                }
                return false;
            });
        }

        void bind(T obj) {
            binding.setVariable(BR.obj, obj);
            binding.executePendingBindings();
        }
    }

    public interface OnClickListener {
        void onClick(int position);
    }

    public interface OnLongClickListener {
        void onLongClick(int position);
    }
}

活动

public class SmsActivity extends AppCompatActivity {

    @BindView(R.id.lyt_empty)
    View lytEmpty;

    @BindView(R.id.progressBar)
    ProgressBar progressBar;

    @BindView(R.id.recycler_view)
    RecyclerView recyclerView;

    PagedList<Message> messages;

    BasePagedAdapter<Message> adapter = new BasePagedAdapter<Message>(DIFF_CALLBACK) {
        @Override
        public Message getDataAtPosition(int position) {
            if (messages != null) {
                return messages.get(position);
            }
            return null;
        }

        @Override
        public int getLayoutIdForType(int viewType) {
            return R.layout.item_sms_list;
        }
    };


    SmsViewModel viewModel;

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

        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        //noinspection ConstantConditions
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        ButterKnife.bind(this);

        viewModel = ViewModelProviders.of(this).get(SmsViewModel.class);

        adapter.setOnClickListener(position -> {
            Intent intent = new Intent(this, SmsDetailActivity.class);
            intent.putExtra(SmsDetailActivity.EXTRA_SMS, messages.get(position));
            startActivity(intent);
        });
        recyclerView.setAdapter(adapter);
        recyclerView.setNestedScrollingEnabled(false);
        loadData();
    }

    private void loadData() {
        viewModel.getLiveData().observe(this, messages -> {
            progressBar.setVisibility(View.GONE);
            this.messages = messages;
            if (messages != null && messages.size() > 0) {
                adapter.submitList(messages);
                recyclerView.setVisibility(View.VISIBLE);
                lytEmpty.setVisibility(View.GONE);
            } else {
                recyclerView.setVisibility(View.GONE);
                lytEmpty.setVisibility(View.VISIBLE);
            }
        });
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_sms_list, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            finish();
        }
        return true;
    }


    private static DiffUtil.ItemCallback<Message> DIFF_CALLBACK =
            new DiffUtil.ItemCallback<Message>() {
                @Override
                public boolean areItemsTheSame(Message oldItem, Message newItem) {
                    return oldItem.uid == newItem.uid;
                }

                @Override
                public boolean areContentsTheSame(Message oldItem, @NonNull Message newItem) {
                    return oldItem.equals(newItem);
                }
            };
}

消息表中当前有 25 个元素,但初始化时仅显示 20 个。当我滚动 Recyclerview 时没有任何反应,其他 5 个元素没有显示

4

1 回答 1

0

你需要这样做,我想。

recyclerView.setNestedScrollingEnabled(true);

信用

看这里:

https://github.com/googlesamples/android-architecture-components/issues/215#issuecomment-394849133

于 2019-03-06T06:03:59.157 回答