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

问题描述 投票:0回答:2

我的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);
java android android-recyclerview recycler-adapter
2个回答
1
投票

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

你还需要做一个后期运行来平滑后期框架中的滚动,如,

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

0
投票

使用SmoothScroller和首选SNAP_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));

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

© www.soinside.com 2019 - 2024. All rights reserved.