appwidget左右滑动更新

  上一篇讲了如何用代码的方式把appwidget添加到桌面上,如果没看的话可以看一下http://blog.csdn.net/so_strange/article/details/51014151

          前面我把appwidget添加到桌面上后,客户又提出了要添加左右滑动翻页的要求.我们知道,appwidget用的是RemoteViews,我又用了GridView,想要滑动翻页,必须要对事件做处理,RemoteViews有不支持自定义的view,目前对我来讲,我还没有找到让RemoteViews支持自定义view的方法.所以我只能在appwidget的父view上面想办法.先上代码:

  

public class RecommendationWidgetLayout extends RelativeLayout {

    private static final String WIDGET_TURN_TO_PREV_PAGE_ACTION = "com.android.bookstore.provider.BUT_PREV_PAGE_ACTION";
    private static final String WIDGET_TURN_TO_NEXT_PAGE_ACTION = "com.android.bookstore.provider.BUT_NEXT_PAGE_ACTION";
    private float lastX;

    public RecommendationWidgetLayout(Context context) {
        this(context, null);
    }

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

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch(ev.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                lastX = ev.getX();
                break;
            case MotionEvent.ACTION_MOVE:
                return detectDirection(ev) != PageTurningDirection.None;
            case MotionEvent.ACTION_UP:
            default:
                break;
        }
        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                lastX = event.getX();
                break;
            case MotionEvent.ACTION_UP:
                PageTurningDirection direction = detectDirection(event);
                if (direction == PageTurningDirection.Left) {
                    turnToPrevPage();
                } else if (direction == PageTurningDirection.Right) {
                    turnToNextPage();
                }
                break;
            default:
                break;
        }
        return true;
    }

    private void turnToPrevPage() {
        sendUpdateWidgetBroadcast(WIDGET_TURN_TO_PREV_PAGE_ACTION);
    }

    private void turnToNextPage() {
        sendUpdateWidgetBroadcast(WIDGET_TURN_TO_NEXT_PAGE_ACTION);
    }

    private PageTurningDirection detectDirection(MotionEvent currentEvent) {
        return PageTurningDetector.detectLeftOrRight(getContext(), (int) (currentEvent.getX() - lastX));
    }

    private void sendUpdateWidgetBroadcast(String action) {
        getContext().sendBroadcast(new Intent(action));
    }
}
public abstract class PageTurningDetector {

    public static PageTurningDirection detectLeftOrRight(Context context, int deltaX)
    {
        int x_DELTA_THRESHOLD = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, context.getResources().getDisplayMetrics());
        if (Math.abs(deltaX) < x_DELTA_THRESHOLD) {
            return PageTurningDirection.None;
        }

        return deltaX > 0 ? PageTurningDirection.Left : PageTurningDirection.Right;
    }
 
  首先自定义的layout继承RelativeLayout,因为这里只是简单的添加一个AppWidgetHostView,所以只需要重写onInterceptTouchEvent和onTouchEvent这两个方法. onInterceptTouchEvent是viewgroup的方法,目的是在系统向该ViewGroup及其各个childView触发onTouchEvent()之前对相关事件进行一次拦截,Android这么设计的想法也很好理解,由于ViewGroup会包含若干childView,因此需要能够统一监控各种touch事件的机会,因此纯粹的不能包含子view的控件是没有这个方法的,如LinearLayout就有,TextView就没有。
   onInterceptTouchEvent()使用也很简单,如果在ViewGroup里覆写了该方法,那么就可以对各种touch事件加以拦截。但是如何拦截,是否所有的touch事件都需要拦截则是比较复杂的,touch事件在onInterceptTouchEvent()和onTouchEvent以及各个childView间的传递机制完全取决于onInterceptTouchEvent()和onTouchEvent()的返回值。并且,针对down事件处理的返回值直接影响到后续move和up事件的接收和传递。

  关于返回值的问题,基本规则很清楚,如果return true,那么表示该方法消费了此次事件,如果return false,那么表示该方法并未处理完全,该事件仍然需要以某种方式传递下去继续等待处理。

  1.down事件首先会传递到onInterceptTouchEvent()方法

  2.如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return false,那么后续的move, up等事件将继续会先传递给该ViewGroup,之后才和down事件一样传递给最终的目标view的onTouchEvent()处理。

  3.如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return true,那么后续的move, up等事件将不再传递给onInterceptTouchEvent(),而是和down事件一样传递给该ViewGroup的onTouchEvent()处理,注意,目标view将接收不到任何事件。

  4.如果最终需要处理事件的view的onTouchEvent()返回了false,那么该事件将被传递至其上一层次的view的onTouchEvent()处理。

  5.如果最终需要处理事件的view 的onTouchEvent()返回了true,那么后续事件将可以继续传递给该view的onTouchEvent()处理。

  上面这段话摘自http://blog.csdn.net/lvxiangan/article/details/9309927,分析的很好,大家一看就明白了,我就不在这里画蛇添足了.(奋斗其实我是菜鸟...你懂的...)

  在detectLeftOrRight()函数里有一个20,这个就是滑动距离的参照,如果滑动的距离小于它,就不算是滑动,不用拦截.当然这个你自己在实际过程中可以自己改动.

  至于更新widget肯定是发广播了,因为本身AppWidgetProvider extends android.content.BroadcastReceiver.需要在onReceive里面处理,这里就不再多说了.不知道的可以查下AppWidgetProvider的说明文档.提醒一下,上面的两个Action一定要在AndroidManifest.xml里面配置哦.本人就犯过这种低级错误.一定要记得配置广播的Action!一定要记得配置广播的Action!一定要记得配置广播的Action!大笑大笑大笑重要的事情说三遍.

  以上的办法其实没有解决根本问题,如何让appwidget自己的view可以实现滑动事件的处理,我还没想到办法,知道的大牛可以告诉我下.Thank you very much !




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值