• 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="按住提示框拖到任意位置
    按手机返回键立即生效"
            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="按住提示框拖到任意位置
    按手机返回键立即生效"
            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;
                }
            });
        }
  • 相关阅读:
    用户使用调查报告(追光的人)
    项目Beta冲刺(7/7)(追光的人)(2019.5.29)
    项目Beta冲刺(6/7)(追光的人)(2019.5.28)
    项目Beta冲刺(5/7)(追光的人)(2019.5.27)
    项目Beta冲刺(4/7)(追光的人)(2019.5.26)
    项目Beta冲刺(3/7)(追光的人)(2019.5.25)
    项目Beta冲刺(2/7)(追光的人)(2019.5.24)
    项目Beta冲刺随笔集合
    项目Alpha冲刺随笔集合
    项目Beta冲刺总结随笔
  • 原文地址:https://www.cnblogs.com/yaowen/p/5122992.html
Copyright © 2020-2023  润新知