我面临一个相当具有挑战性的情况,我需要根据RecyclerView
中触摸事件提供的标记自动并定期滚动RecyclerView
。
我有一个RecyclerView
的可折叠物品,而可折叠的物品在ImageView
内有一个ScrollView
。这是一个很差的实现方式,因为我知道ScrollView
不会垂直滚动如果父母也这样做的话。
但是,由于我需要此功能,因此我想到了在RecyclerView
可见时禁止在ScrollView
中滚动,以使其滚动。我为此做了一个自定义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);
}}
答案 0 :(得分:0)
头呆了一天后,我想出了办法。 对于任何可能遇到这种情况的人,
首先,我在我的LocalBroadCastManager
中使用了Handler
,EventListener
和几个标志来实现它。哦,诀窍是scrollToPositionWithOffset
。 / p>
某些代码
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);
}
}
};
这就是我要做的。发送标志滚动并滚动滚动,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);
});
欢呼:)