023 Android 自定义Toast控件
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控件的更多相关文章
- Android自定义日历控件(继承系统控件实现)
Android自定义日历控件(继承系统控件实现) 主要步骤 编写布局 继承LinearLayout设置子控件 设置数据 继承TextView实现有圆圈背景的TextView 添加Attribute 添 ...
- Android自定义组合控件详细示例 (附完整源码)
在我们平时的Android开发中,有时候原生的控件无法满足我们的需求,或者经常用到几个控件组合在一起来使用.这个时候,我们就可以根据自己的需求创建自定义的控件了,一般通过继承View或其子类来实现. ...
- android自定义倒计时控件示例
这篇文章主要介绍了Android秒杀倒计时自定义TextView示例,大家参考使用吧 自定义TextView控件TimeTextView代码: 复制代码 代码如下: import android.co ...
- 014 Android 自定义组合控件
1.需求介绍 将已经编写好的布局文件,抽取到一个类中去做管理,下次还需要使用类似布局时,直接使用该组合控件的对象. 优点:可复用. 例如要重复利用以下布局: <RelativeLayout an ...
- Android自定义用户控件简单范例(二)
对于完全由后台定制的控件,并不是很方便其他人的使用,因为我们常常需要看到控件放到xml界面上的效果,并根据效果进行布局的调整,这就需要一个更加标准的控件制作流程: 我们的自定义控件和其他的控件一样,应 ...
- android 自定义组合控件 顶部导航栏
在软件开发过程中,经常见到,就是APP 的标题栏样式几乎都是一样的,只是文字不同而已,两边图标不同.为了减少重复代码,提高效率, 方便大家使用,我们把标题栏通过组合的方式定义成一个控件. 例下图: 点 ...
- (转)android自定义组合控件
原文地址:http://mypyg.iteye.com/blog/968646 目标:实现textview和ImageButton组合,可以通过Xml设置自定义控件的属性. 1.控件布局:以Linea ...
- android 自定义日历控件
日历控件View: /** * 日历控件 功能:获得点选的日期区间 * */ public class CalendarView extends View implements View.OnTouc ...
- Android自定义评分控件:RatingStarView
RatingStarView Android自定义的评分控件,类似ProgressBar那样的,使用星星图标(full.half.empty)作为progress标识的评分/打分控件. 效果图 图1: ...
随机推荐
- java如何实现多线程?线程的状态有哪些?
java实现多线程有两种方法 1.继承Thread类 2.实现Runnable接口 这两种方法的共同点: 不论用哪种方法,都必须用Thread(如果是Thead子类就用它本身) ...
- FCS省选模拟赛 Day1
Description Solution T1 shopping 目测是插板法乱搞一下 发现题解写的是容斥dp: \[ ans = \sum_i (-1)^ig[i] \] \(g[i]\)表示的有 ...
- 模板 - 数据结构 - 可持久化无旋Treap/PersistentFHQTreap
有可能当树中有键值相同的节点时,貌似是要对Split和Merge均进行复制的,本人实测:只在Split的时候复制得到了一个WA,但只在Merge的时候复制还是AC,可能是恰好又躲过去了.有人说假如确保 ...
- LDA算法 (主题模型算法) 学习笔记
转载请注明出处: http://www.cnblogs.com/gufeiyang 随着互联网的发展,文本分析越来越受到重视.由于文本格式的复杂性,人们往往很难直接利用文本进行分析.因此一些将文本数值 ...
- 依赖倒置原则(DIP)
1. 定义 (1)高层模块不应依赖于低层模块,两者都应该依赖于抽象.(2)抽象不应该依赖于细节,细节应该依赖于抽象. 为什么是“倒置”这个词? 这是由于许多传统的软件开发方法,比如结构化分析和设计,总 ...
- 微信小程序实现左侧滑栏
前言 一直想给项目中的小程序设置侧滑栏,将退出按钮放到侧滑中,但是小程序没有提供相应的控件和API,因此只能自己手动实现,网上很多大神造的轮子很不错,本文就在是站在巨人的肩膀上实现. 效果 先看看效果 ...
- #C++初学记录#日常学习函数
静态变量static,只进行一次初始化. #include<cstring> #include<iostream> using namespace std; int main( ...
- CSS(1)
使用CSS的注意点: 1.style标签必须写在head标签的开始标签和结束标签之间(也就是必须和title标签是兄弟关系). 2.style标签中的type属性其实可以不用写,默认就是type=&q ...
- appium+python 微信小程序的自动化
sudo kill -9 $(lsof -i:8889 -t) mitmweb -p 8889 -s addons.py mitmdump -q -p 8889 -s addons.py http: ...
- Python将多张图片进行合并拼接
import PIL.Image as Image import os IMAGES_PATH = r'D:\pics22223\\' # 图片集地址 IMAGES_FORMAT = ['.jpg', ...