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. C# 使用配置文件配置应用

    使用配置文件配置应用 .NET Framework 通过配置文件为开发人员和管理员提供了对应应用程序运行方式的控制权和灵活性.配置文件可以按需要更改的XML文件.管理员能够控制应用程序可以访问哪些受保 ...

  2. 坑:jmeter代理服务器录制脚本出现target controller is configured to "use recording Controller" but no such controller exists...

    配置好代理服务器后,运行代理服务器 run 报错: target controller is configured to "use recording Controller" bu ...

  3. Picture Control 加载路径图片

    //CBitmap bitmap; //HBITMAP hBmp; //bitmap.LoadBitmap(strImgPath); //hBmp = (HBITMAP)bitmap.GetSafeH ...

  4. AtCoder Beginner Contest 133 E - Virus Tree 2(组合数学)

    题意 n个点的树k种颜色,距离不超过2的点对需颜色不同,求方案数 Code(copy) #include<iostream> #include<cstdio> #include ...

  5. Tkinter 之事件绑定

    import tkinter as tk window = tk.Tk() # 设置窗口大小 winWidth = 600 winHeight = 400 # 获取屏幕分辨率 screenWidth ...

  6. Python多线程与多进程详解

    进程,线程,协程https://blog.csdn.net/qq_23926575/article/details/76375337 多进程 https://www.cnblogs.com/lipij ...

  7. Enhancer | 增强子 专题

    要做就做深做精! Everything needs good justification. The interpretation should be biologically and statisti ...

  8. 微信小程序的z-index在苹果ios无效

    1.在微信开发者工具可以正常显示 2.在安卓真机手机可以正常显示 3.在ios手机真机无法正常显示 原因:父级view的css属性有 position: fixed; ,把它注释掉即可

  9. MiniUI官方表单验证示例

    原文地址:http://www.miniui.com/docs/tutorial/validator.html 表单验证 参考示例: 验证规则     表单验证     表单验证:文本提示     表 ...

  10. TextView: android:ellipsize="marquee" 跑马灯效果无效的问题

    今天练习的时候想实现一个文字的跑马灯效果,本来想自己手动实现的,不过突然想起来android里的TextView属性似乎自带了这个效果,叫: android:ellipsize ,平时都是把它的属性值 ...