差补器原理:

图标拖拽:

   

activity_drag_view.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" > <!-- 2个TextView,一个显示一个隐藏 -->
<TextView
android:id="@+id/tv_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:background="@drawable/call_locate_blue"
android:gravity="center"
android:padding="15dp"
android:text="按住提示框拖到任意位置\n按手机返回键立即生效"
android:textColor="@color/black"
android:textSize="18sp" /> <TextView
android:id="@+id/tv_bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/call_locate_blue"
android:gravity="center"
android:padding="10dp"
android:text="按住提示框拖到任意位置\n按手机返回键立即生效"
android:textColor="@color/black"
android:textSize="18sp"
android:visibility="invisible" /> <!-- 拖拽的图片 -->
<ImageView
android:id="@+id/iv_drag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="90dp"
android:src="@drawable/drag" /> </RelativeLayout>

                       

package com.itheima52.mobilesafe.activity;

import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView; import com.itheima52.mobilesafe.R; /**
* 修改归属地显示位置
*
* 半透明效果:清单文件<activity
android:name=".activity.DragViewActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar" /> 这个acticity透明没有标题栏。 xml文件<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#5000" 背景半透明
>
*/
public class DragViewActivity extends Activity { private TextView tvTop;
private TextView tvBottom; private ImageView ivDrag; private int startX;
private int startY;
private SharedPreferences mPref; long[] mHits = new long[2];// 数组长度表示要点击的次数 @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drag_view); mPref = getSharedPreferences("config", MODE_PRIVATE); tvTop = (TextView) findViewById(R.id.tv_top);
tvBottom = (TextView) findViewById(R.id.tv_bottom);
ivDrag = (ImageView) findViewById(R.id.iv_drag); int lastX = mPref.getInt("lastX", 0);
int lastY = mPref.getInt("lastY", 0); // 获取屏幕宽高
final int winWidth = getWindowManager().getDefaultDisplay().getWidth();
final int winHeight = getWindowManager().getDefaultDisplay().getHeight(); if (lastY > winHeight / 2) {// 上边显示,下边隐藏
tvTop.setVisibility(View.VISIBLE);
tvBottom.setVisibility(View.INVISIBLE);
} else {
tvTop.setVisibility(View.INVISIBLE);
tvBottom.setVisibility(View.VISIBLE);
}
// ivDrag.getWidth();获取不到,因为还没有绘制完毕。
// onMeasure(测量view), onLayout(安放位置), onDraw(绘制)
// ivDrag.layout(lastX, lastY, lastX + ivDrag.getWidth(),lastY + ivDrag.getHeight());//不能用这个方法,因为还没有测量完成,就不能安放位置,下面的方法就可以,RelativeLayout是控件的父控件。
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) ivDrag.getLayoutParams();// 获取布局对象
layoutParams.leftMargin = lastX;// 设置左边距
layoutParams.topMargin = lastY;// 设置top边距
ivDrag.setLayoutParams(layoutParams);// 重新设置位置 ivDrag.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
System.arraycopy(mHits, 1, mHits, 0, mHits.length - 1);
mHits[mHits.length - 1] = SystemClock.uptimeMillis();// 开机后开始计算的时间
if (mHits[0] >= (SystemClock.uptimeMillis() - 500)) {
// 把图片居中
ivDrag.layout(winWidth / 2 - ivDrag.getWidth() / 2,
ivDrag.getTop(), winWidth / 2 + ivDrag.getWidth()
/ 2, ivDrag.getBottom());
}
}
}); // 设置触摸监听
ivDrag.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 初始化起点坐标
startX = (int) event.getRawX();
startY = (int) event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
int endX = (int) event.getRawX();
int endY = (int) event.getRawY(); // 计算移动偏移量
int dx = endX - startX;
int dy = endY - startY; // 更新左上右下距离
int l = ivDrag.getLeft() + dx;
int r = ivDrag.getRight() + dx; int t = ivDrag.getTop() + dy;
int b = ivDrag.getBottom() + dy; // 判断是否超出屏幕边界, 注意状态栏的高度
if (l < 0 || r > winWidth || t < 0 || b > winHeight - 20) {
break;
} // 根据图片位置,决定提示框显示和隐藏
if (t > winHeight / 2) {// 上边显示,下边隐藏
tvTop.setVisibility(View.VISIBLE);
tvBottom.setVisibility(View.INVISIBLE);
} else {
tvTop.setVisibility(View.INVISIBLE);
tvBottom.setVisibility(View.VISIBLE);
} // 更新界面(左上右下),因为已经绘制完成了,所以可以使用layout()方法。
ivDrag.layout(l, t, r, b); // 重新初始化起点坐标
startX = (int) event.getRawX();
startY = (int) event.getRawY();
break;
case MotionEvent.ACTION_UP:
// 记录坐标点
Editor edit = mPref.edit();
edit.putInt("lastX", ivDrag.getLeft());
edit.putInt("lastY", ivDrag.getTop());
edit.commit();
break;
default:
break;
}
return false;//事件要向下传递,让onclick(双击事件)可以响应
}
});
}
}
/**
* 自定义归属地浮窗Toast, 需要权限android.permission.SYSTEM_ALERT_WINDOW
*/
private void showToast(String text) {
mWM = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE); // 获取屏幕宽高
winWidth = mWM.getDefaultDisplay().getWidth();
winHeight = mWM.getDefaultDisplay().getHeight(); params = new WindowManager.LayoutParams();
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
params.format = PixelFormat.TRANSLUCENT;
params.type = WindowManager.LayoutParams.TYPE_PHONE;// 电话窗口。它用于电话交互(特别是呼入)。它置于所有应用程序之上,状态栏之下。
params.gravity = Gravity.LEFT + Gravity.TOP;// 将重心位置设置为左上方,
// 也就是(0,0)从左上方开始,而不是默认的重心位置
params.setTitle("Toast"); int lastX = mPref.getInt("lastX", 0);
int lastY = mPref.getInt("lastY", 0); // 设置浮窗的位置, 基于左上方的偏移量
params.x = lastX;
params.y = lastY; // view = new TextView(this);
view = View.inflate(this, R.layout.toast_address, null); int[] bgs = new int[] { R.drawable.call_locate_white,
R.drawable.call_locate_orange, R.drawable.call_locate_blue,
R.drawable.call_locate_gray, R.drawable.call_locate_green };
int style = mPref.getInt("address_style", 0); view.setBackgroundResource(bgs[style]);// 根据存储的样式更新背景 TextView tvText = (TextView) view.findViewById(R.id.tv_number);
tvText.setText(text); mWM.addView(view, params);// 将view添加在屏幕上(Window) view.setOnTouchListener(new OnTouchListener() { @Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 初始化起点坐标
startX = (int) event.getRawX();
startY = (int) event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
int endX = (int) event.getRawX();
int endY = (int) event.getRawY(); // 计算移动偏移量
int dx = endX - startX;
int dy = endY - startY; // 更新浮窗位置,WindowManager里面只可以用params实现位置的移动
params.x += dx;
params.y += dy; // 防止坐标偏离屏幕
if (params.x < 0) {
params.x = 0;
} if (params.y < 0) {
params.y = 0;
} // 防止坐标偏离屏幕
if (params.x > winWidth - view.getWidth()) {
params.x = winWidth - view.getWidth();
} if (params.y > winHeight - view.getHeight()) {
params.y = winHeight - view.getHeight();
} // System.out.println("x:" + params.x + ";y:" + params.y); mWM.updateViewLayout(view, params); // 重新初始化起点坐标
startX = (int) event.getRawX();
startY = (int) event.getRawY();
break;
case MotionEvent.ACTION_UP:
// 记录坐标点
Editor edit = mPref.edit();
edit.putInt("lastX", params.x);
edit.putInt("lastY", params.y);
edit.commit();
break; default:
break;
}
return true;
}
});
}

android136 360 拖拽的更多相关文章

  1. jQuery可拖拽3D万花筒旋转特效

    这是一个使用了CSS3立体效果的强大特效,本特效使用jQuery跟CSS3 transform来实现在用户鼠标按下拖动时,环形图片墙可以跟随鼠标进行3D旋转动画. 效果体验:http://hovert ...

  2. canvas 图片拖拽旋转之二——canvas状态保存(save和restore)

    引言 在上一篇日志“canvas 图片拖拽旋转之一”中,对坐标转换有了比较深入的了解,但是仅仅利用坐标转换实现的拖拽旋转,会改变canvas坐标系的状态,从而影响画布上其他元素的绘制.因此,这个时候需 ...

  3. js拖拽3D立方体旋转

    这段时间有点闲,所以就自己找些小玩意来练习练习.今天做了一个可以拖拽页面内空白位置3D立方体就会跟着转动的小例子,布局方面用到css3 3D转换技术,通过transform控制旋转实现的. 上个图 代 ...

  4. JQ实现3D拖拽效果

    <!DOCTYPE HTML> <html onselectstart='return false'> <head> <meta http-equiv=&qu ...

  5. jquery 实现页面拖拽并保存到cookie

    实现的效果就是页面内的图片可拖拽到任意位置,并将所在位置保存.下次打开页面依然可见.本文是作demo用,实际开发中,位置的数据应保存到数据库中. 好了,开始. 1.准备工作. a.jquery(1.7 ...

  6. js手写图片查看器(图片的缩放、旋转、拖拽)

    在做一次代码编辑任务中,要查看图片器.在时间允许的条件下,放弃了已经封装好的图片jq插件,现在自己手写js实现图片的缩放.旋转.推拽功能! 具体代码如下: <!DOCTYPE html> ...

  7. js实现图片查看器(图片的缩放、旋转、拖拽)

    一.关于图片查看器. 目前网络上能找到的图片查看器很多,谁便一搜就能出来.如:jquery.iviewer.js.Viewer.js这两个js文件,其中功能也足够满足大部分开发需求.但是单纯的就想实现 ...

  8. angularjs1 自定义图片查看器(可旋转、放大、缩小、拖拽)

    笔记: angularjs1 制作自定义图片查看器(可旋转.放大.缩小.拖拽) 2018-01-12 更新  可以在我的博客  查看我 已经封装好的 纯 js写的图片查看器插件    博客链接 懒得把 ...

  9. [ActionScript 3.0] 动态绘制扇形实例(拖拽绘制)

    package { import flash.display.Shape; import flash.display.Sprite; import flash.events.MouseEvent; / ...

随机推荐

  1. FormsAuthentication 登录兼容 IE11 保存cookie

    现象:使用FormsAuthentication进行登录验证,在IE11客户端无法保存cookie 解决方法:在web.config中的forms中增加cookieless="UseCook ...

  2. 多线程程序设计学习(8)Thread-Per-Message

    Thread-Per-Message[这个工作交给你模式]一:Thread-Per-Message的参与者--->Client(委托人)--->host(中介开线程)--->hepl ...

  3. Spring--通过注解来配置bean

    Spring通过注解配置bean 基于注解配置bean 基于注解来配置bean的属性 在classpath中扫描组件 组件扫描(component scanning):Spring能够从classpa ...

  4. cdn是什么和作用有些

    内容分发网络其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快.更稳定.通过在网络各处放置节点服务器所构 成的在现有的互联网基础之上的一层智能虚拟网络,CDN系 ...

  5. UVA 11488-Hyper Prefix Sets(Trie)

    题意: 给一个01串的集合,一个集合的幸运值是串的个数*集合中串的最大公共前缀 ,求所有子集中最大幸运值 分析: val[N]表示经过每个节点串的个数求幸运值 求就是每个节点值*该节点的深度 搜一遍树 ...

  6. 《Python基础教程(第二版)》学习笔记 -> 第三章 使用字符串

    本章讲话介绍如何使用字符串格式化其他的值,并简单了解一下利用字符串的分割.联接.搜索等方法能做些什么. 基本字符串操作 所有标准的序列操作(索引.分片.乘法.判断成员资格.求长度.取最大最小值)对字符 ...

  7. 【译】 AWK教程指南 8处理多行数据

    awk 每次从数据文件中只读取一行数据进行处理.awk是依照其内置变量 RS(Record Separator) 的定义将文件中的数据分隔成一行一行的Record.RS 的默认值是 "\n& ...

  8. ExtJs 5.0需要注意的问题

    1.在网上查找到的一些例子当中,存在new Ext.grid.ColumnModel()这样的操作,在5.0当中这是不允许的,在5.0当中这个已经被设置为私有方法,不允许用户调用,在5.0中我们不需要 ...

  9. 第四章:ARP 地址解析协议

    网络接口有一个硬件地址,48bit的值,在硬件层次上进行的数据帧交换必须有正确的接口地址.tcp/ip有自己的地址,32bit的IP地址. 但是知道主机的IP地址并不能让内核发送一帧数据给主机.内核( ...

  10. 【转载】解析提高PHP执行效率的50个技巧

    1.用单引号代替双引号来包含字符串,这样做会更快一些.因为PHP会在双引号包围的字符串中搜寻变量, 单引号则不会,注意:只有echo能这么做,它是一种可以把多个字符串当作参数的”函数”(译注:PHP手 ...