Android: ViewDragHelper tutorial

本文详细介绍了如何在自定义Android视图中利用ViewDragHelper类实现视图拖动功能,包括创建实例、处理触摸事件、设置回调函数及确保动画连续进行的方法。
转自:http://blog.denevell.org/android-viewdraghelper-example-tutorial.html


If you want to drag things around your screen, you’ll want to use the compatability library’s ViewDragHelper class.

You’ll first need to make your own ViewGroup extending custom view, since we’ll be intercepting MotionEvents.

Creating an instance

Once you’ve made your custom view extending ViewGroup, you need to create a ViewDragHelper instance. We’ll put it in onAttachedToWindow().

@Override
protected void onAttachedToWindow() {
    super.onAttachedToWindow();
    mDragHelper = ViewDragHelper.create(this, 1.0f, new OurViewDragHelperCallbacks());
    ...
}

We’re using the create() factory method, passing in this ViewGroup, the sensitivity for a drag start (1.0f is normally according to the docs), and some callbacks.

Motion events

Before we look at the callbacks, let’s look at how they are activiated, and for that we look at onInterceptTouchEvent() and onTouchEvent().

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
  boolean shouldInterceptTouchEvent = mDragHelper.shouldInterceptTouchEvent(ev);
    return shouldInterceptTouchEvent;
}

This method uses our drag helper to decide if our class should intercept the touch events or not. We use this so if our child view is a button, for example, we can both press and slide it.

Next we use the onTouchEvent() method to make the view drag helper process this motion event, which will be called according to the interaction of the view and the method above.

@Override
public boolean onTouchEvent(MotionEvent event) {
    mDragHelper.processTouchEvent(event);
    return true;
}

ViewDragHelper callbacks

Now we have the MotionEvents being passed correctly to our ViewDragHelper instance, we can look at the callbacks.

new ViewDragHelper.Callback() {

    @Override
    public boolean tryCaptureView(View arg0, int pointerId) {
       return true; 
    }

The above will be passed the views which are dragged, and allow you to say if they should be captured or not. In this case we’re saying deal with any of the ViewGroup’s children.

    @Override
    public int clampViewPositionVertical(View child, int top, int dy) {
       return top;
    }

The above method allows us to drag on the vertical axis. If we’re happy with the new position of the drag, we just return the ‘top’ value. You can define clamp the dragging in certain regions using this method.

This has a sister, clampViewPositionHorizonal, that allows you to drag or constrain on the horizonal axis.

    @Override
    public int getViewVerticalDragRange(View child) {
       return parent.getMeasuredHeight()-child.getMeasuredHeight();
    }

The above method is used to calculate the velocity internally, by knowing your view’s dragging space. Again, it has a sister method, replacing Vertical for Horizontal.

    @Override
    public void onViewReleased(View releasedChild, float xvel, float yvel) {
       super.onViewReleased(releasedChild, xvel, yvel);
       if(yvel>0) {
         mDragHelper.settleCapturedViewAt(releasedChild.getLeft(), parent.getMeasuredHeight()-releasedChild.getMeasuredHeight());
       } else {
         mDragHelper.settleCapturedViewAt(releasedChild.getLeft(), 0);
       }
       invalidate();
    }
});

The above method, and final we’ll look at, is called when the dragging of an element stops. We’re using it to see if the velocity of the drag in the Y axis is positive or negative.

If it’s positive, i.e. we’re dragging down, we take the released view and tell it slide down down to the bottom of the parent. If it’s negative, i.e. we’re dragging up, we slide up to the top.

We finally call invalidate so the animation can begin. There are other methods we can call on the drag helper, like smoothSlideViewTo, but settleCatpuredViewAt takes into account the current velocity.

Ensuring the animation continues

After we call the settleCapturedViewAt or similar methods above, we need to ensure the animatin continues. In the computeScroll() method on our ViewGroup or similar we have the following:

@Override
public void computeScroll() {
    super.computeScroll();
    if(mDragHelper.continueSettling(true)) {
       ViewCompat.postInvalidateOnAnimation(this);
    }
}

We call the continueSettling method on the ViewDragHelper instance so our animation continues, and if it’s not yet settled, we then go and call the postInvalidateOnAnimation() method to ensure we keep animating.

There are plenty of other methods to play with here https://developer.android.com/reference/android/support/v4/widget/ViewDragHelper.html

转者注:在自定义容器里面获取里面的子View方法:

@Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mDragView1=getChildAt(0);
        mDragView2=getChildAt(1);
        Log.v("TAG","====mDragView 1 is "+mDragView1+"---22 IS "+mDragView2);
    }

在构造方法里面获取为空。


内容概要:本文设计并实现了一套基于“云-边-端”协同架构的工业设备智能管控系统,旨在解决传统制造业中存在的设备管理效率低、数据孤岛、运维成本高等问题。系统融合物联网感知、边缘计算、云边协同、微服务架构与AI预测性维护等技术,实现了设备数据的实时采集、多协议自适应解析、远程精准控制及智能预警。通过模块化设计,支持Modbus、OPC UA、Profinet等多种工业协议,结合规则引擎与机器学习算法,构建智能控制与故障预测模型,已在高端装备制造企业成功示范应用,显著降低非计划停机时间和运维成本,推动制造业数字化转型。; 适合人群:具备一定电子信息工程或自动化专业背景,从事工业互联网、智能制造、物联网系统开发与集成的相关技术人员及本科及以上层次的学生;尤其适合关注工业设备远程监控与智能运维的科研与工程人员。; 使用场景及目标:①应用于制造业设备的远程电源控制与状态监控,提升设备管理智能化水平;②实现跨品牌设备的互联互通与多协议兼容接入;③通过AI模型开展预测性维护,减少突发故障与维护成本;④为中小企业提供低成本、短周期、高兼容性的智能化升级解决方案。; 阅读建议:此论文理论与实践结合紧密,建议读者重点关注系统架构设计、多协议解析实现、云边协同机制与AI模型应用部分,结合实际工业场景理解技术选型与实现路径,可参考其模块划分与数据库设计进行二次开发或项目仿真实践。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值