簡體   English   中英

如何使用許多類型的customViewHolder在recyclerView中實現recyclerView.smoothScrollToPosition(position)?

[英]How can I implement recyclerView.smoothScrollToPosition(position) in recyclerView with many types of customViewHolder?

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

為什么要使用自定義平滑滾動器,而您已經可以使用默認 滾動器了。 並且還避免在回調之后初始化適配器。 使用空白arraylist在create上初始化它,然后將數據更新到adapter中 ,這將是一個好習慣,否則,適配器將在每個api回調中初始化。

另外,您還需要執行一次后期運行以平滑地在后期框架中滾動,

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

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

反復設置適配器不是一個好習慣

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM