自定义可拖动的Toast
package com.loaderman.toastdemo; import android.content.Context; import android.graphics.PixelFormat; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.widget.TextView; /** * * 自定义归属地吐司 * <p/> * 让窗口布局响应触摸事件: * 1. 去掉FLAG_NOT_TOUCHABLE的标记 * 2. 调整显示级别为TYPE_PHONE, 可以支持触摸 * 3. 加权限: <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> */ public class AddressToast { private WindowManager mWM; private View mView; private final WindowManager.LayoutParams mParams; private final TextView tvAddress; private int startX; private int startY; private Context mContext; private int[] mIcons = new int[]{R.drawable.shape_address_normal, R.drawable .shape_address_orange, R.drawable.shape_address_blue, R.drawable.shape_address_gray, R.drawable.shape_address_green}; public AddressToast(Context ctx) { mContext = ctx; //窗口管理器 //窗口: android系统中最顶级的布局, 任何的界面和组件都显示在窗口中, Activity, 状态栏, dialog //当需要在第三方app中显示布局时, 由于没有activity可以依托,此时可以直接使用WindowManager在窗口上添加布局 mWM = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE); //初始化布局参数, 定义当前布局的宽高,位置,显示方式等信息 mParams = new WindowManager.LayoutParams(); mParams.height = WindowManager.LayoutParams.WRAP_CONTENT;//高度包裹内容 mParams.width = WindowManager.LayoutParams.WRAP_CONTENT;//宽度包裹内容 mParams.format = PixelFormat.TRANSLUCENT;//显示格式,默认就行 //params.windowAnimations = com.android.internal.R.style.Animation_Toast;//窗口动画 mParams.type = WindowManager.LayoutParams.TYPE_PHONE;//类型, 吐司类型(不支持触摸) //params.setTitle("Toast");//标题 //标记, 保持屏幕常亮, 没有焦点, 不可触摸 mParams.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; // | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; // mParams.x; // mParams.y; //初始化布局 // mView = new TextView(ctx); // mView.setText(text); // mView.setTextColor(Color.RED); // mView.setTextSize(25); mView = View.inflate(ctx, R.layout.toast_address, null); tvAddress = (TextView) mView.findViewById(R.id.tv_address); //设置窗口布局的触摸事件 mView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: System.out.println("按下..."); //1.记录起点坐标 startX = (int) event.getRawX(); startY = (int) event.getRawY(); break; case MotionEvent.ACTION_MOVE: System.out.println("移动..."); //2. 记录移动后的坐标 int moveX = (int) event.getRawX(); int moveY = (int) event.getRawY(); //3. 计算偏移量 int dx = moveX - startX; int dy = moveY - startY; //4. 根据偏移量更新布局位置 mParams.x += dx; mParams.y += dy; mWM.updateViewLayout(mView, mParams);//更新控件位置 //5. 重新初始化起点坐标 startX = moveX; startY = moveY; break; case MotionEvent.ACTION_UP: System.out.println("抬起..."); break; default: break; } return true;//消费掉此事件 } }); } //显示布局 public void show(String text) { //mView.setText(text); tvAddress.setText(text); //获取当前选中的样式 tvAddress.setBackgroundResource(mIcons[0]);//重新设置背景 //给窗口添加布局对象 mWM.addView(mView, mParams); } //隐藏布局 public void hide() { if (mWM != null && mView != null) { //移除窗口布局 //布局没有添加给窗口时, 从窗口移除布局就会出异常 try { mWM.removeView(mView); } catch (Exception e) { e.printStackTrace(); } } } }
package com.loaderman.toastdemo; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; public class MainActivity extends AppCompatActivity { private AddressToast mToast; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mToast = new AddressToast(this); } public void display(View view){ mToast.show("自定义的哦"); } public void hide(View view){ mToast.hide(); } }
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.loaderman.toastdemo.MainActivity"> <Button android:id="@+id/btn_show" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="display" android:text="显示"/> <Button android:id="@+id/btn_hide" android:onClick="hide" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="隐藏"/> </LinearLayout>
toast_address.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/tv_address" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/shape_address_normal" android:drawableLeft="@drawable/location" android:text="未知号码" android:padding="8dp" android:textColor="@color/white" android:textSize="18sp"/> </LinearLayout>
在res/drawable下
shape_address_blue.xml shape_address_gray.xml shape_address_green.xml shape_normal_blue.xml shape_address_orange.xml只需要把下面代码需要以下color即可
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <!--颜色--> <solid android:color="@color/global_blue"/> <!--给矩形加圆角--> <corners android:radius="6dp"/> </shape>
在res/values/colors.xml添加需求颜色值即可如
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#3F51B5</color> <color name="colorPrimaryDark">#303F9F</color> <color name="colorAccent">#FF4081</color> <color name="red">#F00</color> <color name="black">#000</color> <color name="gray">#a000</color> <color name="global_blue">#459FD7</color> <color name="white">#fff</color> <color name="light_gray">#cccccc</color> <color name="light_green">#00ffa1</color> </resources>
添加权限:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
效果图:
最后,关注【码上加油站】微信公众号后,有疑惑有问题想加油的小伙伴可以码上加入社群,让我们一起码上加油吧!!!