在我的示例活动中,我有
-一个包含
的ListView-多个包含
的HorizontalScrollView-一组TextView
水平滚动体验相当糟糕。
当我启动一个水平滚动(或投掷)时,我必须非常小心地使它工作。
只要水平滚动包含一个(小的)垂直组件,垂直的ListView滚动就会接管并完全停止水平滚动。
有什么改进的建议吗?
提前感谢,
Marcimport android.app.Activity;
import android.database.DataSetObserver;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class Test extends Activity
{
private final static int N = 20;//number of HorizontalScrollView
private final static int M = 20;//number of TextViews inside a single HorizontalScrollView
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
//create a list of HorizontalScrollViews
final HorizontalScrollView[] hors = new HorizontalScrollView[N];
for (int i = 0; i < hors.length; i++)
{
hors[i] = new HorizontalScrollView(this, null);
hors[i].setMinimumHeight(60);
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.HORIZONTAL);
hors[i].addView(ll);
for (int j = 0; j < M; j++)
{
TextView t = new TextView(Test.this);
t.setText("HorizontalScrollView: "+i+"; TextView: "+j);
t.setMinimumHeight(40);
ll.addView(t);
}
}
//add a ListView
ListView list = new ListView(this);
layout.addView(list);
list.setAdapter(new BaseAdapter()
{
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
return hors[position];
}
@Override
public long getItemId(int position)
{
return 0;
}
@Override
public Object getItem(int position)
{
return hors[position];
}
@Override
public int getCount()
{
return N;
}
});
setContentView(layout);
}
}
问题是ListView
(或者更确切地说是它的父AbsListView
)实现了onInterceptTouchEvent
,因此ListView
可以拦截所有的触摸事件,只要它认为它是在一个更好的位置来处理它们。
这可以通过调用requestDisallowInterceptTouchEvent
来避免,例如,通过子类化HorizontalScrollView
并在其dispatchTouchEvent
中:
public boolean dispatchTouchEvent(MotionEvent ev)
{
boolean ret = super.dispatchTouchEvent(ev);
if(ret)
{
requestDisallowInterceptTouchEvent(true);
}
return ret;
}
它需要一些改进(比如只有当水平组件大于垂直组件时才调用requestDisallowInterceptTouchEvent
),因为现在它几乎不允许ListView
控制。
虽然我没有深入你的代码,但一般人做的错误是插入listView在ScrollView
因为listview是自动滚动的,所以当其他东西可能在scrollView中时,把它放在scrollView外面。
检查是否符合此场景,否则共享XML布局
Android有一个概念叫做触控斜坡。Android的ACTION_MOVE阈值
这是最好的办法。
把给定的代码放在你的水平listview的onScroll方法它工作完美
ViewParent view_parent = getParent();
if (view_parent != null)
{
view_parent.requestDisallowInterceptTouchEvent(true);
}