HorizontalScrollView внутри ListView: небольшая вертикальная прокрутка останавливает горизонтальную прокрутку
В моем примере деятельности у меня есть
- ListView, содержащий
- несколько HorizontalScrollView, содержащие
- набор TextView
Хотя горизонтальная прокрутка довольно плохая.
Когда я запускаю горизонтальную прокрутку (или бросание), я должен быть очень осторожным, чтобы она работала.
Как только горизонтальная прокрутка содержит (небольшой) вертикальный компонент, вертикальная прокрутка ListView вступает во владение и полностью останавливает горизонтальную прокрутку.
Любое предложение о том, как улучшить это?
Заранее спасибо,
Марк
import 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);
}
}
4 ответа
Проблема в том, что 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.
поскольку просмотр списка автоматически прокручивается, поэтому держите его вне scrollView, в то время как другие вещи могут быть в scrollView.
проверьте, является ли это сценарий, иначе поделитесь XML Layout
Лучший способ сделать это.
поместите данный код в ваш горизонтальный список на метод Scroll
ViewParent view_parent = getParent();
if (view_parent != null)
{
view_parent.requestDisallowInterceptTouchEvent(true);
}
У Android есть концепция, которая называется touch slop. Вот на подобный вопрос уже ответили: Android ACTION_MOVE Threshold