android136 360 拖拽

简介:


差补器原理:

图标拖拽:

   

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;
            }
        });
    }
复制代码

 


本文转自农夫山泉别墅博客园博客,原文链接:http://www.cnblogs.com/yaowen/p/5122992.html,如需转载请自行联系原作者
相关文章
|
17小时前
|
Android开发
Android通过手势(多点)缩放和拖拽图片
Android通过手势(多点)缩放和拖拽图片
12 4
|
10月前
|
XML 前端开发 Java
Android实现一个可拖拽带有坐标尺的进度条
Canvas绘制这样的一个可拖拽坐标尺,基本上可以拆分出四部分,第一部分就是背景和默认的离散间隔,第二部分是移动的背景和离散间隔,第三部分是移动的图片也就是thumb,最后一部分是底部的文字坐标。
|
监控 Android开发 iOS开发
Android6.0 源码修改之 仿IOS添加全屏可拖拽浮窗返回按钮
Android6.0 源码修改之 仿IOS添加全屏可拖拽浮窗返回按钮
106 0
|
Android开发
Android | 格子拖拽填充效果
Android | 格子拖拽填充效果
|
iOS开发 监控
Android6.0 源码修改之 仿IOS添加全屏可拖拽浮窗返回按钮
Android6.0 源码修改之 仿IOS添加全屏可拖拽浮窗返回按钮前言之前写过屏蔽系统导航栏功能的文章,具体可看Android6.0 源码修改之屏蔽导航栏虚拟按键(Home和RecentAPP)/动态显示和隐藏NavigationBar 在某些特殊定制的版本中要求完全去掉导航栏,那么当用户点进一些系统自带的应用界面如设置、联系人等,就没法退出了,虽然可以在actionBar中添加back按钮,但总不能每一个app都去添加吧。
1199 0
|
Android开发 Java 容器