自定义View

自定义View

  1. 自定义Toast
01-自定义Toast
  • 需求 : 自定义Toast,并可任意拖动.
  • 实现 :
    • 通过分析Toast源码可以得出以下结论
      1. Toast的显示是通过WindowManager的addView方法实现的
      2. Toast的隐藏是通过WindowManager的removeView方法实现的
      3. 如果希望Toast可触摸被拖动
        1. 去掉WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE 属性
        2. 更改类型为WindowManager.LayoutParams.TYPE_PRIORITY_PHONE.
        3. 为该视图添加OnTouchListener, 并实现对应的触摸事件
      4. 使用WindowManager.LayoutParams.TYPE_PRIORITY_PHONE类型, 需要添加权限
      5. 视图的更新使用WindowManager的updateViewLayout方法实现
      6. Toast的隐藏在PhoneStateListener中TelephonyManager.CALL_STATE_IDLE状态下实现
  • 代码:

    public class LocationToast implements OnTouchListener {
    
        private WindowManager mWM;
        private Context context;
        private View mView;
        private WindowManager.LayoutParams params = new WindowManager.LayoutParams();
        private float startX;
        private float startY;
    
        public LocationToast(Context context) {
            this.context = context;
            // 初始化WindowManager
            mWM = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            // 初始化LayoutParams
            params.height = WindowManager.LayoutParams.WRAP_CONTENT;
            params.width = WindowManager.LayoutParams.WRAP_CONTENT;
            params.format = PixelFormat.TRANSLUCENT;// 图片显示的格式
            params.type = WindowManager.LayoutParams.TYPE_TOAST;// 设置窗体的类型
            params.setTitle("Toast");
            // 添加到WindowManager后如何显示
            params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON // 屏幕常亮
                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;// 禁止获取焦点
        }
    
        // 显示Toast
        public void show(String msg) {
            if (mView == null) {
                mView = View.inflate(context, R.layout.location_toast, null);
                mView.setOnTouchListener(this);
            }
    
            // 获取界面上的TextView, 并设置文本
            TextView tView = (TextView) mView.findViewById(R.id.act_location_tv_location);
            tView.setText(msg);
            // 显示Toast
    
            if (mView.getParent() != null) {
                mWM.removeView(mView);
            }
            mWM.addView(mView, params);
        }
    
        // 隐藏Toast
        public void hide() {
            if (mView != null) {
                if (mView.getParent() != null) {
                    mWM.removeView(mView);
                }
                mView = null;
            }
        }
    
        // 拖动事件
        @Override
        public boolean onTouch(View v, MotionEvent event) {
    
            int action = event.getAction();
            // 手指按下时获取坐标点
            if (action == MotionEvent.ACTION_DOWN) {
                startX = event.getRawX();
                startY = event.getRawY();
            } else if (action == MotionEvent.ACTION_MOVE) {
                // 手指移动时获取坐标点
                float currentX = event.getRawX();
                float currentY = event.getRawY();
                // 获取偏移量
                float movedX = currentX - startX;
                float movedY = currentY - startY;
                // 让View根据偏移量移动
                params.x += (int) movedX;
                params.y += (int) movedY;
                mWM.updateViewLayout(mView, params);
                // 重置坐标点
                startX = currentX;
                startY = currentY;
            }
    
            return false;
        }
    } 
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值