控制控件随手指移动

    这里用到了一些属性动画的知识和对屏幕坐标的知识,其实不是很难,给大家上个图。
这里写图片描述
    然后代码呢其实就是一个Mainctivity,界面也就一个,我力图简单,只为你们服务,下面给出代码。

import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements View.OnClickListener, View.OnTouchListener {

    private TextView mRlMezi; //被我们控制的控件
    private DisplayMetrics dm; //用来获取屏幕的宽高
    private int lastX, lastY;  //手指离开屏幕的坐标点
    private static Boolean know = false; //用来处理每次把触碰事件当移动来处理还是当移动来处理
    private float position1 = 0; //刚点击时的X坐标
    private float position2 = 0;  //手指离开屏幕的X坐标
    private ValueAnimator animator1;  //用来执行动画
    private int l, b, r, t;  //控件的位置参数

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mRlMezi = (TextView) findViewById(R.id.rl_mezi);
        dm = getResources().getDisplayMetrics();
        //下面两个方法时关键,实际上我们使用的时候只需要把我们需要控制的控件添加这两个监听即可实现效果
        mRlMezi.setOnTouchListener(this);   //一个设置触碰监听
        mRlMezi.setOnClickListener(this);   //一个设置点击监听
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.rl_mezi:
                if (!know) {
                    Toast.makeText(this, "点我干嘛?", Toast.LENGTH_SHORT).show();  //这里我只打了一个Toast,但是实际上我们可以做更多的事,比如跳出一个对话框,或者进入另一个Activity什么的
                }
                break;
        }
    }


    @Override
    public boolean onTouch(View v, MotionEvent event) {
        int ea = event.getAction();
        final int screenWidth = dm.widthPixels;   //获取屏宽
        final int screenHeight = dm.heightPixels;   //获取屏高
        switch (v.getId()) {
            case R.id.rl_mezi:
                switch (ea) {
                    case MotionEvent.ACTION_DOWN:
                        lastX = (int) event.getRawX();
                        lastY = (int) event.getRawY();
                        position1 = lastX;
                        know = false;
                        break;
                    case MotionEvent.ACTION_MOVE:
                        int dx = (int) event.getRawX() - lastX;
                        int dy = (int) event.getRawY() - lastY;
                        l = v.getLeft() + dx;
                        b = v.getBottom() + dy;
                        r = v.getRight() + dx;
                        t = v.getTop() + dy;
                        /*
                        * 下面用来处理超出屏幕范围
                        * */
                        if (l < 0) {
                            l = 0;
                            r = l + v.getWidth();
                        }
                        if (t < 0) {
                            t = 0;
                            b = t + v.getHeight();
                        }
                        if (r > screenWidth) {
                            r = screenWidth;
                            l = r - v.getWidth();
                        }
                        if (b > screenHeight) {
                            b = screenHeight;
                            t = b - v.getHeight();
                        }
                        v.layout(l, t, r, b);
                        lastX = (int) event.getRawX();
                        lastY = (int) event.getRawY();
                        v.postInvalidate();
                        break;
                    case MotionEvent.ACTION_UP:
                        position2 = (int) event.getRawX();
                        //对比两个移动的差距,如果大于4,我们认定移动了,即不可响应onClick事件,如果小于4,就可以响应
                        if (Math.abs(position2 - position1) > 4) {
                            know = true;
                        }
                        if (v.getLeft() + v.getWidth() / 2 > screenWidth / 2) {
                            startrightanimator(v.getX(), v.getY(), screenWidth - v.getLeft() - v.getWidth());
                            animator1.start();
                        } else {
                            startleftanimator(v.getX(), v.getY(), v.getLeft());
                        }
                        break;

                }
            default:
                break;
        }
        return know;
    }

    //执行向左移动的动画
    private void startleftanimator(final float x, final float y, final int postion) {
        //我们用的是属性动画,只有属性动画才可以让控件移动并且响应位置也发生移动
        animator1 = ValueAnimator.ofInt(0, postion);
        animator1.setDuration(1000);   //这里设置动画的时长
        animator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int curValue = Integer.valueOf(animation.getAnimatedValue().toString());
                //注意下面的设置,只有一个地方是需要我们手动更改的,那就是:mRlMezi,使用的使用更改成我们需要控制的那个控件即可
                mRlMezi.layout(-curValue + (int) x, (int) y, -curValue + (int) x + mRlMezi.getWidth(), mRlMezi.getHeight() + (int) y);
            }
        });
        animator1.start();   //开始动画

    }

    //执行向右移动的动画
    private void startrightanimator(final float x, final float y, final int postion) {
        animator1 = ValueAnimator.ofInt(0, postion);
        animator1.setDuration(1000);
        animator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int curValue = Integer.valueOf(animation.getAnimatedValue().toString());
                mRlMezi.layout(curValue + (int) x, (int) y, curValue + (int) x + mRlMezi.getWidth(), mRlMezi.getHeight() + (int) y);
            }
        });
        animator1.start();
    }

}

    注释很详细,下面给出我的DEMO:
http://download.csdn.net/download/wanxuedong/9896733

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 您可以使用WPS JS宏编写代码来实现控件随单元格移动的功能。以下是一个简单的示例代码: ```javascript function onCellChange(range) { // 获取控件对象 var control = this.Document.getControl("控件名称"); if (control != null) { // 获取控件左上角单元格的位置 var leftTopCell = control.getLeftTopCell(); var row = leftTopCell.getRow() + range.getRowCount() - 1; var column = leftTopCell.getColumn() + range.getColumnCount() - 1; // 设置控件左上角单元格的位置 control.setLeftTopCell(this.Document.getRange(row, column)); } } ``` 在这个示例中,我们定义了一个名为`onCellChange`的函数,它会在单元格内容变化时被触发。在函数中,我们首先获取了指定名称的控件对象,然后根据控件左上角单元格的位置和单元格内容变化的范围,计算出控件应该移动到的新位置,并将其设置为控件的左上角单元格。 您需要将此代码复制到WPS文档中的JS宏编辑器中,并将其中的`控件名称`替换为您实际使用的控件名称。然后,您需要在WPS文档中选择“开发工具”->“JS宏”->“宏设置”,并将“单元格变更事件”设置为我们刚才定义的`onCellChange`函数。这样,当您在文档中更改单元格内容时,控件就会自动随着单元格移动了。 ### 回答2: WPS JS宏是一种在WPS表格中使用的自动化脚本工具。通过编写JS宏,我们可以在表格中实现自动化的操作。 其中,控件是JS宏中的一种对象,可以在表格中添加各种交互元素,如按钮、文本框等。这些控件可以与单元格进行绑定,从而与表格中的数据进行交互。 随单元格移动是指当单元格在表格中移动时,控件也会随之一起移动。这样的功能非常有用,可以确保控件始终与相关的数据单元格保持对应关系。 要实现这个功能,我们可以使用WPS JS宏提供的事件处理函数。事件处理函数可以捕捉到表格的各种事件,包括单元格移动事件。通过在事件处理函数中编写代码,我们可以在单元格移动时,自动调整控件的位置。 具体做法是在JS宏的代码中,使用事件处理函数监听表格的单元格移动事件。当该事件触发时,可以获取到移动之前和移动之后的单元格位置。然后,我们可以通过计算单元格位置的差值,将控件相应地移动。 例如,可以使用控件left和top属性来改变其相对于表格的位置,从而实现随单元格移动的效果。通过监听多个单元格移动事件,我们可以根据实际需求,对控件的位置进行灵活的调整。 总之,WPS JS宏中的控件可以随着单元格的移动而进行相应的位置调整。通过编写事件处理函数,我们能够实现控件与单元格之间的自动关联,从而实现更加智能化的表格操作。 ### 回答3: WPS JS宏控件随单元格移动是指在WPS表格中使用JS宏控件时,当单元格移动或插入行列时,控件也会相应地移动。 WPS表格是一款功能强大的电子表格软件,通过使用JS宏控件,我们可以添加自定义的功能和操作。当我们在表格中插入或移动单元格时,表格中的内容会被移动或调整,而WPS JS宏控件也会相应地随之移动。 通过在JS宏控件的代码中使用相应的事件处理程序,我们可以实现控件随单元格移动的功能。比如在单元格内容发生变化时,我们可以通过编写代码来重新定位和调整控件的位置,使其与单元格保持一致。 实现控件随单元格移动的过程可以分为以下几个步骤: 1. 监听单元格移动或插入行列的事件,比如onCellMove或onAddRow。 2. 在事件处理程序中,获取要移动的单元格的位置信息,比如行索引和列索引。 3. 通过控件的相关属性或方法,重新设定控件的位置,使其与目标单元格保持一致。 4. 更新控件的显示和布局,确保控件在新位置上正确显示。 通过以上步骤的操作,我们可以实现WPS JS宏控件随单元格移动的功能。这样,在表格中移动或调整单元格时,控件也会相应地移动,保持与单元格的对应关系,提高了表格的可用性和用户体验。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值