RecyclerView插入动画不显示

时间:2018-12-28 09:18:17

标签: android android-recyclerview

我在名为“ QuestionListFragment”的片段中有一个循环滚动的recyclerView。

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 ));
    }

}

如您所见,我用三个项目初始化了recyclerView。由于三个项目不足以占据整个屏幕,因此recyclerView将调用onScrolled方法,而endlessRecyclerVeiwScrollListener将触发QuestionsListFragment中的onLoadMore()方法。我在调试模式下运行该项目,的确达到了我在onLoadMore()方法中设置的断点。但是,recyclerView应该在末尾添加一个新项,但我没有看到这种情况。

下面是我的recyclerViewAdapter代码:

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);
        }
    }
}

但是,如果我将questionsListAdapter.addItem()代码放在其他方法下(如onResume),则新项目将在一开始就成功添加。看起来与滚动相关的东西会阻止插入动画的发生?

1 个答案:

答案 0 :(得分:0)

我不确定我是否理解你的问题。但是要回答标题:“ RecyclerView不显示用于插入和更新动作的动画”,您需要在RecyclerView Adapter中启用以下两项以打开动画:

  1. 在RecyclerView Adapter构造函数中,您必须调用:

    setHasStableIds(true);
    
  2. 还必须在适配器中重写getItemId()并确保为每个项目返回唯一的ID:

    @Override
    public long getItemId(int position) {
        //return a unique ID for this position
    }
    

此处有更多信息:How to Animate Addition or Removal of Android ListView Rows