Goo*_*oey 9 android listview scrollview motionevent
我有一个ListView在ScrollView显示意见,我想做到以下几点:
当用户向下滑动时,首先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;
}
});
Run Code Online (Sandbox Code Playgroud)
日志会在合适的时刻触发,但ScrollView即使我返回false也不会移动.
我也尝试添加v.getParent().requestDisallowInterceptTouchEvent(false);到语句中,但这也没有用.
我怎样才能使它工作?
您可以创建自定义ScrollView和ListView和覆盖
onInterceptTouchEvent(MotionEvent event)
Run Code Online (Sandbox Code Playgroud)
像这样:
@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);
}
Run Code Online (Sandbox Code Playgroud)
这样ListView,你在底部的每一次Down Touch ScrollView都会转到ListView.
这只是一个草图实现,但我认为你可以通过做同样的事情来检测你何时处于最顶层 ListView
作为一个注释,我将尝试使用一个简单的实现,使用ListView您ScrollView添加的当前内容作为ListView的标题使用listView.addHeaderView(scrollViewContent).我不知道这是否符合您的需求.
编辑:
检测何时应该开始滚动ScrollView.保持一个参考ListView的ScrollView.当用户向上滚动并且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;
}
Run Code Online (Sandbox Code Playgroud)
ListView中的方法listIsAtTop如下所示:
public boolean listIsAtTop() {
if(getChildCount() == 0) return true;
return (getChildAt(0).getTop() == 0 && getFirstVisiblePosition() ==0);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6456 次 |
| 最近记录: |