Android模仿Toast实现提示框效果

这篇文章主要为大家详细介绍了Android模仿Toast实现提示框效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了Android模仿Toast实现提示框效果的具体代码,供大家参考,具体内容如下

Toast提示只要提示的时间够长,就可以浮动到其他任何界面之上,所以我们可以模仿Toast来实现来电号码归属地的提示框

1、WindowManager

The interface that apps use to talk to the window manager. Use Context.getSystemService(Context.WINDOW_SERVICE) to get one of these. Each window manager instance is bound to a particular Display.

1).void addView(View view,ViewGroup.LayoutParams params)
将一个View视图显示到当前窗口,LayoutParams are used by views to tell their parents how they want to be laid out.

2).void removeView(View view); 将一个View视图从当前窗口中移除。

2、自定义窗体提示框(参考Toast源码)

WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);  View view = View.inflate(getApplicationContext(), R.layout.toast_location,                 null);  TextView tv = (TextView) view.findViewById(R.id.tv_toast_address); tv.setText(address); LayoutParams params = new LayoutParams(); params.height = WindowManager.LayoutParams.WRAP_CONTENT; params.width = WindowManager.LayoutParams.WRAP_CONTENT; params.gravity = Gravity.LEFT | Gravity.TOP; params.x = sp.getInt("lastx", 0); params.y = sp.getInt("lasty", 0); //本来还有一个FLAG_NOTUCHALBE为了让下面能触摸把这个给去掉了 params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; params.format = PixelFormat.TRANSLUCENT;    //源码中这里是TYPE_TAOST但是这里为了下面要进行点击拖动事件,而Toast不能拖动, 所以这里改成了TYPE_PRIORITY_PHONE,这是一个系统类型的提示框,使用这个提示框必须要申请权限,android.permission.SYSTEM_ALERT_WINDOW params.type = WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;  wm.addView(view, params); 

3、WindowManager添加的显示框的简单拖动

该这个View注册一个onTouchListener

public void showLocation(String address) {     view = View.inflate(getApplicationContext(), R.layout.toast_location,             null);     // 得到spint which = sp.getInt("which", 0);     view.setBackgroundResource(bgs[which]);     view.setOnTouchListener(new OnTouchListener() {         int startX ,startY;         public boolean onTouch(View v, MotionEvent event) {             switch (event.getAction()) {             case MotionEvent.ACTION_DOWN:Log.i(TAG,"摸到");                 startX = (int) event.getRawX();                 startY  = (int) event.getRawY();                 break;             case MotionEvent.ACTION_MOVE:Log.i(TAG,"移动");                 int newX = (int) event.getRawX();                 int newY  = (int) event.getRawY();                 int dx = newX - startX;                 int dy = newY - startY;                 params.x+=dx;                 params.y+=dy;   //这里在WindowManager中不能够使用layout方法了,无效,只能使用layoutparams来更新位置,这里的params就是上面的那个params                 wm.updateViewLayout(view, params);                 //重新初始化 手指的位置                 startX = (int) event.getRawX();                 startY  = (int) event.getRawY();                 break;             }             return true;         }     }); }

4、普通ImageView随手指拖动改变位置

iv_drag_view.setOnTouchListener(new OnTouchListener() {     //记录住最初手指按下时的位置int startX , startY;      //onTouch方法的返回值如果是true监听器会把这个事件给消费掉, false则监听器不会消费掉这个事件public boolean onTouch(View v, MotionEvent event) {         switch (event.getAction()) {               case MotionEvent.ACTION_DOWN:Log.i(TAG,"摸到这个控件了");                 startX = (int) event.getRawX();//记录手指第一次点击到屏幕时候距离x和y轴的距离                 startY = (int) event.getRawY();             break;             case MotionEvent.ACTION_MOVE:// 手指在屏幕上移动的事件Log.i(TAG,"移动");                 int newX = (int) event.getRawX(); //在移动的过程中不断的获取到手指当前移动到的位置int newY = (int) event.getRawY();                 int dx = newX - startX;           //计算出手指移动了多少int dy = newY - startY;                 int l = iv_drag_view.getLeft(); //获取图片上下左右的长度int r = iv_drag_view.getRight();                 int b = iv_drag_view.getBottom();                 int t = iv_drag_view.getTop();                 int newl = l+dx; //计算图片应该移动的距离int newr = r+dx;                 int newt = t+dy;//imageview 在窗体中新的位置int newb = b+dy;                 //判断如果图片准备移动到的位置超出了屏幕就不让它移动,这里减去30是减去窗体上面的状态栏的高度if(newl<0||newt <0 ||newb>display.getHeight()-30||newr>display.getWidth()){                     break;                 }                             //将图片移动到新的位置。直接调用ImageView的layout方法                 iv_drag_view.layout(newl,  newt, newr, newb);                  //一旦图片移动到新的位置就重新计算手指当前的位置,这样循环下去就能实现随着手指的拖动                 startX = (int) event.getRawX();                 startY = (int) event.getRawY();             break;             case MotionEvent.ACTION_UP: // 手指在离开屏幕的一瞬间对应的事件.Log.i(TAG,"放手");             int lasty = iv_drag_view.getTop();//得到最后在离屏幕上方的距离int lastx = iv_drag_view.getLeft();//得到最后离屏幕左边的距离Editor editor = sp.edit();             editor.putInt("lastx", lastx);             editor.putInt("lasty", lasty);             editor.commit();             break;         }             return true; //这地方一定要返回true告诉系统这个事件做完了     } });

注意:在onCreate方法中使用layout方法是没有效果的,因为在进入一个Activity中系统首先会执行一个计算的操作,计算各个控件的布局,然后调用setContentView方法显示出来这个控件,第二步才会执行这个layout方法,但是在onCreate方法中设置了layout,在执行layout这段代码的时候,窗体有可能还没有计算完控件的布局,所以先执行了这个layout,然后又执行了计算控件布局来显示,这样layout就没效了,这里要怎么弄呢只能是通过设置这个控件的layout布局,这样在计算位置的时候就能计算了,这样设置布局能让它在计算的时候就计算了。如下,在onCreate方法中去这样设置。

protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     sp = getSharedPreferences("config", MODE_PRIVATE);     // Have the system blur any windows behind this one.     getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,             WindowManager.LayoutParams.FLAG_BLUR_BEHIND);     wm = (WindowManager) getSystemService(WINDOW_SERVICE);//窗体管理者     display = wm.getDefaultDisplay();     setContentView(R.layout.activity_drag_view);     tv_drag_view = (TextView) findViewById(R.id.tv_drag_view);     iv_drag_view = (ImageView) findViewById(R.id.iv_drag_view);     int lastx = sp.getInt("lastx", 0);     int lasty = sp.getInt("lasty", 0);     RelativeLayout.LayoutParams params = (LayoutParams) iv_drag_view.getLayoutParams();     params.leftMargin = lastx;     params.topMargin = lasty;     iv_drag_view.setLayoutParams(params);  }

注意:在WindowManager中要想更新控件的距离就不能用layout方法了,只能用mWindowManager.updateViewLayout(view, params);

5、实现双击事件

1).双击的定义 Android中没有提供双击的点击事件,双击就是单位时间内的两次点击

2).触摸和点击事件的区别 点击事件: 一组动作的集合 点击 - 停留 - 离开. 触摸事件: 手指按下屏幕 手指在屏幕上移动 手指离开屏幕的一瞬间

public class DragViewActivity extends Activity {     protected static final String TAG = "DragViewActivity";     private ImageView iv_drag_view;     private TextView tv_drag_view;     private SharedPreferences sp;     private WindowManager wm;     private Display  display; //窗体的显示的分辨率private long firstClickTime;//第一次点击时候的事件@Overrideprotected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         sp = getSharedPreferences("config", MODE_PRIVATE);         // Have the system blur any windows behind this one.         getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,                 WindowManager.LayoutParams.FLAG_BLUR_BEHIND);         wm = (WindowManager) getSystemService(WINDOW_SERVICE);//窗体管理者         display = wm.getDefaultDisplay();         setContentView(R.layout.activity_drag_view);         tv_drag_view = (TextView) findViewById(R.id.tv_drag_view);         iv_drag_view = (ImageView) findViewById(R.id.iv_drag_view);         int lastx = sp.getInt("lastx", 0);         int lasty = sp.getInt("lasty", 0);         RelativeLayout.LayoutParams params = (LayoutParams) iv_drag_view.getLayoutParams();         params.leftMargin = lastx;         params.topMargin = lasty;         iv_drag_view.setLayoutParams(params);         iv_drag_view.setOnClickListener(new OnClickListener() {             public void onClick(View v) {                 Log.i(TAG,"被点击了.");                 if(firstClickTime>0){//说明这是第二次点击.long secondTime = System.currentTimeMillis();                     long dtime = secondTime - firstClickTime;                     if(dtime<500){                         //双击事件.Log.i(TAG,"双击居中");                         int iv_width = iv_drag_view.getRight() - iv_drag_view.getLeft();                         iv_drag_view.layout(display.getWidth()/2-iv_width/2, iv_drag_view.getTop(), display.getWidth()/2+iv_width/2, iv_drag_view.getBottom());                         int lasty = iv_drag_view.getTop();//得到最后在离屏幕上方的距离int lastx = iv_drag_view.getLeft();//得到最后离屏幕左边的距离Editor editor = sp.edit();                         editor.putInt("lastx", lastx);                         editor.putInt("lasty", lasty);                         editor.commit();                     }                     firstClickTime = 0;//将第一次点击的时间还原成0。return;                 } else {                 //第一次点击                     firstClickTime = System.currentTimeMillis();//  记录第一次点击的时间//新开一个线程,在这个子线程中如果是500毫秒内没有再点击就将第一次点击的时间设置为0new Thread(){                         public void run() {                             try {                                 Thread.sleep(500);                                 firstClickTime = 0;                             } catch (InterruptedException e) {                                 e.printStackTrace();                             }                         };                     }.start();                 }                            }         });     } }

6、触摸和双击同时发生时候的返回值

//onTouch方法的返回值,True if the listener has consumed the event, false otherwise,true 监听器会把这个事件给消费掉, false 不会消费掉这个事件 iv_drag_view.setOnTouchListener(new OnTouchListener() {     int startX , startY;     public boolean onTouch(View v, MotionEvent event) {         switch (event.getAction()) {         case MotionEvent.ACTION_DOWN:// 手指触摸到屏幕的事件Log.i(TAG,"摸到这个控件了");             startX = (int) event.getRawX();             startY = (int) event.getRawY();             break;         case MotionEvent.ACTION_MOVE:// 手指在屏幕上移动的事件Log.i(TAG,"移动");             int newX = (int) event.getRawX();             int newY = (int) event.getRawY();             int dx = newX - startX;             int dy = newY - startY;             int l = iv_drag_view.getLeft();             int r = iv_drag_view.getRight();             int b = iv_drag_view.getBottom();             int t = iv_drag_view.getTop();             int newl = l+dx;             int newr = r+dx;             int newt = t+dy;//imageview 在窗体中新的位置int newb = b+dy;             if(newl<0||newt <0 ||newb>display.getHeight()-30||newr>display.getWidth()){                 break;             }             int tv_height = tv_drag_view.getBottom() - tv_drag_view.getTop();             if(newt>display.getHeight()/2){//imageview在窗体的下方//textview在窗体的上方                 tv_drag_view.layout(tv_drag_view.getLeft(), 0, tv_drag_view.getRight(), tv_height);             }else{                 tv_drag_view.layout(tv_drag_view.getLeft(), display.getHeight()-tv_height-30, tv_drag_view.getRight(), display.getHeight()-30);                 //textview在窗体的下方             }             iv_drag_view.layout(newl,  newt, newr, newb);             //更新手指开始的位置.             startX = (int) event.getRawX();             startY = (int) event.getRawY();             break;         case MotionEvent.ACTION_UP: // 手指在离开屏幕的一瞬间对应的事件.Log.i(TAG,"放手");             int lasty = iv_drag_view.getTop();//得到最后在离屏幕上方的距离int lastx = iv_drag_view.getLeft();//得到最后离屏幕左边的距离Editor editor = sp.edit();             editor.putInt("lastx", lastx);             editor.putInt("lasty", lasty);             editor.commit();             break;         }         // 这里对于触摸事件应该是返回true为什么这里返回false呢,因为这里这一个控件同时实现了点击和触摸这两个事件,如果返回true,// 那么就不可能发生点击事件了,所以对于同时实现点击和触摸的控件返回值要为falsereturn false;     } });

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持0133技术站。

以上就是Android模仿Toast实现提示框效果的详细内容,更多请关注0133技术站其它相关文章!

赞(0) 打赏
未经允许不得转载:0133技术站首页 » 移动