我找到此 ,但这对我没有帮助.任何帮助将不胜感激. 解决方案如果我理解您的问题,则您正在寻找一种跳到某个位置并将该位置居于RecyclerView中心的方法.也许您已经尝试过RecyclerView.scrollToPosition(),但是并不能捕捉到视图.您可能还尝试过RecyclerView.smoothScrollToPosition(),并且效果更好,但是如果您有很多项目并且滚动很长的距离,则可能希望避免所有移动. scrollToPosition()不起作用的原因是,它不会触发使用滚动侦听器检测何时捕捉的LinearSnapHelper.由于smoothScrollToPosition()确实触发了LinearSnapHelper,因此我们将使用scrollToPosition()将我们带到目标视图的区域,然后使用smoothScrollToPosition()将视图居中,如下所示:private RecyclerView mRecycler;private void newScrollTo(final int pos) { RecyclerView.ViewHolder vh = mRecycler.findViewHolderForLayoutPosition(pos); if (vh != null) { // Target view is available, so just scroll to it. mRecycler.smoothScrollToPosition(pos); } else { // Target view is not available. Scroll to it. mRecycler.addOnScrollListener(new RecyclerView.OnScrollListener() { // From the documentation: // This callback will also be called if visible item range changes after a layout // calculation. In that case, dx and dy will be 0.This callback will also be called // if visible item range changes after a layout calculation. In that case, // dx and dy will be 0. @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); mRecycler.removeOnScrollListener(this); if (dx == 0) { newScrollTo(pos); } } }); mRecycler.scrollToPosition(pos); }} 示例应用 MainActivity.java public class MainActivity extends AppCompatActivity { private final LinearLayoutManager mLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false); private final List<String> mItems = new ArrayList<>(); private RecyclerView mRecycler; private final int mItemCount = 2000; private final Handler mHandler = new Handler(); private final LinearSnapHelper mLinearSnapHelper = new LinearSnapHelper(); protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); for (int i = 0; i < mItemCount; i++) { mItems.add(i + ""); } mRecycler = findViewById(R.id.recyclerView); final RecyclerViewAdapter adapter = new RecyclerViewAdapter(null); adapter.setItems(mItems); mRecycler.setLayoutManager(mLayoutManager); mRecycler.setAdapter(adapter); mLinearSnapHelper.attachToRecyclerView(mRecycler); newScrollTo(1);// fireScrollTo(); } private int maxScrolls = mItemCount; private void fireScrollTo() { if (--maxScrolls > 0) { int pos = (int) (Math.random() * mItemCount); newScrollTo(pos); mHandler.postDelayed(new Runnable() { @Override public void run() { fireScrollTo(); } }, 2000); } } private void newScrollTo(final int pos) { mRecycler.smoothScrollToPosition(pos); RecyclerView.ViewHolder vh = mRecycler.findViewHolderForLayoutPosition(pos); if (vh != null) { // Target view is available, so just scroll to it. mRecycler.smoothScrollToPosition(pos); } else { // Target view is not available. Scroll to it. mRecycler.addOnScrollListener(new RecyclerView.OnScrollListener() { // From the documentation: // This callback will also be called if visible item range changes after a layout // calculation. In that case, dx and dy will be 0.This callback will also be called // if visible item range changes after a layout calculation. In that case, // dx and dy will be 0. @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); mRecycler.removeOnScrollListener(this); if (dx == 0) { newScrollTo(pos); } } }); mRecycler.scrollToPosition(pos); } }} activity_main.xml <android.support.constraint.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent"> <View android:layout_width="3px" android:layout_height="match_parent" android:background="@android:color/holo_red_light" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" android:clipToPadding="false" android:paddingStart="660px" android:paddingEnd="660px"/></android.support.constraint.ConstraintLayout> RecyclerViewAdapter.java class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private List<String> mItems; RecyclerViewAdapter(List<String> items) { mItems = items; } @Override public @NonNull RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, parent, false); view.getLayoutParams().width = 220; view.getLayoutParams().height = 220;// view.setPadding(220 * 3, 0, 220 * 3, 0); ((TextView) view).setGravity(Gravity.CENTER); return new ItemViewHolder(view); } @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { ItemViewHolder vh = (ItemViewHolder) holder; String itemText = mItems.get(position); vh.mItemTextView.setText(itemText); int bgColor = (position % 2 == 0) ? android.R.color.holo_blue_light : android.R.color.holo_green_light; holder.itemView.setBackgroundColor( holder.itemView.getContext().getResources().getColor(bgColor)); } @Override public int getItemCount() { return (mItems == null) ? 0 : mItems.size(); } @Override public int getItemViewType(int position) { return TYPE_ITEM; } static class ItemViewHolder extends RecyclerView.ViewHolder { private TextView mItemTextView; ItemViewHolder(View item) { super(item); mItemTextView = item.findViewById(android.R.id.text1); } } public void setItems(List<String> items) { mItems = items; } @SuppressWarnings("unused") private final static String TAG = "RecyclerViewAdapter"; private final static int TYPE_ITEM = 1;}How can I snap to particular position for LinearSnapHelper() in horizontal RecyclerView? There is a function scrolltoposition for RecyclerView which scroll to that position but did not keep it in center for this snaphelper.I am looking for something like below image. So when I set to particular position, it will keep it in center. I dont find anything related to select position for SnapHelperi find this , but this doesn't help me.Any help would be appreciated. 解决方案 If I understand your question, you are looking for a way to jump to a position and have that position centered in the RecyclerView.Maybe you have tried RecyclerView.scrollToPosition() but that doesn't snap to the view. You may also have tried RecyclerView.smoothScrollToPosition() and that works better but you may want to avoid all the movement if you have a lot of items and are scrolling a long way.The reason that scrollToPosition() doesn't work is that it doesn't trigger the LinearSnapHelper which uses a scroll listener to detect when to snap. Since smoothScrollToPosition() does trigger the LinearSnapHelper, we will use scrollToPosition() to get us in the area of the target view then use smoothScrollToPosition() to get the view centered as follows:private RecyclerView mRecycler;private void newScrollTo(final int pos) { RecyclerView.ViewHolder vh = mRecycler.findViewHolderForLayoutPosition(pos); if (vh != null) { // Target view is available, so just scroll to it. mRecycler.smoothScrollToPosition(pos); } else { // Target view is not available. Scroll to it. mRecycler.addOnScrollListener(new RecyclerView.OnScrollListener() { // From the documentation: // This callback will also be called if visible item range changes after a layout // calculation. In that case, dx and dy will be 0.This callback will also be called // if visible item range changes after a layout calculation. In that case, // dx and dy will be 0. @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); mRecycler.removeOnScrollListener(this); if (dx == 0) { newScrollTo(pos); } } }); mRecycler.scrollToPosition(pos); }}Sample appMainActivity.javapublic class MainActivity extends AppCompatActivity { private final LinearLayoutManager mLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false); private final List<String> mItems = new ArrayList<>(); private RecyclerView mRecycler; private final int mItemCount = 2000; private final Handler mHandler = new Handler(); private final LinearSnapHelper mLinearSnapHelper = new LinearSnapHelper(); protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); for (int i = 0; i < mItemCount; i++) { mItems.add(i + ""); } mRecycler = findViewById(R.id.recyclerView); final RecyclerViewAdapter adapter = new RecyclerViewAdapter(null); adapter.setItems(mItems); mRecycler.setLayoutManager(mLayoutManager); mRecycler.setAdapter(adapter); mLinearSnapHelper.attachToRecyclerView(mRecycler); newScrollTo(1);// fireScrollTo(); } private int maxScrolls = mItemCount; private void fireScrollTo() { if (--maxScrolls > 0) { int pos = (int) (Math.random() * mItemCount); newScrollTo(pos); mHandler.postDelayed(new Runnable() { @Override public void run() { fireScrollTo(); } }, 2000); } } private void newScrollTo(final int pos) { mRecycler.smoothScrollToPosition(pos); RecyclerView.ViewHolder vh = mRecycler.findViewHolderForLayoutPosition(pos); if (vh != null) { // Target view is available, so just scroll to it. mRecycler.smoothScrollToPosition(pos); } else { // Target view is not available. Scroll to it. mRecycler.addOnScrollListener(new RecyclerView.OnScrollListener() { // From the documentation: // This callback will also be called if visible item range changes after a layout // calculation. In that case, dx and dy will be 0.This callback will also be called // if visible item range changes after a layout calculation. In that case, // dx and dy will be 0. @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); mRecycler.removeOnScrollListener(this); if (dx == 0) { newScrollTo(pos); } } }); mRecycler.scrollToPosition(pos); } }}activity_main.xml<android.support.constraint.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent"> <View android:layout_width="3px" android:layout_height="match_parent" android:background="@android:color/holo_red_light" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" android:clipToPadding="false" android:paddingStart="660px" android:paddingEnd="660px"/></android.support.constraint.ConstraintLayout>RecyclerViewAdapter.javaclass RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private List<String> mItems; RecyclerViewAdapter(List<String> items) { mItems = items; } @Override public @NonNull RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, parent, false); view.getLayoutParams().width = 220; view.getLayoutParams().height = 220;// view.setPadding(220 * 3, 0, 220 * 3, 0); ((TextView) view).setGravity(Gravity.CENTER); return new ItemViewHolder(view); } @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { ItemViewHolder vh = (ItemViewHolder) holder; String itemText = mItems.get(position); vh.mItemTextView.setText(itemText); int bgColor = (position % 2 == 0) ? android.R.color.holo_blue_light : android.R.color.holo_green_light; holder.itemView.setBackgroundColor( holder.itemView.getContext().getResources().getColor(bgColor)); } @Override public int getItemCount() { return (mItems == null) ? 0 : mItems.size(); } @Override public int getItemViewType(int position) { return TYPE_ITEM; } static class ItemViewHolder extends RecyclerView.ViewHolder { private TextView mItemTextView; ItemViewHolder(View item) { super(item); mItemTextView = item.findViewById(android.R.id.text1); } } public void setItems(List<String> items) { mItems = items; } @SuppressWarnings("unused") private final static String TAG = "RecyclerViewAdapter"; private final static int TYPE_ITEM = 1;} 这篇关于如何在水平RecyclerView中捕捉到LinearSnapHelper的特定位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
09-02 19:47