【问题标题】:HorizontalScrollView inside ListView: minor vertical scroll stops horizontal scrollListView 内的 Horizo​​ntalScrollView:较小的垂直滚动停止水平滚动
【发布时间】:2011-11-07 11:25:39
【问题描述】:

在我的示例活动中,我有
- 一个 ListView 包含
- 多个 Horizo​​ntalScrollView 包含
- 一组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);

}


}

【问题讨论】:

  • 我想我可以将这个问题重新表述为“子视图是否有可能接收 ListView 父级消耗的 TouchEvents”。这将允许 ListView 处理我的移动的垂直分量,而 Horizo​​ntalScrollView 可以处理移动的水平分量。

标签: android android-layout


【解决方案1】:

问题是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 进行控制。

【讨论】:

    【解决方案2】:

    虽然我没有深入了解您的代码,但人们犯的一般错误是将 listView 插入 ScrollView 。

    因为 listview 是自动滚动的,所以将它放在 scrollView 之外,而其他东西可能在 scrollView 中。

    检查是否是这种情况,否则共享 XML 布局

    【讨论】:

    • 我的 ListView 是父组件,Horizo​​ntalScrollViews 是 ListView 的子组件(所以它似乎与您的场景相反)。我不使用 XML 布局;所有视图都是在代码中创建的。
    【解决方案3】:

    Android 有一个概念叫做触摸倾斜。这是已经回答的类似问题:Android ACTION_MOVE Threshold

    【讨论】:

    • 我不认为 mTouchSlop 在这里是相关的。最初的问题是较小的垂直滚动会停止水平滚动,因为此时 ListView 正在接管。
    【解决方案4】:

    最好的方法。

    将给定的代码放在你的水平列表视图 onScroll 方法上,它可以正常工作

       ViewParent view_parent = getParent();
       if (view_parent != null) 
       {
         view_parent.requestDisallowInterceptTouchEvent(true);
       }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-23
      • 1970-01-01
      • 1970-01-01
      • 2019-06-27
      • 1970-01-01
      相关资源
      最近更新 更多