gpt4 book ai didi

android - 当 Listview 在顶部/底部时将运动事件传递给父 Scrollview

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:29:19 25 4
gpt4 key购买 nike

我在 ScrollView 中有一个 ListView 来显示评论,我想执行以下操作:

当用户向下滑动时,首先 ScrollView 应该完全向下滚动,因为列表位于底部。一旦完全关闭,Listiew 应该开始滚动。

类似地,当用户向上滚动时,首先 ListView(此处顺序颠倒!)应该在 ScrollView 开始滚动之前向上滚动。

到目前为止,我已经完成了以下工作:

listView.setOnTouchListener(new View.OnTouchListener() {
// Setting on Touch Listener for handling the touch inside ScrollView
@Override
public boolean onTouch(View v, MotionEvent event) {

// If going up but the list is already at up, return false indicating we did not consume it.
if(event.getAction() == MotionEvent.ACTION_UP) {
if (listView.getChildCount() == 0 && listView.getChildAt(0).getTop() == 0) {
Log.e("Listview", "At top!");
return false;
}
}

// Similar behaviour but when going down check if we are at the bottom.
if( event.getAction() == MotionEvent.ACTION_DOWN) {
if (listView.getLastVisiblePosition() == listView.getAdapter().getCount() - 1 &&
listView.getChildAt(listView.getChildCount() - 1).getBottom() <= listView.getHeight()) {
Log.e("Listview","At bottom!");
v.getParent().requestDisallowInterceptTouchEvent(false);
return false;
}
}
v.getParent().requestDisallowInterceptTouchEvent(true);
return false;
}
});

日志在正确的时刻触发,但是即使我返回 false,ScrollView 也不会移动。

我还尝试将 v.getParent().requestDisallowInterceptTouchEvent(false); 添加到语句中,但这也不起作用。

我怎样才能让它发挥作用?

最佳答案

您可以创建自定义的 ScrollViewListView 并覆盖

onInterceptTouchEvent(MotionEvent event)

像这样:

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
View view = (View) getChildAt(getChildCount()-1);
int diff = (view.getBottom()-(getHeight()+getScrollY()));

if( event.getAction() == MotionEvent.ACTION_DOWN) {
if (diff ==0) {
return false;
}
}

return super.onInterceptTouchEvent(event);
}

这样,当您位于 ScrollView 底部时,ListView 上的每次向下触摸都会转到 ListView

这只是一个草图实现,但我认为您可以从这里开始,做同样的事情来检测您何时位于 ListView

的顶部

请注意,我会尝试使用 ListView 和您的当前内容 ScrollView 通过使用 listView 添加为 ListView 的标题来尝试更简单的实现.addHeaderView(scrollViewContent)。我不知道这是否符合您的需求。

编辑:

检测何时应该开始滚动 ScrollView。在 ScrollView 中保留对 ListView 的引用。当用户向上滚动并且 ListView 位于顶部时,让 ScrollView 使用该事件。

private void init(){
ViewConfiguration vc = ViewConfiguration.get(getContext());
mTouchSlop = vc.getScaledTouchSlop();
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
final int action = MotionEventCompat.getActionMasked(event);

switch (action) {
case MotionEvent.ACTION_DOWN:{
yPrec = event.getY();
}
case MotionEvent.ACTION_MOVE: {
final float dy = event.getY() - yPrec;

if (dy > mTouchSlop) {
// Start scrolling!
mIsScrolling = true;
}
break;
}
}

if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
mIsScrolling = false;
}

// Calculate the scrolldiff
View view = (View) getChildAt(getChildCount()-1);
int diff = (view.getBottom()-(getHeight()+getScrollY()));

if ((!mIsScrolling || !listViewReference.listIsAtTop()) && diff == 0) {
if (event.getAction() == MotionEvent.ACTION_MOVE) {
return false;
}
}

return super.onInterceptTouchEvent(event);
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
final int action = MotionEventCompat.getActionMasked(ev);
if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
mIsScrolling = false;
}
return super.onTouchEvent(ev);
}


public void setListViewReference(MyListView listViewReference) {
this.listViewReference = listViewReference;
}

ListView 中的 listIsAtTop 方法如下所示:

public boolean listIsAtTop()   {
if(getChildCount() == 0) return true;
return (getChildAt(0).getTop() == 0 && getFirstVisiblePosition() ==0);
}

关于android - 当 Listview 在顶部/底部时将运动事件传递给父 Scrollview,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32631547/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com