zoukankan      html  css  js  c++  java
  • Android-满屏幕拖动的控件

    本文转载自师兄一篇博客:http://blog.csdn.net/yayun0516/article/details/52254818

    觉得跟之前的模拟小火箭很相似,又有学习的地方,能作为知识补充。所以转载一起学习。大家也可以关注他的文章哦。


    也就是,用户可以随心所欲的拖动控件,布局文件很简单就是一个Button控件:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
       
    android:id="@+id/root"
       
    android:layout_width="match_parent"
       
    android:layout_height="match_parent">

       <Button
           
    android:id="@+id/id_text"
           
    android:layout_width="wrap_content"
           
    android:layout_height="wrap_content"
           
    android:text="Hello World!" />
    </RelativeLayout>

    MainActivity.java:

    package com.example.administrator.followview;

    public class
    MainActivity extends Activity implements View.OnTouchListener {
       private Button mButton;
       private
    ViewGroup mViewGroup;
       private int
    xDelta;
       private int
    yDelta;
       public static final
    String TAG = "YAYUN";

       
    @Override
       
    public void onCreate(Bundle savedInstanceState) {

           super.onCreate(savedInstanceState);
           
    setContentView(R.layout.activity_main);
           
    mViewGroup = (ViewGroup) findViewById(R.id.root);
           
    mButton = (Button) findViewById(R.id.id_text);
           
    RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
                   ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
           
    layoutParams.leftMargin = 50;
           
    layoutParams.topMargin = 50;

           
    mButton.setLayoutParams(layoutParams);
           
    mButton.setOnTouchListener(this);
       
    }

       @Override
       
    public boolean onTouch(View view, MotionEvent event) {
           final int x = (int) event.getRawX();
           final int
    y = (int) event.getRawY();
           
    Log.d(TAG, "onTouch: x= " + x + "y=" + y);
           switch
    (event.getAction() & MotionEvent.ACTION_MASK) {
               case MotionEvent.ACTION_DOWN:
                   RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) view
                           .getLayoutParams();
                   
    xDelta = x - params.leftMargin;
                   
    yDelta = y - params.topMargin;
                   
    Log.d(TAG, "ACTION_DOWN: xDelta= " + xDelta + "yDelta=" + yDelta);
                   break;
               case
    MotionEvent.ACTION_MOVE:
                   RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view
                           .getLayoutParams();
                   int
    xDistance = x - xDelta;
                   int
    yDistance = y - yDelta;
                   
    Log.d(TAG, "ACTION_MOVE: xDistance= " + xDistance + "yDistance=" + yDistance);
                   
    layoutParams.leftMargin = xDistance;
                   
    layoutParams.topMargin = yDistance;
                   
    view.setLayoutParams(layoutParams);
                   break;
           
    }
           mViewGroup.invalidate();
           return true;
       
    }
    }

    MainActivity实现了OnTouchListener接口,覆写了onTouch方法,每次回调这个方法通过x和y变量记录当前的坐标。

    ACTION_DOWN是在按下的时候调用(没抬起来只调用一次),通过xDelta和yDelta来记录第一次按下的点相对于控件左上角的位置,也就是相对距离。

    ACTION_MOVE移动的时候不断调用,通过xDistance和yDistance来记录移动的相对距离作为leftMargin和topMargin再动态设置给控件。

    最后,调用invalidate方法更新控件位置。

    解释起来不容易解释,理解起来也不容易理解,我们可以看一下Log,帮助理解:


    按下的时候,首先打印当前的坐标为(131,75),由于在onCreate方法中设置了初始的leftMargin和topMargin都为50,所以此时xDelta的值为131-50=81,yDelta的值为75-50=25。第一个ACTION_MOVE的xDistance为132-81=51,yDistance的值为80-25=55,同理,后面都是循环调用了。

    这里主要要注意相对的概念,计算的都是相对距离。

    这个效果直接用到的场景不多,但是里面的处理思路都是在开发中经常会用到的,onTouch方法也是控件交互经常会用到的方法,这方面要很熟悉。

    希望这个简单的实例可以给大家带来思维的碰撞。

  • 相关阅读:
    洛谷 P1903 【模板】分块/带修改莫队(数颜色)
    BZOJ 2038: [2009国家集训队]小Z的袜子(hose)
    LibreOJ #6208. 树上询问
    LibreOJ #6002. 「网络流 24 题」最小路径覆盖
    hdu 3861 The King’s Problem
    洛谷 P2868 [USACO07DEC]观光奶牛Sightseeing Cows
    洛谷 P2905 [USACO08OPEN]农场危机Crisis on the Farm
    洛谷 U3348 A2-回文数
    洛谷 P1001 A+B Problem
    LibreOJ #2130. 「NOI2015」软件包管理器
  • 原文地址:https://www.cnblogs.com/wanghang/p/6299610.html
Copyright © 2011-2022 走看看