1.Toast自定义控件工具类
package com.example.administrator.test62360safeguard.Utils; import android.content.Context; import android.graphics.PixelFormat; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.widget.TextView; import com.example.administrator.test62360safeguard.R; public class ToastUtil { /** * 显示吐司 * @param context 应用的上下文 * @param windowManager 窗口管理器 * @param textshow 需要在textview 中需要显示的文本内容 * @return 吐司toast控件 */ public static View showToast(final Context context, final WindowManager windowManager, String textshow){ final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams(); final WindowManager.LayoutParams params = mParams; //设置toast的高度、宽度 params.height = WindowManager.LayoutParams.WRAP_CONTENT; params.width = WindowManager.LayoutParams.WRAP_CONTENT; params.format = PixelFormat.TRANSLUCENT; params.type = WindowManager.LayoutParams.TYPE_TOAST; params.setTitle("Toast"); params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; //| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; //默认可以被触摸 params.gravity=Gravity.LEFT+Gravity.TOP; //设置toast的位置()左上角 //toast显示效果,xml--->view ,将toast挂到windowManager窗体 final View myToastView = View.inflate(context, R.layout.toast_view, null); //给自定义的toast控件添加拖拽事件 myToastView.setOnTouchListener(new View.OnTouchListener() { int startX; int startY; int window_width; int window_height; @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: startX = (int) event.getRawX(); //获取点击位置(移动前)相对于整个屏幕原点(左上)的x距离 startY = (int) event.getRawY(); //获取点击位置(移动前)相对于整个屏幕原点(左上)的y距离 break; case MotionEvent.ACTION_MOVE: int moveX = (int) event.getRawX(); //获取点击位置(移动后)相对于整个屏幕原点(左上)的x距离 int moveY = (int) event.getRawY();//获取点击位置(移动后)相对于整个屏幕原点(左上)的y距离 int disX=moveX-startX; //x方向的移动距离 int disY=moveY-startY; //y方向的移动距离 params.x=params.x+disX; //设置toast控件的放置位置 params.y=params.y+disY; //容错处理 //获取屏幕的宽和高 window_width = windowManager.getDefaultDisplay().getWidth(); window_height=windowManager.getDefaultDisplay().getHeight(); //以下4个if语句:判断控件是否在屏幕的有效区域内 if(params.x<0){ params.x=0; } if(params.y<0){ params.y=0; } if(params.x>window_width-myToastView.getWidth()){ params.x=window_width-myToastView.getWidth(); } if(params.y>window_height-myToastView.getHeight()){ params.y=window_height-myToastView.getHeight(); } //告知窗体,toast控件需要按照手势的移动,去做位置的更新 windowManager.updateViewLayout(myToastView,params); startX = (int) event.getRawX(); //获取点击位置(移动后)相对于整个屏幕原点(左上)的x距离 startY = (int) event.getRawY(); //获取点击位置(移动后)相对于整个屏幕原点(左上)的y距离 break; case MotionEvent.ACTION_UP: SharePreferenceUtil.putInt(context, ConstantValue.LOCATION_X, params.x); SharePreferenceUtil.putInt(context, ConstantValue.LOCATION_Y, params.y); break; } //(1)若只需要响应拖拽事件,应该返回true //(2)既要响应点击事件,又要响应拖拽过程,则此返回值结果需要修改为false return true; } }); params.x=SharePreferenceUtil.getInt(context,ConstantValue.LOCATION_X,0); params.y=SharePreferenceUtil.getInt(context,ConstantValue.LOCATION_Y,0); int[] picArray=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 toast_style_index = SharePreferenceUtil.getInt(context, ConstantValue.TOAST_STYLE, 0); //设置toast中显示的文字内容 TextView tv_toast = myToastView.findViewById(R.id.tv_toast); tv_toast.setText(textshow); tv_toast.setBackgroundResource(picArray[toast_style_index]); //在窗体上挂载一个view(需要添加权限) windowManager.addView(myToastView,mParams); return myToastView; } /** * 移除吐司 * @param windowManager 窗口管理器 * @param toastView 所要关闭的toast组件 */ public static void closeToast( WindowManager windowManager, View toastView) { windowManager.removeView(toastView); } }
2.调用类
(1)设置中心页面的后台处理类:SettingActivity.java
package com.example.administrator.test62360safeguard; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.view.WindowManager; import android.widget.Toast; import com.example.administrator.test62360safeguard.Utils.ConstantValue; import com.example.administrator.test62360safeguard.Utils.SetttingClickView; import com.example.administrator.test62360safeguard.Utils.SetttingItemView; import com.example.administrator.test62360safeguard.Utils.SharePreferenceUtil; import com.example.administrator.test62360safeguard.Utils.ToastUtil; public class SettingActivity extends AppCompatActivity { View toastView=null; private String[] toastStyleArray; private int toast_style_value; private SetttingClickView scv_toast_style; private SetttingClickView scv_toast_location; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_setting); initUpdate(); initPhoneAddress(); initToastStyle(); initToastLocation(); } /** * 设置中心列表中第4个条目:设置归属地提示框位置 */ private void initToastLocation() { scv_toast_location = findViewById(R.id.scv_toast_location); scv_toast_location.setTitle("归属地提示框位置"); scv_toast_location.setDes("设置归属地提示框位置"); scv_toast_location.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent=new Intent(getApplicationContext(),ToastLocationActivity.class); startActivity(intent); } }); } /** * 设置中心列表中第3个条目:设置归属地显示风格 */ private void initToastStyle() { scv_toast_style = findViewById(R.id.scv_toast_style); scv_toast_style.setTitle("设置归属地显示风格"); //1.创建描述文字所在的string类型的数组 toastStyleArray = new String[]{"透明","橙色","蓝色","灰色","绿色"}; //2.通过sp中存储的显示样式对应的索引值,用于获取描述文字 toast_style_value = SharePreferenceUtil.getInt(getApplicationContext(),ConstantValue.TOAST_STYLE,0); //3.通过索引,获取字符串数组中的文字,让控件显示 scv_toast_style.setDes(toastStyleArray[toast_style_value]); //4.给自定义控件绑定点击事件 scv_toast_style.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showToastStyleDialog(); } }); } /** * 创建选择toast显示样式对话框 */ private void showToastStyleDialog() { AlertDialog.Builder builder=new AlertDialog.Builder(this); builder.setIcon(R.mipmap.ic_launcher); //设置对话框图标 builder.setTitle("请选择归属地样式"); //设置标题 /* 选择单个条目事件监听 参数1:string类型的数组描述颜色 参数2:弹出对话框选中条目的索引值 参数3:点击某一个条目后触发的点击事件(1.记录选择的索引值 2.关闭对话框 3.显示选中颜色的文字) */ builder.setSingleChoiceItems(toastStyleArray, toast_style_value, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //(1.记录选择的索引值 2.关闭对话框 3.显示选中颜色的文字) SharePreferenceUtil.putInt(getApplicationContext(),ConstantValue.TOAST_STYLE,which); dialog.dismiss(); //关闭对话框 scv_toast_style.setDes(toastStyleArray[which]); } }); //消极按钮 builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); builder.show(); //显示对话框 } /** * 设置中心列表中第2个条目:是否显示电话号码归属地的方法 */ private void initPhoneAddress() { final SetttingItemView siv_phone_address=findViewById(R.id.siv_phone_address); //获取已有的开关状态,用来显示 boolean open_phone=SharePreferenceUtil.getBoolean(this,ConstantValue.OPEN_PHONE,false); siv_phone_address.setChecked(open_phone); //点击过程中,状态切换过程 siv_phone_address.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //获取之前的选中状态 boolean isCheck=siv_phone_address.isChecked(); //将原有状态取反,设置为当前状态 siv_phone_address.setChecked(!isCheck); //将当前状态保存到SharePreference中(进行更新) SharePreferenceUtil.putBoolean(getApplicationContext(),ConstantValue.OPEN_PHONE,!isCheck); WindowManager windowManager= (WindowManager) getSystemService(WINDOW_SERVICE); if(!isCheck){ //调用自定义toast toastView=ToastUtil.showToast(getApplicationContext(),windowManager,"hello linda"); }else { if(toastView!=null){ ToastUtil.closeToast(windowManager,toastView); } } } }); } /** * 设置中心列表中第1个条目:自动更新模块 */ private void initUpdate() { final SetttingItemView siv_update=findViewById(R.id.siv_update); //获取已有的开关状态,用来显示 boolean open_update=SharePreferenceUtil.getBoolean(this,ConstantValue.OPEN_UPDATE,false); siv_update.setChecked(open_update); siv_update.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //获取之前的选中状态 boolean isCheck=siv_update.isChecked(); //将原有状态取反,设置为当前状态 siv_update.setChecked(!isCheck); //将当前状态保存到SharePreference中(进行更新) SharePreferenceUtil.putBoolean(getApplicationContext(),ConstantValue.OPEN_UPDATE,!isCheck); } }); } }
(2)设置Toast控件显示位置的页面后台代码:ToastLocationActivity.java
package com.example.administrator.test62360safeguard; import android.annotation.SuppressLint; import android.os.SystemClock; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.widget.Button; import android.widget.ImageView; import android.widget.RelativeLayout; import com.example.administrator.test62360safeguard.Utils.ConstantValue; import com.example.administrator.test62360safeguard.Utils.SharePreferenceUtil; public class ToastLocationActivity extends AppCompatActivity { ImageView iv_drag; Button bt_drag_visible; Button bt_drag_invisible; private int startX; private int startY; private WindowManager windowManager; private int window_width; private int window_height; private long[] mHits = new long[2]; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_toast_location); initUI(); } @SuppressLint("ClickableViewAccessibility") private void initUI() { iv_drag = findViewById(R.id.ivTL_drag_pic); bt_drag_visible = findViewById(R.id.bt_drag_visible); bt_drag_invisible = findViewById(R.id.bt_drag_invisible); windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); window_width = windowManager.getDefaultDisplay().getWidth(); window_height=windowManager.getDefaultDisplay().getHeight(); int location_x=SharePreferenceUtil.getInt(getApplicationContext(),ConstantValue.LOCATION_X,0); int location_y=SharePreferenceUtil.getInt(getApplicationContext(),ConstantValue.LOCATION_Y,0); RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); layoutParams.leftMargin=location_x; layoutParams.topMargin=location_y; iv_drag.setLayoutParams(layoutParams); //给控件绑定双击事件 iv_drag.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { System.arraycopy(mHits, 1, mHits, 0, mHits.length-1); mHits[mHits.length-1] = SystemClock.uptimeMillis(); if(mHits[mHits.length-1]-mHits[0]<500){ //满足双击事件后,调用代码 int left = window_width/2 - iv_drag.getWidth()/2; //left表示控件左边缘距屏幕左侧的距离 int top = window_height/2 - iv_drag.getHeight()/2; int right = window_width/2+iv_drag.getWidth()/2; int bottom = window_height/2+iv_drag.getHeight()/2; //控件按以上规则显示 iv_drag.layout(left, top, right, bottom); //存储最终位置 SharePreferenceUtil.putInt(getApplicationContext(), ConstantValue.LOCATION_X, iv_drag.getLeft()); SharePreferenceUtil.putInt(getApplicationContext(), ConstantValue.LOCATION_Y, iv_drag.getTop()); } } }); //监听某一个控件的拖拽事件(按下、移动、放下) iv_drag.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: startX = (int) event.getRawX(); //获取点击位置(移动前)相对于整个屏幕原点(左上)的x距离 startY = (int) event.getRawY(); //获取点击位置(移动前)相对于整个屏幕原点(左上)的y距离 break; case MotionEvent.ACTION_MOVE: int moveX = (int) event.getRawX(); //获取点击位置(移动后)相对于整个屏幕原点(左上)的x距离 int moveY = (int) event.getRawY();//获取点击位置(移动后)相对于整个屏幕原点(左上)的y距离 int disX=moveX-startX; //x方向的移动距离 int disY=moveY-startY; //y方向的移动距离 //1.当前控件所在屏幕的左上角的位置 //getLeft()获取该控件与父控件的相对位置 int left=iv_drag.getLeft()+disX; //控件(移动后)左侧坐标=控件(移动前)左侧坐标+移动距离 int top=iv_drag.getTop()+disY; //顶端坐标 int right=iv_drag.getRight()+disX; int bottom=iv_drag.getBottom()+disY; //容错处理:控件不能拖拽出手机屏幕 //左边缘不能超出屏幕 if(left<0){ return true; } if (right>window_width){ return true; } if (top<0){ return true; } if(bottom>window_height-30){ return true; } //2.告知移动的控件,按照计算出来的坐标去展示 iv_drag.layout(left,top,right,bottom); //3.重置起始位置的坐标 startX = (int) event.getRawX(); startY = (int) event.getRawY(); break; case MotionEvent.ACTION_UP: //4.存储移动后的位置坐标 SharePreferenceUtil.putInt(getApplicationContext(),ConstantValue.LOCATION_X,iv_drag.getLeft()); SharePreferenceUtil.putInt(getApplicationContext(),ConstantValue.LOCATION_Y,iv_drag.getTop()); break; } //(1)若只需要响应拖拽事件,应该返回true //(2)既要响应点击事件,又要响应拖拽过程,则此返回值结果需要修改为false return false; } }); } }
3.效果图
来源:https://www.cnblogs.com/luckyplj/p/10839605.html