java - 如何在具有多种类型的customViewHolder的recyclerView中实现recyclerView.smoothScrollToPosition(position)?

标签 java android android-recyclerview

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

}

并在 Activity 中调用它

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

最佳答案

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

此外,您还需要进行后期运行以在后帧中平滑滚动,例如,

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

关于java - 如何在具有多种类型的customViewHolder的recyclerView中实现recyclerView.smoothScrollToPosition(position)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54898887/

相关文章:

android - React-Native:当用户在剪贴板上复制文本时做一些事情

java - ListView 崩溃,无法处理 Holder 类

android - RecyclerView如何实现ViewCacheExtension?

java - 从 String.format() 生成的字符串中提取值

java - 在资源处理程序中设置字符编码

android - 如何在 galaxy trend plus gt s 7580 上运行 eclipse 项目

android - AnimateLayoutChanges 不适用于 RecyclerView

android - RecyclerView textChangeListener 或数据绑定(bind)

java - 被Android访问控制机制搞糊涂了。它与 Java 不同

java - 如何在 fragment 中添加后退箭头以进行后退操作?