如何在水平RecyclerView中捕捉到LinearSnapHelper()的特定位置? RecyclerView有一个函数scrolltoposition,可滚动到该位置,但不会在此snaphelper中居中。
我正在寻找下图所示的内容。因此,当我设置到特定位置时,它将保持居中。我没有发现与SnapHelper
的选择职位相关的任何信息我找到了this,但这对我没有帮助。 任何帮助将不胜感激。
答案 0 :(得分:1)
如果我理解您的问题,那么您正在寻找一种跳到某个位置并将该位置居于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;
}
答案 1 :(得分:0)
For horizontal RecyclerView, you should use PagerSnapHelper()
instead of LinearSnapHelper()
.
答案 2 :(得分:0)
将此添加到您想要滚动回收站视图的任何位置
recyclerView.scrollToPosition(position)
recyclerView.post {
var view = recyclerView.layoutManager?.findViewByPosition(position);
if (view == null) {
// do nothing
}
var snapDistance = snapHelper.calculateDistanceToFinalSnap(recyclerView.layoutManager!!, view!!)
if (snapDistance?.get(0) != 0 || snapDistance[1] != 0) {
recyclerView.scrollBy(snapDistance?.get(0)!!, snapDistance?.get(1));
}
}
使用此LinearSnap Helper(附加到您的回收站视图)
var snapHelper = LinearSnapHelper()
snapHelper.attachToRecyclerView(recyclerView)