使 ListView 的行为像垂直画廊一样

发布于 2024-12-01 02:06:07 字数 2519 浏览 0 评论 0原文

我有以下代码,使 ListView 显示为垂直画廊

public class VerticalGallery extends ListView {
    private View currentDisplayingView;
    private int currentPosition;

    public VerticalGallery(Context context, List<Page> pages) {
            super(context);

        setOnItemSelectedListener(new OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                currentDisplayingView = view;
                currentPosition = position;
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });

        setAdapter(new PageAdapter(context, pages));

        setCacheColorHint(Color.TRANSPARENT);
    }

    public boolean onTouchEvent(MotionEvent evt) {
        if (currentDisplayingView != null && currentDisplayingView.onTouchEvent(evt))
            return true;

        PageAdapter adapter = (PageAdapter) getAdapter();

        if (currentPosition == adapter.list.size() - 1)
            return false;

        // TODO: Handle events and swipe somewhere
        return super.onTouchEvent(evt);
    }

    public class PageAdapter extends BaseAdapter {
        private Context context;
        private List<Page> list;

        public PageAdapter(Context c, List<Page> pages) {
            context = c;
            list = pages;
        }

        public int getCount() {
            return list.size();
        }

        public Page getItem(int position) {
            return list.get(position);
        }

        public long getItemId(int position) {
            return position;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            View view = getItem(position).generateView(context);
            view.setLayoutParams(new ListView.LayoutParams(LayoutParams.MATCH_PARENT,
                    LayoutParams.MATCH_PARENT));
            return view;
        }
    }    
}

,但我还需要模拟一些行为:

  • 集中视图: 当出现新视图时,我需要将其集中在我的显示屏上。
  • 触发 onItemSelected 事件: 我需要这些,因为我将事件分派到当前视图,并且仅当 currentView 在 touchEvent 上返回 false 时才让 ListView 滚动,我并不需要 ItemSelected 事件,这可能是类似的事情。
  • 另一个问题是,如果用户向上滑动,我应该只翻译一个视图(而不是根据手势的速度翻译多个视图)。

任何能让我做到这一点的组件也将是一个有用的答案。

编辑: 实际上,我用这个解决方案解决了这个问题使用动画来滑动视图但我会保持这个问题的开放性。

I have the following code that make the ListView appears like a Vertical Gallery

public class VerticalGallery extends ListView {
    private View currentDisplayingView;
    private int currentPosition;

    public VerticalGallery(Context context, List<Page> pages) {
            super(context);

        setOnItemSelectedListener(new OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                currentDisplayingView = view;
                currentPosition = position;
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });

        setAdapter(new PageAdapter(context, pages));

        setCacheColorHint(Color.TRANSPARENT);
    }

    public boolean onTouchEvent(MotionEvent evt) {
        if (currentDisplayingView != null && currentDisplayingView.onTouchEvent(evt))
            return true;

        PageAdapter adapter = (PageAdapter) getAdapter();

        if (currentPosition == adapter.list.size() - 1)
            return false;

        // TODO: Handle events and swipe somewhere
        return super.onTouchEvent(evt);
    }

    public class PageAdapter extends BaseAdapter {
        private Context context;
        private List<Page> list;

        public PageAdapter(Context c, List<Page> pages) {
            context = c;
            list = pages;
        }

        public int getCount() {
            return list.size();
        }

        public Page getItem(int position) {
            return list.get(position);
        }

        public long getItemId(int position) {
            return position;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            View view = getItem(position).generateView(context);
            view.setLayoutParams(new ListView.LayoutParams(LayoutParams.MATCH_PARENT,
                    LayoutParams.MATCH_PARENT));
            return view;
        }
    }    
}

But there's some behaviors that I need to simulate also:

  • Centralize a View:
    When a new view come, I need to centralize it on my display.
  • Fire onItemSelected events:
    I need those cause I dispatch events to the current view, and let the ListView scroll only when the currentView returns false on a touchEvent, I don't need exactly the ItemSelected events, this can be something similar.
  • And another question is, if the user swipe up, I should only translate one view (not several according to the speed of the gesture).

Any component that will let me do that will be a usefull answer also.

EDIT:
Actually, I solved this problem with this solution Using Animation to swipe views but I'll keep this question open.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

_蜘蛛 2024-12-08 02:06:07

如何同时实现 ontouch 和 onfling在同一个列表视图中?

阅读有关 GestureListener 类实现的问题接受的答案。

将 MyGestureListener 类设置为当前类的内部类,或将 ListView 对象传递给 MyGestureListener 类的构造函数。

在 onFling() 方法中测量初始触摸和最终触摸之间的差异,例如

 @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        if(e1.getY() > e2.getY()) //1
        {
            int pos=(int)Math.floor(listView.getLastVisiblePosition/2);//2
            if(pos < listView.getLastVisiblePosition())
                      listView.smoothScrollToPosition(pos--);//3
            else
                listView.smoothScrollToPosition(listView.getLastVisiblePosition());
        }
        else
        {
               int pos=(int)Math.floor(listView.getLastVisiblePosition/2);
            if(pos < listView.getLastVisiblePosition && pos > listView.getFirstVisiblePosition())
                      listView.smoothScrollToPosition(pos++);
                   else
                        listView.smoothScrollToPosition(listView.getFirstVisiblePosition());
        }                
    } 
  1. if e1.getY() > > e2.getY() 表示用户向下滑动。 e2.getY() - e1.getY() 的差值为负。

  2. 假设当前位置是中间位置。

  3. 向下移动一位。

该代码未经测试,是对您的第三个问题的回应。我只是向你指出我的想法。

how to implement both ontouch and also onfling in a same listview?

Read this question accepted answer about implementations of GestureListener class.

Make MyGestureListener class as inner in your current one or pass ListView object to the constructor of the MyGestureListener class.

In onFling() method measure the difference between initial and final touches like

 @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        if(e1.getY() > e2.getY()) //1
        {
            int pos=(int)Math.floor(listView.getLastVisiblePosition/2);//2
            if(pos < listView.getLastVisiblePosition())
                      listView.smoothScrollToPosition(pos--);//3
            else
                listView.smoothScrollToPosition(listView.getLastVisiblePosition());
        }
        else
        {
               int pos=(int)Math.floor(listView.getLastVisiblePosition/2);
            if(pos < listView.getLastVisiblePosition && pos > listView.getFirstVisiblePosition())
                      listView.smoothScrollToPosition(pos++);
                   else
                        listView.smoothScrollToPosition(listView.getFirstVisiblePosition());
        }                
    } 
  1. if e1.getY() > e2.getY() means that user fling-ed downwards. The difference e2.getY() - e1.getY() is negative.

  2. Suppose that current position is the middle one.

  3. Moving downwards for one position.

This code isn't tested and is response to your 3rd question. I'm just pointing you my idea.

倾城°AllureLove 2024-12-08 02:06:07

在我研究的过程中,我开发了这个可以进行分页的自定义 ScrollView。

公共类 ScrollViewVertical 扩展 ScrollView {
私有布尔分页;

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

public boolean onTouchEvent(MotionEvent evt) {
    if (evt.getAction() == MotionEvent.ACTION_UP)
        if (isPaging()){
            centralizeContent();
            return true;
        }

    return super.onTouchEvent(evt);
}

private void centralizeContent() {
    int currentY = getScrollY() + getHeight() / 2;
    ViewGroup content = (ViewGroup) getChildAt(0);
    for (int i = 0; i < content.getChildCount(); i++) {
        View child = content.getChildAt(i);
        System.out.println(BoundsUtils.from(child));
        if (child.getTop() < currentY && child.getBottom() > currentY) {
            smoothScrollTo(0, child.getTop());
            break;
        }
    }
}

}

As I research, I developed this custom ScrollView that does pagination.

public class ScrollViewVertical extends ScrollView {
private boolean paging;

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

public boolean onTouchEvent(MotionEvent evt) {
    if (evt.getAction() == MotionEvent.ACTION_UP)
        if (isPaging()){
            centralizeContent();
            return true;
        }

    return super.onTouchEvent(evt);
}

private void centralizeContent() {
    int currentY = getScrollY() + getHeight() / 2;
    ViewGroup content = (ViewGroup) getChildAt(0);
    for (int i = 0; i < content.getChildCount(); i++) {
        View child = content.getChildAt(i);
        System.out.println(BoundsUtils.from(child));
        if (child.getTop() < currentY && child.getBottom() > currentY) {
            smoothScrollTo(0, child.getTop());
            break;
        }
    }
}

}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文