自定义可拖动土司
来源:互联网 发布:鲸鱼死后爆炸知乎 编辑:程序博客网 时间:2024/04/30 02:06
一、自定义可拖动土司代码如下:
总的来说:显示Toast就是把一个view添加到window中,去掉Toast就是把一个view从window中移除,因为window不是Activity,所以程序存不存在都不影响Toast的显示。
1、成员变量
private WindowManager.LayoutParams params;private WindowManager wm;private View view;
2、参数及成员初始化
@Overridepublic void onCreate() { // 初始化窗体管理器 wm = (WindowManager) getSystemService(WINDOW_SERVICE); // 初始化土司的参数 initToastParams(); super.onCreate();}
3、初始化土司的参数
private void initToastParams() { // TODO Auto-generated method stub // XXX This should be changed to use a Dialog, with a Theme.Toast // defined that sets up the layout params appropriately. // 土司的初始化参数 params = new WindowManager.LayoutParams(); params.height = WindowManager.LayoutParams.WRAP_CONTENT; params.width = WindowManager.LayoutParams.WRAP_CONTENT; //对齐方式左上角 params.gravity = Gravity.LEFT | Gravity.TOP; params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE /* | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE */ | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; params.format = PixelFormat.TRANSLUCENT; //初始化土司的位置(从sp中取) //params.x = (int) Float.parseFloat(SpTools.getString(getApplicationContext(), MyConstants.TOASTX, "0")); //params.y = (int) Float.parseFloat(SpTools.getString(getApplicationContext(), MyConstants.TOASTY, "0")); params.type = WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;// 土司天生不相应事件,改变类型 params.setTitle("Toast");}
4、显示土司
/** * 显示土司 * * @param incomingNumber * 电话号码 */protected void showLocationToast(String incomingNumber) { // 土司显示的view view = View.inflate(getApplicationContext(), R.layout.sys_toast, null); TextView tv_location = (TextView) view .findViewById(R.id.tv_toast_location); tv_location.setText(PhoneLocationEngine.locationQuery(incomingNumber, getApplicationContext())); // 初始化view的触摸事件 view.setOnTouchListener(new OnTouchListener() { private float startX; private float startY; @Override public boolean onTouch(View v, MotionEvent event) { System.out.println(event.getX() + ":" + event.getRawX()); // 拖动土司 switch (event.getAction()) { case MotionEvent.ACTION_DOWN:// 按下 startX = event.getRawX(); startY = event.getRawY(); break; case MotionEvent.ACTION_MOVE:// 按下移动,拖动 //新的 x y坐标 float moveX = event.getRawX();//移动后的x坐标 float moveY = event.getRawY();//移动后的x坐标 //dx x方向的位置变化值 dy y方向的位置变化值 float dx = moveX - startX; float dy = moveY - startY; //改变土司的坐标 params.x += dx; params.y += dy; //重新获取新的x y坐标 startX = moveX; startY = moveY; //更新土司的位置 wm.updateViewLayout(view, params); break; case MotionEvent.ACTION_UP:// 松开 //解决左右边界滑出多次后,要拉多次才能拖动的问题 if (params.x < 0) { params.x = 0; } else if (params.x + view.getWidth() > wm.getDefaultDisplay().getWidth()) { params.x = wm.getDefaultDisplay().getWidth() - view.getWidth(); } if (params.y < 0) { params.y = 0; } else if (params.y + view.getHeight() > wm.getDefaultDisplay().getHeight()) { params.y = wm.getDefaultDisplay().getHeight() - view.getHeight(); } //记录当前土司位置,把x y坐标值保存到sp中 //SpTools.putString(getApplicationContext(), MyConstants.TOASTX, params.x + ""); //SpTools.putString(getApplicationContext(), MyConstants.TOASTY, params.y + ""); default: break; } return false; } }); wm.addView(view, params);}
5、关闭土司
/** * 关闭土司 */protected void closeLocationToast() { // TODO Auto-generated method stub // 初始先执行一次 if (view != null) { wm.removeView(view); view = null;// 删除完 置为null }}
6、清单文件中添加权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
二、Toast源码及分析如下:
自定义土司
分析:看系统的Toast是怎么做出来
1,看Toast的源码
a, makeText方法 //构造土司对象,创建TN的实例 mTN = new TN(); Toast result = new Toast(context); LayoutInflater inflate = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View v = inflate.inflate(com.android.internal.R.layout.transient_notification, null); //土司显示的文本框 TextView tv = (TextView)v.findViewById(com.android.internal.R.id.message); tv.setText(text); result.mNextView = v;//把当前土司的view给mNextView属性 result.mDuration = duration;//土司显示的时长 return result; b,show方法 if (mNextView == null) { throw new RuntimeException("setView must have been called"); } INotificationManager service = getService(); String pkg = mContext.getPackageName(); TN tn = mTN; tn.mNextView = mNextView; try { service.enqueueToast(pkg, tn, mDuration); } catch (RemoteException e) { // Empty } c, TN的源代码 TN的构造函数: 初始化LayoutParams TN() { // XXX This should be changed to use a Dialog, with a Theme.Toast // defined that sets up the layout params appropriately. final WindowManager.LayoutParams params = mParams; params.height = WindowManager.LayoutParams.WRAP_CONTENT; params.width = WindowManager.LayoutParams.WRAP_CONTENT; params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; params.format = PixelFormat.TRANSLUCENT; params.windowAnimations = com.android.internal.R.style.Animation_Toast; params.type = WindowManager.LayoutParams.TYPE_TOAST; params.setTitle("Toast"); } 显示土司的代码: public void handleShow() { if (localLOGV) Log.v(TAG, "HANDLE SHOW: " + this + " mView=" + mView + " mNextView=" + mNextView); if (mView != mNextView) { // remove the old view if necessary handleHide(); mView = mNextView; mWM = WindowManagerImpl.getDefault(); final int gravity = mGravity; mParams.gravity = gravity; if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) { mParams.horizontalWeight = 1.0f; } if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.FILL_VERTICAL) { mParams.verticalWeight = 1.0f; } mParams.x = mX; mParams.y = mY; mParams.verticalMargin = mVerticalMargin; mParams.horizontalMargin = mHorizontalMargin; if (mView.getParent() != null) { if (localLOGV) Log.v(TAG, "REMOVE! " + mView + " in " + this); mWM.removeView(mView); } if (localLOGV) Log.v(TAG, "ADD! " + mView + " in " + this); //土司显示的真正代码 mWM.addView(mView, mParams); trySendAccessibilityEvent(); } }
2,分析结果(怎么添加toast):
土司是加载到WindowManager中 mView 土司显示的View mParams 土司在windowmanager中显示的参数配置 mWM.addView(mView, mParams);
3,拖动土司
前提: 去掉 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE 改变Toast类型,params.type = WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;//土司天生不相应事件,改变类型 给Toast加触摸事件 view.setOnTouchLi......
自定义toast的参数
// 土司的初始化参数 params = new WindowManager.LayoutParams(); ; params.height = WindowManager.LayoutParams.WRAP_CONTENT; params.width = WindowManager.LayoutParams.WRAP_CONTENT; //对齐方式左上角 params.gravity = Gravity.LEFT | Gravity.TOP; params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE /* | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE */ | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; params.format = PixelFormat.TRANSLUCENT; //初始化土司的位置 params.x = (int) Float.parseFloat(SpTools.getString(getApplicationContext(), MyConstants.TOASTX, "0")); params.y = (int) Float.parseFloat(SpTools.getString(getApplicationContext(), MyConstants.TOASTY, "0")); params.type = WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;// 土司天生不相应时间,改变类型 params.setTitle("Toast");
0 0
- 自定义可拖动土司
- 自定义土司随意拖动
- 自定义土司
- Android 自定义可移动土司及多击事件
- 自定义view,可拖动
- 自定义可拖动TextView
- 可拖动自定义view
- 手机卫士 自定义土司
- tableview 自定义可水平拖动
- Android自定义可拖动进度条
- android 自定义可拖动框
- Android初学之自定义土司
- Silverlight制作可拖动的自定义控件
- Android自定义可拖动组件+animation
- winform 可拖动的自定义Label控件
- Android 自定义可拖动尺子控件
- 自定义View绘制圆,可拖动
- 初学自定义view(可拖动圆)
- 再来说说Linux文件权限那些事儿
- PHP数据类型
- C# 通俗解释网络通信中的“报头”
- SGU 139 Help Needed!(机智)
- Linux进程调度
- 自定义可拖动土司
- //mywebshell.php
- 《暗时间》读书笔记1
- Window10下安装sbt
- C++第三次作业
- LeetCode——017
- get方法实例-登录
- 架构高性能网站秘笈(六)——构建数据缓冲区
- NSURLConnection取消连接