Android:开启和关闭ListView滚动 [英] Android: Turn ListView Scrolling on and off

查看:114
本文介绍了Android:开启和关闭ListView滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有签名捕获控件的ListView.当用户触及签名捕获控件时,我需要阻止ListView滚动-现在发生的事情是捕获控件上的水平笔划起作用,但是垂直笔划画了一条小线,然后开始滚动ListView.

我找不到打开和关闭ListView滚动的简单方法.在StackOverflow上有一些示例,但是很少有人接受答案,而且我尝试了许多看起来很有希望而没有成功的解决方案.我觉得可能有一种方法可以告诉签名捕获组件拦截触摸事件,而不是将它们进一步传递到事件链中,但是我不知道那是什么.

我的签名捕获是在此处找到的签名捕获的略微修改的版本: http://www.mysamplecode.com/2011/11/android-capture-signature-using-canvas.html

功能代码都一样.

有关此问题的SS,请参见 http://imgur.com/WbfgTkj .绿色突出显示的区域是签名捕获区域.请注意,它位于列表视图的底部,必须滚动才能到达它.

解决方案

好吧,我想通了;我想为下一个偶然发现这个问题的人留下答案是很公平的.我向Java纯粹主义者表示歉意,我像C#一样编写Java.我也在边走边弄清楚这件事.

解决方案是创建一个自定义ListView.它的神奇之处在于它可以选择打开和关闭触摸事件分派(特别是ACTION_MOVE,它可以滚动).这是代码:

 公共类UnScrollingListView扩展了ListView {公共UnScrollingListView(上下文上下文,AttributeSet属性,int defStyle){超级(上下文,属性,defStyle);}公共UnScrollingListView(Context context,AttributeSet attrs){super(context,attrs);}公共UnScrollingListView(上下文上下文){super(context);}公共布尔DisableTouchEventScroll = false;受保护的布尔DispatchMoveEventInsteadOfConsumingIt = false;受保护的View DispatchTarget = null;公共无效ResetToNormalListViewBehavior(){DisableTouchEventScroll = false;DispatchMoveEventInsteadOfConsumingIt = false;DispatchTarget = null;}公共无效SetUpDispatch(查看v){DisableTouchEventScroll = true;DispatchMoveEventInsteadOfConsumingIt = true;DispatchTarget = v;}受保护的静态float [] GetRelativeCoordinates(View innerView,MotionEvent e){int [] screenCoords = new int [2];//不确定我是否必须预先分配它.innerView.getLocationOnScreen(screenCoords);返回新的float [] {e.getRawX()-screenCoords [0],e.getRawY()-screenCoords [1]};}@Override布尔布尔dispatchTouchEvent(MotionEvent ev){if(DispatchMoveEventInsteadOfConsumingIt&& DispatchTarget!= null){//转换坐标系float [] newCoords = GetRelativeCoordinates(DispatchTarget,ev);ev.setLocation(newCoords [0],newCoords [1]);DispatchTarget.onTouchEvent(ev);返回true;}if(DisableTouchEventScroll&& ev.getAction()== MotionEvent.ACTION_MOVE){返回true;}返回super.dispatchTouchEvent(ev);}} 

默认情况下,它的行为类似于普通的列表视图.您可以调用SetUpDispatch(View)告诉它停止滚动列表视图,并将所有ACTION_MOVE事件分派到特定的View.然后,您可以调用ResetToNormalListViewBehavior()使其重新开始滚动.将签名捕获代码链接到我的原始帖子中,您所需要做的就是在onTouchEvent中更改以下内容:

 开关(event.getAction()){案例MotionEvent.ACTION_DOWN:...listView.SetUpDispatch(this);返回true;案例MotionEvent.ACTION_UP:listView.ResetToNormalListViewBehavior();案例MotionEvent.ACTION_MOVE:... 

不确定是否有人会遇到此问题,但是似乎有一些通用的应用程序,因此,如果您阅读过此书,祝您好运.

I have a ListView that has a signature capture control in it. When the user touches down on the signature capture control I need to prevent the ListView from scrolling -- what happens now is that horizontal strokes on the capture control work, but vertical strokes draw a small line and then start the scroll the ListView.

I cannot find an easy way to turn ListView scrolling on and off. There are some examples on StackOverflow, but few have accepted answers, and I've tried many of the solutions that looked promising without success. I feel like there is probably a way to tell the signature capture component to intercept the touch events and not pass them further up the event chain, but I don't know what that is.

My signature capture is a slightly modified version of the one found here: http://www.mysamplecode.com/2011/11/android-capture-signature-using-canvas.html

The functional code is all the same.

See http://imgur.com/WbfgTkj for a SS of the issue. The area highlighted in green is the signature capture area. Note that it is at the bottom of the listview and must be scrolled to reach it.

解决方案

Well I figured it out; I guess it's only fair to leave an answer behind for the next guy who stumbles onto this question. I apologize in advance to Java purists, I write Java like C#. I'm also kind of figuring out this Android thing as I go.

The solution was to create a custom ListView. The magic in it is that it has the option to turn touch-event dispatching (specifically ACTION_MOVE, which is the one that does scrolling) on and off. Here's the code:

public class UnScrollingListView extends ListView {

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

public boolean DisableTouchEventScroll = false;

protected boolean DispatchMoveEventInsteadOfConsumingIt = false;
protected View DispatchTarget = null;

public void ResetToNormalListViewBehavior() {
    DisableTouchEventScroll = false;
    DispatchMoveEventInsteadOfConsumingIt = false;
    DispatchTarget = null;
}

public void SetUpDispatch(View v) {
    DisableTouchEventScroll = true;
    DispatchMoveEventInsteadOfConsumingIt = true;
    DispatchTarget = v;
}

protected static float[] GetRelativeCoordinates(View innerView, MotionEvent e) {
    int[] screenCoords = new int [2];       //not sure if I have to preallocate this or not.
    innerView.getLocationOnScreen(screenCoords);
    return new float[] {
        e.getRawX() - screenCoords[0],
        e.getRawY() - screenCoords[1]};
}

@Override
public boolean dispatchTouchEvent(MotionEvent ev){
    if(DispatchMoveEventInsteadOfConsumingIt && DispatchTarget != null) {
        //convert coordinate systems
        float[] newCoords = GetRelativeCoordinates(DispatchTarget, ev);
        ev.setLocation(newCoords[0], newCoords[1]);

        DispatchTarget.onTouchEvent(ev);
        return true;
    }

    if(DisableTouchEventScroll && ev.getAction() == MotionEvent.ACTION_MOVE) {
        return true;
   }

   return super.dispatchTouchEvent(ev);
}
}

This behaves like a normal listview by default. You can call SetUpDispatch(View) to tell it to stop scrolling the listview and dispatch all ACTION_MOVE events to a specific View. You can then call ResetToNormalListViewBehavior() to make it start scrolling again. With the signature capture code linked in my original post, all you need to do is change the following in the onTouchEvent:

switch (event.getAction()) 
{
    case MotionEvent.ACTION_DOWN:
        ...
        listView.SetUpDispatch(this);
        return true;

    case MotionEvent.ACTION_UP:
        listView.ResetToNormalListViewBehavior();

    case MotionEvent.ACTION_MOVE:
        ...

Not sure if anyone will ever encounter this problem, but it seems to have some general applications, so good luck with it if you ever read this.

这篇关于Android:开启和关闭ListView滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆