如何使用许多类型的customViewHolder在recyclerView中实现recyclerView.smoothScrollToPosition(position)?

时间:2019-02-27 05:52:00

标签: java android android-recyclerview recycler-adapter

我的recycleView有3种viewHolder。

位置0为viewHolder1。

位置1-41是viewHolder2。

位置42是viewHolder3。

但是,如果myDataSource.size()大于42,则会创建viewHolder3。

所以我需要使recyclerView.smoothScrollToPosition(position)工作。

请帮助。...

这是我的LinearLayoutManagerWithSmoothScroller

public class LinearLayoutManagerWithSmoothScroller extends LinearLayoutManager {



public LinearLayoutManagerWithSmoothScroller(Context context) {
    super(context);
}

@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
    View firstVisibleChild = recyclerView.getChildAt(0);
    final int childHeight = firstVisibleChild.getHeight();

    int distanceInPixels = ((findFirstVisibleItemPosition() - position) * childHeight);
    if (distanceInPixels == 0) {
        distanceInPixels = (int) Math.abs(firstVisibleChild.getY());
    }




    SmoothScroller smoothScroller = new SmoothScroller(recyclerView.getContext(), Math.abs(distanceInPixels), 1000);
    smoothScroller.setTargetPosition(position);
    startSmoothScroll(smoothScroller);
}



private class SmoothScroller extends LinearSmoothScroller {
    private static final int TARGET_SEEK_SCROLL_DISTANCE_PX = 10000;
    private final float distanceInPixels;
    private final float duration;

    public SmoothScroller(Context context, int distanceInPixels, int duration) {
        super(context);
        this.distanceInPixels = distanceInPixels;
        float millisecondsPerPx = calculateSpeedPerPixel(context.getResources().getDisplayMetrics());
        this.duration = distanceInPixels < TARGET_SEEK_SCROLL_DISTANCE_PX ?
                (int) (Math.abs(distanceInPixels) * millisecondsPerPx) : duration;
    }

    @Override
    public PointF computeScrollVectorForPosition(int targetPosition) {
        return LinearLayoutManagerWithSmoothScroller.this
                .computeScrollVectorForPosition(targetPosition);
    }

    @Override
    protected int calculateTimeForScrolling(int dx) {
        float proportion = (float) dx / distanceInPixels;
        return (int) (duration * proportion);
    }
}

}

并在活动中调用它

call = Quiz5Manager.getInstance(QuizGameRankingActivity.this).getQuiz5Interface().loadQuiz5Ranking(BaseApplication.sharedPreferences.getString("facebook_id", ""));
        call.enqueue(new Callback<Quiz5Ranking_Model>() {
            @Override
            public void onResponse(Call<Quiz5Ranking_Model> call, Response<Quiz5Ranking_Model> response) {
                if (response.isSuccessful()) {
                    if (response.body() != null) {
                        Quiz5Ranking_Model quiz5Ranking_model = response.body();
                        List<Quiz5Ranking_UserRank_Model> all_rank_model = quiz5Ranking_model.getRankUsers();
                        all_rank_model.add(quiz5Ranking_model.getUserRank());
                        mAdapter = new QuizRankingAdapter(QuizGameRankingActivity.this, all_rank_model);
                        recycleview.setAdapter(mAdapter);
                        recycleview.setLayoutManager(new LinearLayoutManagerWithSmoothScroller(QuizGameRankingActivity.this));
                        mAdapter.notifyDataSetChanged();
                        recycleview.smoothScrollToPosition(20);

                        int user_rank = quiz5Ranking_model.getUserRank().getRankId();
                        if (user_rank > 44) {
                            showToast("more than 44");
                        } else {
                            if (user_rank <= 3) {
                                showToast("Top 3");
                            } else if (user_rank >= 4 && user_rank <= 44) {
                                showToast("Normal");
                            }
                        }
                    }
                }
            }

            @Override
            public void onFailure(Call<Quiz5Ranking_Model> call, Throwable t) {
                showToast("Fail to load. Please try again later.");
            }
        });

我在这行上得到了空指针异常

View firstVisibleChild = recyclerView.getChildAt(0);

2 个答案:

答案 0 :(得分:0)

SmoothScrollerSNAP_TO_START一起使用:

RecyclerView.SmoothScroller smoothScroller = new LinearSmoothScroller(context) {
  @Override protected int getVerticalSnapPreference() {
    return LinearSmoothScroller.SNAP_TO_START;
  }
};

现在设置要滚动到的位置:

smoothScroller.setTargetPosition(position);

并将该SmoothScroller传递给LayoutManager

layoutManager.startSmoothScroll(smoothScroller);

更新

onResponse删除这两行,并将它们添加到onCreate

 recycleview.setAdapter(mAdapter);
 recycleview.setLayoutManager(new LinearLayoutManagerWithSmoothScroller(QuizGameRankingActivity.this));

这不是一次又一次设置适配器的好习惯

答案 1 :(得分:0)

为什么要使用自定义平滑滚动器,而您已经可以使用默认。并在回调后避免初始化适配器。在使用空白arraylist创建时将其初始化,然后将数据更新到适配器,这是一个好习惯,否则适配器将在每个每个api回调中初始化

此外,您将需要进行后期运行以平滑地在后期框架中滚动,

recyclerview.post(new Runnable() {
            @Override
            public void run() {
                 recycleview.smoothScrollToPosition(20);
            }
        });