日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Android模仿Toast實現提示框效果_Android

作者:Scofield_Phil ? 更新時間: 2022-10-05 編程語言

本文實例為大家分享了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;
? ? }
});

原文鏈接:https://blog.csdn.net/Scotfield_msn/article/details/52492134

欄目分類
最近更新