如何使用 Runnable 和布尔标志滚动 recyclerView automatically/periodically
How to scroll a recyclerView automatically/periodically using a Runnable and boolean flags
我面临着一个相当具有挑战性的情况,我需要根据 RecyclerView
.
中触摸事件提供的标志自动并定期滚动 RecyclerView
我有 RecyclerView
个可折叠物品,可折叠物品在 ScrollView
中有一个 ImageView
。我知道这是一个糟糕的实现,因为 ScrollView
不会如果 parent 也垂直滚动。
但由于我想要此功能,我想在 ScrollView
可见时禁用 RecyclerView
中的滚动以使其滚动。我为此定制了 LayoutManager
如下:
public class ConditionalScrollManager extends LinearLayoutManager {
public ConditionalScrollManager(Context context) {
super(context);
}
ConditionalScrollManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
@Override
public boolean canScrollVertically() {
return Adapter_Admin.canScroll && super.canScrollVertically();
}
}
但是,这带来了一个问题,即无法完全看到屏幕底部的项目,因为单击项目后列表不可滚动。
标志 Adapter_Admin.canScroll
来自我的适配器:
canScroll = true;
flAdmin.setOnClickListener(v -> {
image = beanOrders.get(getLayoutPosition()).getsImage();
message = beanOrders.get(getLayoutPosition()).getsMessage();
scrollOne = true;
scrollTo = getLayoutPosition();
if (flAdmin.isFolded()) {
flAdmin.unfoldWithAnimation();
canScroll = false;
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
canScroll = true;
}
}, 0, 10);
} else {
flAdmin.foldWithAnimation();
canScroll = true;
scrollOne = false;
}
});
其中 boolean
canScroll 是静态全局变量。我尝试添加 TimerTask
使 RecyclerView
可滚动 10 毫秒,这样滚动就可以发生在这里:
rvAdmin.addOnItemTouchListener(new TchListener(this, rvAdmin, new TchListener.ClickListener() {
@Override
public void onClick(View view, int position) {
if (Adapter_Admin.canScroll)
rvAdmin.scrollToPosition(position);
}
@Override
public void onLongClick(View view, int position) {
}
}));
然后将标志恢复为 false
,但它不起作用,我没有得到预期的效果。
TchListener 是处理触摸事件的自定义侦听器。
public class TchListener implements RecyclerView.OnItemTouchListener {
private ClickListener clicklistener;
private GestureDetector gestureDetector;
public TchListener(Context context, final RecyclerView recycleView, final ClickListener clicklistener) {
this.clicklistener = clicklistener;
gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View child = recycleView.findChildViewUnder(e.getX(), e.getY());
clicklistener.onLongClick(child, recycleView.getChildAdapterPosition(child));
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child != null && clicklistener != null && gestureDetector.onTouchEvent(e)) {
clicklistener.onClick(child, rv.getChildAdapterPosition(child));
}
return false;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
public interface ClickListener {
void onClick(View view, int position);
void onLongClick(View view, int position);
}}
绞尽脑汁想了一天,想出了办法。
对于可能处于这种情况的任何人,
好吧,首先我在 EventListener
中使用了 LocalBroadCastManager
、Handler
和几个标志来实现 it.Oh 诀窍是 scrollToPositionWithOffset
.
一些代码,
private BroadcastReceiver scrollReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int scrollTo = intent.getIntExtra(ConstHelper.SCROLL_TO, 0);
boolean scroll = intent.getBooleanExtra(ConstHelper.SMOOTH_SCROLL, false);
if (scroll) {
((LinearLayoutManager) Objects.requireNonNull(rvAdmin
.getLayoutManager()))
.scrollToPositionWithOffset(scrollTo, 8);
}
}
};
这就是我 do.Send 滚动标志和滚动数量所需要的,BroadCastManager
为我完成了。
我只需要增加 RecyclerView
paddingBottom
使其也滚动到最后一项。
哦,Handler
是将标志设置回 false 以在几秒后禁用滚动;
我的 ClickListener
:
flAdmin.setOnClickListener((View v) -> {
scrollTo = getLayoutPosition();
image = beanOrders.get(getLayoutPosition()).getsImage();
message = beanOrders.get(getLayoutPosition()).getsMessage();
Intent intent = new Intent(ConstHelper.START_SCROLL);
intent.putExtra(ConstHelper.SMOOTH_SCROLL, true);
intent.putExtra(ConstHelper.SCROLL_TO, getLayoutPosition());
LocalBroadcastManager.getInstance(itemView.getContext()).sendBroadcast(intent);
if (flAdmin.isFolded()) {
flAdmin.unfoldWithAnimation();
} else {
flAdmin.foldWithAnimation();
}
new Handler().postDelayed(() -> canScroll = false, 2000);
});
干杯:)
我面临着一个相当具有挑战性的情况,我需要根据 RecyclerView
.
RecyclerView
我有 RecyclerView
个可折叠物品,可折叠物品在 ScrollView
中有一个 ImageView
。我知道这是一个糟糕的实现,因为 ScrollView
不会如果 parent 也垂直滚动。
但由于我想要此功能,我想在 ScrollView
可见时禁用 RecyclerView
中的滚动以使其滚动。我为此定制了 LayoutManager
如下:
public class ConditionalScrollManager extends LinearLayoutManager {
public ConditionalScrollManager(Context context) {
super(context);
}
ConditionalScrollManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
@Override
public boolean canScrollVertically() {
return Adapter_Admin.canScroll && super.canScrollVertically();
}
}
但是,这带来了一个问题,即无法完全看到屏幕底部的项目,因为单击项目后列表不可滚动。
标志 Adapter_Admin.canScroll
来自我的适配器:
canScroll = true;
flAdmin.setOnClickListener(v -> {
image = beanOrders.get(getLayoutPosition()).getsImage();
message = beanOrders.get(getLayoutPosition()).getsMessage();
scrollOne = true;
scrollTo = getLayoutPosition();
if (flAdmin.isFolded()) {
flAdmin.unfoldWithAnimation();
canScroll = false;
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
canScroll = true;
}
}, 0, 10);
} else {
flAdmin.foldWithAnimation();
canScroll = true;
scrollOne = false;
}
});
其中 boolean
canScroll 是静态全局变量。我尝试添加 TimerTask
使 RecyclerView
可滚动 10 毫秒,这样滚动就可以发生在这里:
rvAdmin.addOnItemTouchListener(new TchListener(this, rvAdmin, new TchListener.ClickListener() {
@Override
public void onClick(View view, int position) {
if (Adapter_Admin.canScroll)
rvAdmin.scrollToPosition(position);
}
@Override
public void onLongClick(View view, int position) {
}
}));
然后将标志恢复为 false
,但它不起作用,我没有得到预期的效果。
TchListener 是处理触摸事件的自定义侦听器。
public class TchListener implements RecyclerView.OnItemTouchListener {
private ClickListener clicklistener;
private GestureDetector gestureDetector;
public TchListener(Context context, final RecyclerView recycleView, final ClickListener clicklistener) {
this.clicklistener = clicklistener;
gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View child = recycleView.findChildViewUnder(e.getX(), e.getY());
clicklistener.onLongClick(child, recycleView.getChildAdapterPosition(child));
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child != null && clicklistener != null && gestureDetector.onTouchEvent(e)) {
clicklistener.onClick(child, rv.getChildAdapterPosition(child));
}
return false;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
public interface ClickListener {
void onClick(View view, int position);
void onLongClick(View view, int position);
}}
绞尽脑汁想了一天,想出了办法。 对于可能处于这种情况的任何人,
好吧,首先我在 EventListener
中使用了 LocalBroadCastManager
、Handler
和几个标志来实现 it.Oh 诀窍是 scrollToPositionWithOffset
.
一些代码,
private BroadcastReceiver scrollReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int scrollTo = intent.getIntExtra(ConstHelper.SCROLL_TO, 0);
boolean scroll = intent.getBooleanExtra(ConstHelper.SMOOTH_SCROLL, false);
if (scroll) {
((LinearLayoutManager) Objects.requireNonNull(rvAdmin
.getLayoutManager()))
.scrollToPositionWithOffset(scrollTo, 8);
}
}
};
这就是我 do.Send 滚动标志和滚动数量所需要的,BroadCastManager
为我完成了。
我只需要增加 RecyclerView
paddingBottom
使其也滚动到最后一项。
哦,Handler
是将标志设置回 false 以在几秒后禁用滚动;
我的 ClickListener
:
flAdmin.setOnClickListener((View v) -> {
scrollTo = getLayoutPosition();
image = beanOrders.get(getLayoutPosition()).getsImage();
message = beanOrders.get(getLayoutPosition()).getsMessage();
Intent intent = new Intent(ConstHelper.START_SCROLL);
intent.putExtra(ConstHelper.SMOOTH_SCROLL, true);
intent.putExtra(ConstHelper.SCROLL_TO, getLayoutPosition());
LocalBroadcastManager.getInstance(itemView.getContext()).sendBroadcast(intent);
if (flAdmin.isFolded()) {
flAdmin.unfoldWithAnimation();
} else {
flAdmin.foldWithAnimation();
}
new Handler().postDelayed(() -> canScroll = false, 2000);
});
干杯:)