【问题标题】:Android - ListView inside Gallery makes the scrolling not SmoothAndroid - Gallery 中的 ListView 使滚动不平滑
【发布时间】:2012-06-15 21:24:07
【问题描述】:

我实现了一个画廊,在里面我从左到右有很多列表视图。 出于某种原因,Gallery 适用于所有视图,但不适用于 listview。 使用 listview,在画廊上滚动时,有时我会有点跳跃。

有人知道如何解决这个问题吗?

一些注意事项:图库使用适配器找出要显示的内容,然后根据适配器创建列表视图

谢谢

【问题讨论】:

  • 一些代码会有所帮助。以及一个屏幕截图,以了解“画廊内的列表视图”是什么意思。
  • 你在这里指的是什么手势检测器? @Override public boolean onTouchEvent(MotionEvent event) { return groupGalleryView.getGestureDetector().onTouchEvent(event);当列表视图在画廊中时,我真的无法消除闪烁!即使列表视图是 list.setClickable(false); list.setEnable(false);我得到了闪烁!啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊!

标签: android


【解决方案1】:

我遇到了类似的问题。问题是 ListView 正在拦截来自您的 Gallery 的触摸事件,并在其处理 ListView 垂直滚动的代码块中修改视图位置。如果只有 Gallery 首先拦截了触摸事件...我认为这是 Android 源代码中的一个错误,但与此同时,您可以通过子类化 Gallery 并改用您的子类来修复不平滑的滚动。这样就可以了:

public class BetterGallery extends Gallery {
    private boolean scrollingHorizontally = false;

    public BetterGallery(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public BetterGallery(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public BetterGallery(Context context) {
        super(context);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        super.onInterceptTouchEvent(ev);
        return scrollingHorizontally;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        scrollingHorizontally = true;
        return super.onScroll(e1, e2, distanceX, distanceY);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch(event.getAction()) {
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_CANCEL:
            scrollingHorizontally = false;
        }

        return super.onTouchEvent(event);
    }
}

另外,在实现画廊的 Activity 中设置如下内容:

    ListView listView = (ListView) view.findViewById(R.id.users);
    listView.setAdapter(userListAdapter);
    listView.setOnTouchListener(new OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {
        galleryView.onTouchEvent(event);
        return false;
        }           
    });

最后,将 onTouchEvent() 添加到活动本身:

@Override
public boolean onTouchEvent(MotionEvent event) {
return galleryView.onTouchEvent(event);
}

最后一点...在完全实现之后,我发现从可用性的角度来看,最好使用我称为 AdaptableViewAnimator 的自定义类扩展 ViewAnimator,当然它只是嵌入了一些适配器功能,并嵌入里面的ListView。它不像 ListView-inside-Gallery 那样浮动。

【讨论】:

  • 已经实现了这个并且滚动效果很好但是这个画廊不会左右滚动。
  • 我编辑了附加要求迈克尔的答案。感谢您的反馈
  • 你好,可以把xml放上去吗,我也想做这个效果,能不能帮帮我,这样可以节省我很多时间,谢谢
  • 更正底部两个代码块:gallery是gestureDetector,所以两个引用应该是:galleryView.onTouchEvent(event);
  • +1 用于在编写代码之前提及“滚动不流畅”;)
【解决方案2】:

其他可滚动项目内的可滚动项目往往会出现问题。我并不惊讶这不能很好地工作。

【讨论】:

  • 我尝试了相反的方法,效果很好。我放了 1 个列表视图,在每个项目中,我画了一个画廊,它的效果令人惊讶。我查看了 android 源代码,它们的实现方式不同,这就是为什么一个有效而另一个无效的原因。我想我需要构建一个自定义布局。对此有什么建议吗?谢谢
  • @CommonsWare 先生,什么是更好的选择?
  • @Gaurav: Gallery 已被弃用。 ListViews 作为 ViewPager 中的页面应该可以工作。
【解决方案3】:

我也有同样的问题。而且解决方案并不简单。

    • 将列表视图设置为在触摸模式下不可聚焦。

    listView.setFocusableInTouchMode(false);

    • 如果您需要焦点,请从 onItemSelected 侦听器中调用它。
  1. 使用 OnInterceptTouchEvent 从您的孩子那里获取触摸事件。并在您的 Gallery 的 onScroll 和 onTouchEvent 中进行一些修改

    OnItemSelectedListener mOnItemSelected = new OnItemSelectedListener()
    {   
        @Override
        public void onItemSelected(AdapterView<?> parent, View view,
                int position, long id)
        {
          view.requestFocusFromTouch();
        }
        @Override
        public void onNothingSelected(AdapterView<?> parent)
        {               
        }
    };
    
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        onTouchEvent(ev);
        return scrollingHorizontally;
    }
    
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        if(Math.abs(distanceX)>Math.abs(distanceY) || scrollingHorizontally == true){
            scrollingHorizontally = true;
            super.onScroll(e1, e2, distanceX, distanceY);
        }
        return scrollingHorizontally;
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch(event.getAction()) {
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_CANCEL:
            scrollingHorizontally = false;
            break;
        default:
                break;
        }
        super.onTouchEvent(event);
        return scrollingHorizontally;
    }
    

【讨论】:

  • 这对我有用,谢谢!比 jkschneider 的解决方案更好,它允许 Gallery 见证来自 ListView 的滚动事件,但有一些奇怪的“弹跳”效果和滚动阻力。
【解决方案4】:

这对我有用

listView.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);

【讨论】:

    猜你喜欢
    • 2018-12-30
    • 2011-09-11
    • 2017-03-12
    • 2014-01-12
    • 1970-01-01
    • 2016-05-06
    • 2015-05-01
    • 1970-01-01
    • 2011-06-24
    相关资源
    最近更新 更多