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.效果图

023 Android 自定义Toast控件的更多相关文章

  1. Android自定义日历控件(继承系统控件实现)

    Android自定义日历控件(继承系统控件实现) 主要步骤 编写布局 继承LinearLayout设置子控件 设置数据 继承TextView实现有圆圈背景的TextView 添加Attribute 添 ...

  2. Android自定义组合控件详细示例 (附完整源码)

    在我们平时的Android开发中,有时候原生的控件无法满足我们的需求,或者经常用到几个控件组合在一起来使用.这个时候,我们就可以根据自己的需求创建自定义的控件了,一般通过继承View或其子类来实现. ...

  3. android自定义倒计时控件示例

    这篇文章主要介绍了Android秒杀倒计时自定义TextView示例,大家参考使用吧 自定义TextView控件TimeTextView代码: 复制代码 代码如下: import android.co ...

  4. 014 Android 自定义组合控件

    1.需求介绍 将已经编写好的布局文件,抽取到一个类中去做管理,下次还需要使用类似布局时,直接使用该组合控件的对象. 优点:可复用. 例如要重复利用以下布局: <RelativeLayout an ...

  5. Android自定义用户控件简单范例(二)

    对于完全由后台定制的控件,并不是很方便其他人的使用,因为我们常常需要看到控件放到xml界面上的效果,并根据效果进行布局的调整,这就需要一个更加标准的控件制作流程: 我们的自定义控件和其他的控件一样,应 ...

  6. android 自定义组合控件 顶部导航栏

    在软件开发过程中,经常见到,就是APP 的标题栏样式几乎都是一样的,只是文字不同而已,两边图标不同.为了减少重复代码,提高效率, 方便大家使用,我们把标题栏通过组合的方式定义成一个控件. 例下图: 点 ...

  7. (转)android自定义组合控件

    原文地址:http://mypyg.iteye.com/blog/968646 目标:实现textview和ImageButton组合,可以通过Xml设置自定义控件的属性. 1.控件布局:以Linea ...

  8. android 自定义日历控件

    日历控件View: /** * 日历控件 功能:获得点选的日期区间 * */ public class CalendarView extends View implements View.OnTouc ...

  9. Android自定义评分控件:RatingStarView

    RatingStarView Android自定义的评分控件,类似ProgressBar那样的,使用星星图标(full.half.empty)作为progress标识的评分/打分控件. 效果图 图1: ...

随机推荐

  1. lp3676 小清新数据结构题

    传送门 Description 有一棵\(n\)个点的树,每个点有一个点权. 现在有\(q\)次操作,每次操作是修改一个点的点权或指定一个点,询问以这个点为根时每棵子树点权和的平方和. Solutio ...

  2. avalon中的ms-attr?

    <div class="item" id="move5" style="margin:0" > <a class=&quo ...

  3. 【2019.10.30】SDN上机第1次作业

    用字符命令搭建如下拓扑,要求写出命令 题目一: 字符命令如下: 题目二: 字符命令如下: 利用可视化工具搭建如下拓扑 要求支持OpenFlow 1.0 1.1 1.2 1.3,设置h1(10.0.0. ...

  4. mysql数据库出现无法登录(ERROR 1045 ),预防和解决及系列问题解决方法。

      一 .当在windows下使用mysql数据库时,出现无法登录的现象,需要修改mysql数据库的roo密码时,我们可以使用一下两种方法. 1. (1)关闭mysql服务.然后在bin目录下使用cm ...

  5. Oracle 11g 数据库 expdp/impdp 全量导入导出

    从一个用户导出导入到另一个用户 问题 环境:oracle 11g; redhat 6 usera是具有DBA权限,密码为usera 全量导出usera用户下的所有内容,并导入到新建的userb用户 解 ...

  6. 每个Web开发者都需要具备的9个软技能--ZT

    本文原始链接:http://www.cnblogs.com/oooweb/p/soft-skills-every-web-developer-should-master.html 对于一份工作,你可能 ...

  7. 关于Kubernetes Master高可用的一些策略

    关于Kubernetes Master高可用的一些策略 Kubernetes高可用也许是完成了初步的技术评估,打算将生产环境迁移进Kubernetes集群之前普遍面临的问题. 为了减少因为服务器当机引 ...

  8. SQL Server 查找空值

    需要查找某一列为空的数据 )NULL不能用 “=”运算符 )NULL不支持+-*/ <> )不同的函数对NULL的支持不一样,使用前要测试,不能靠猜,不能凭经验

  9. 004 DOM01

    一:说明 1.Js的三个部分 ECMAScripts标准:JS的基本语法 DOM:文档对象模型,操作页面的元素的 BOM:浏览器对象模型,操作浏览器 2.术语 文档:一个页面就是一个文档 元素:页面中 ...

  10. 分析imx8mm-evk评估板的pinctrl设备树

    1. 分析arch/arm64/boot/dts/freescale/imx8mm-evk.dts中的i2c3相关的pinctrl_i2c3节点 pinctrl_i2c3: i2c3grp { fsl ...