Android模仿Toast實現(xiàn)提示框效果
本文實例為大家分享了Android模仿Toast實現(xiàn)提示框效果的具體代碼,供大家參考,具體內(nèi)容如下
Toast提示只要提示的時間夠長,就可以浮動到其他任何界面之上,所以我們可以模仿Toast來實現(xiàn)來電號碼歸屬地的提示框
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,這是一個系統(tǒng)類型的提示框,使用這個提示框必須要申請權(quán)限,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監(jiān)聽器會把這個事件給消費掉, false則監(jiān)聽器不會消費掉這個事件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是減去窗體上面的狀態(tài)欄的高度if(newl<0||newt < 0 ||newb>display.getHeight()-30||newr>display.getWidth()){ ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? //將圖片移動到新的位置。直接調(diào)用ImageView的layout方法 ? ? ? ? ? ? ? ? iv_drag_view.layout(newl, ?newt, newr, newb);? ? ? ? ? ? ? ? ? //一旦圖片移動到新的位置就重新計算手指當前的位置,這樣循環(huán)下去就能實現(xiàn)隨著手指的拖動 ? ? ? ? ? ? ? ? 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告訴系統(tǒng)這個事件做完了 ? ? } });
注意:在onCreate方法中使用layout方法是沒有效果的,因為在進入一個Activity中系統(tǒng)首先會執(zhí)行一個計算的操作,計算各個控件的布局,然后調(diào)用setContentView方法顯示出來這個控件,第二步才會執(zhí)行這個layout方法,但是在onCreate方法中設置了layout,在執(zhí)行l(wèi)ayout這段代碼的時候,窗體有可能還沒有計算完控件的布局,所以先執(zhí)行了這個layout,然后又執(zhí)行了計算控件布局來顯示,這樣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、實現(xiàn)雙擊事件
1).雙擊的定義 Android中沒有提供雙擊的點擊事件,雙擊就是單位時間內(nèi)的兩次點擊
2).觸摸和點擊事件的區(qū)別 點擊事件: 一組動作的集合 點擊 - 停留 - 離開. 觸摸事件: 手指按下屏幕 手指在屏幕上移動 手指離開屏幕的一瞬間
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毫秒內(nèi)沒有再點擊就將第一次點擊的時間設置為0new Thread(){ ? ? ? ? ? ? ? ? ? ? ? ? public void run() { ? ? ? ? ? ? ? ? ? ? ? ? ? ? try { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Thread.sleep(500); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? firstClickTime = 0; ? ? ? ? ? ? ? ? ? ? ? ? ? ? } catch (InterruptedException e) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? }; ? ? ? ? ? ? ? ? ? ? }.start(); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ?? ? ? ? ? ? ? } ? ? ? ? }); ? ? } }
6、觸摸和雙擊同時發(fā)生時候的返回值
//onTouch方法的返回值,True if the listener has consumed the event, false otherwise,true 監(jiān)聽器會把這個事件給消費掉, 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呢,因為這里這一個控件同時實現(xiàn)了點擊和觸摸這兩個事件,如果返回true,// 那么就不可能發(fā)生點擊事件了,所以對于同時實現(xiàn)點擊和觸摸的控件返回值要為falsereturn false; ? ? } });
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Android使用RadioGroup實現(xiàn)底部導航欄
這篇文章主要為大家詳細介紹了Android使用RadioGroup實現(xiàn)底部導航欄,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-08-08Android實現(xiàn)側(cè)滑菜單DrawerLayout
這篇文章主要為大家詳細介紹了Android實現(xiàn)側(cè)滑菜單DrawerLayout,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-05-05在Android中如何使用DataBinding詳解(Kotlin)
這篇文章主要給大家介紹了關于在Android中如何使用DataBinding(Kotlin)的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-11-11Android版微信跳一跳小游戲利用技術手段達到高分的操作方法
朋友圈到處都是曬微信跳一跳小游戲的,很多朋友能達到二三百分了。下面小編給大家分享Android版微信跳一跳小游戲利用技術手段達到高分的操作方法,需要的朋友一起看看吧2018-01-01Ionic2創(chuàng)建App啟動頁左右滑動歡迎界面
使用Ionic2創(chuàng)建應用非常簡單,只需在V1的命令后跟上--v2即可.這篇文章主要介紹了Ionic2創(chuàng)建App啟動頁左右滑動歡迎界面的相關資料,需要的朋友可以參考下2016-10-10