I have an endless scrolling recyclerView in a fragment called 'QuestionListFragment'.
public class QuestionsListFragment extends Fragment implements OnLoadMoreListener {
private RecyclerView rcQuestionsList;
private ArrayList<Question> questionsList;
private QuestionsListAdapter questionsListAdapter;
private LinearLayoutManager linearLayoutManager;
private EndlessRecyclerViewScrollListener endlessRecyclerViewScrollListener;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState){
View view = inflater.inflate(R.layout.fragment_questions_list, container, false);
rcQuestionsList = view.findViewById(R.id.recyclerView);
questionsList = getQuestionsList();
questionsListAdapter = new QuestionsListAdapter(questionsList);
rcQuestionsList.setAdapter(questionsListAdapter);
linearLayoutManager = new LinearLayoutManager(getActivity());
rcQuestionsList.setLayoutManager(linearLayoutManager);
endlessRecyclerViewScrollListener = new EndlessRecyclerViewScrollListener(this, linearLayoutManager);
rcQuestionsList.addOnScrollListener(endlessRecyclerViewScrollListener);
return view;
}
private ArrayList<Question> getQuestionsList(){
ArrayList<Question> questionsList = new ArrayList<>();
questionsList.add(new Question(0, new User("木小猪", ContextCompat.getDrawable(getActivity(), R.drawable.avatar1)), "玉山镇东城大道世贸广场KFC", "店内人流状况,越清楚越好", 2, 3f));
questionsList.add(new Question(1, new User("古晓峰", ContextCompat.getDrawable(getActivity(), R.drawable.avatar3)),"苏州幼儿师范高等专科院校校门口", "停车场状况,显示剩余车位", 2, 2.5f ));
questionsList.add(new Question(2, new User("谢贤斌", ContextCompat.getDrawable(getActivity(), R.drawable.avatar4)),"湖北工业大学正门水果店", "下雨雨量情况", 1, 1.5f ));
return questionsList;
}
@Override
public void OnLoadMore(){
questionsListAdapter.addItem(new Question(6, new User("吴磊", ContextCompat.getDrawable(this.getActivity(), R.drawable.avatar2)),"南湖大道花木城公交站牌向东50米", "店内客流量状况(要求拍照)", 3, 2.5f ));
}
}
As you can see, I initialize the recyclerView with three items. Since three items aren't enough to occupy the whole screen, the recyclerView will call onScrolled method and the endlessRecyclerVeiwScrollListener will trigger the onLoadMore() method in QuestionsListFragment. I run the project in debug mode and indeed it hits the breakpoint I set in onLoadMore() method. However, the recyclerView should add one new item in its end, I didn't see that happen.
Below is my recyclerViewAdapter code:
public class QuestionsListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<Question> questionsList;
private final int VIEW_TYPE_ITEM = 0;
private final int VIEW_TYPE_LOADING = 1;
public QuestionsListAdapter(List<Question> questions){
this.questionsList = questions;
setHasStableIds(true);
}
@Override
public int getItemViewType(int position){
return questionsList.get(position) == null ? VIEW_TYPE_LOADING : VIEW_TYPE_ITEM;
}
@Override
public long getItemId(int position){
if(getItemViewType(position) == VIEW_TYPE_ITEM)
return questionsList.get(position).getId();
else if(getItemViewType(position) == VIEW_TYPE_LOADING)
return -1;
return -2;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
Context context = viewGroup.getContext();
LayoutInflater layoutInflater = LayoutInflater.from(context);
if(i == VIEW_TYPE_ITEM){
View questionItemView = layoutInflater.inflate(R.layout.item_question, viewGroup, false);
return new ViewHolder(questionItemView);
}
else if(i == VIEW_TYPE_LOADING){
View loadingView = layoutInflater.inflate(R.layout.item_loading, viewGroup, false);
return new LoadingViewHolder(loadingView);
}
return null;
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
if(viewHolder instanceof ViewHolder){
Question question = questionsList.get(i);
ViewHolder itemViewHolder = (ViewHolder)viewHolder;
itemViewHolder.addressTextView.setText(question.getAddress());
itemViewHolder.notesTextView.setText(question.getNotes());
itemViewHolder.moneyEachRedPackage.setText(Float.toString(question.getMoneyEachRedPackage()));
itemViewHolder.avatarImageView.setImageDrawable(question.getUser().getAvatar());
}
else if(viewHolder instanceof LoadingViewHolder){
LoadingViewHolder loadingViewHolder = (LoadingViewHolder)viewHolder;
loadingViewHolder.progressBar.setIndeterminate(true);
}
}
@Override
public int getItemCount() {
return questionsList.size();
}
public void addItem(Question newItem){
this.questionsList.add(newItem);
notifyItemInserted(questionsList.size()-1);
}
public void removeItem(int index){
this.questionsList.remove(index);
notifyItemRemoved(index);
notifyItemRangeChanged(index, getItemCount());
}
public void updateQuestionsListItems(ArrayList<Question> newQuestionsList){
final QuestionsDiffCallBack diffCallBack = new QuestionsDiffCallBack(this.questionsList, newQuestionsList);
final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffCallBack);
this.questionsList.clear();
this.questionsList.addAll(newQuestionsList);
diffResult.dispatchUpdatesTo(this);
}
public class LoadingViewHolder extends RecyclerView.ViewHolder{
private ProgressBar progressBar;
LoadingViewHolder(View view){
super(view);
progressBar = view.findViewById(R.id.progressBar);
}
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView addressTextView;
private TextView notesTextView;
private ImageView redPackageOne;
private ImageView redPackageTwo;
private ImageView redPackageThree;
private TextView moneyEachRedPackage;
private CircleImageView avatarImageView;
ViewHolder(View viewItem){
super(viewItem);
addressTextView = itemView.findViewById(R.id.addressTextView);
notesTextView = itemView.findViewById(R.id.notesTextView);
redPackageOne = itemView.findViewById(R.id.redPackage1);
redPackageTwo = itemView.findViewById(R.id.redPackage2);
redPackageThree = itemView.findViewById(R.id.redPackage3);
moneyEachRedPackage = itemView.findViewById(R.id.moneyEachRedPackageTextView);
avatarImageView = itemView.findViewById(R.id.avatarImageView);
}
}
}
But if I put the questionsListAdapter.addItem() code under some other method, like onResume, the new item would be successfully added in the beginning. Looks like something related to scroll stops the inserting animation happen?