####自定义归属地的Toast
1. 在构造方法,构建Toast的params
> 这段代码是从Toast的内部类TN构造方法借鉴得出。
public AddressToast(Context context){
mWM = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
this.mContext = context;
mParams = new WindowManager.LayoutParams();
mParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
mParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
mParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
/* | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE*/
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
mParams.format = PixelFormat.TRANSLUCENT;
//mParams.windowAnimations = com.android.internal.R.style.Animation_Toast;
mParams.type = WindowManager.LayoutParams.TYPE_PHONE; //此处要添加一个权限。 SYSTEM_ALERT_WINDOW
mParams.setTitle("Toast");
}
2. 显示Toast
mView = (TextView) View.inflate(mContext, R.layout.view_address_toast, null);
mWM.addView(mView, mParams);
3. 隐藏Toast
if (mView.getParent() != null) {
mWM.removeView(mView);
}
mView = null;
4. 移动Toast
1. 对当前的view,执行触摸监听
mView.setOnTouchListener(this);
2. 移动toast
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: //按下
//event.getX() // 当前的触摸点到控件的左边间距
downX = event.getRawX(); // 当前的触摸点到屏幕的左边间距
downY = event.getRawY();
break;
case MotionEvent.ACTION_MOVE: //移动
moveX = event.getRawX(); // 当前的触摸点到屏幕的左边间距
moveY = event.getRawY();
//计算现在移动了多少距离 开始坐标(0 ,0 ) ---> (10 ,10) --->(20 , 20 )
int dx = Math.round(moveX - downX );
int dy = Math.round(moveY - downY );
//更新位置 一边移动,一边重置它的x 和 y的坐标点
mParams.x += dx;
mParams.y += dy ;
//根据最新的参数去重新确定view的位置
mWM.updateViewLayout(mView, mParams);
//重置downx downy
downX = moveX;
downY = moveY;
break;
小火箭
##小火箭
* 火箭的火焰效果
> 分析得出: 使用的帧动画实现
1. 在res文件夹里面生成一个文件夹 drawable , 定义一个xml文件
2. 播放动画
ImageView view = new ImageView(mContext);
//设置背景资源
view.setBackgroundResource(R.drawable.rocket_bg);
//得到背景资源,其实就是得到早前的动画对象
AnimationDrawable ad = (AnimationDrawable) view.getBackground();
//播放动画
ad.start();
1. 发射台的显示隐藏 与 火箭的显示隐藏 处理逻辑是一样
2. 火箭的移动 与 早前的号码归属地移动时一样的。
###对火箭的发射条件判断
> 获取某一个控件在屏幕中的坐标带你。
int [] location = new int[2];
//获取发射台的x 和 y坐标
mBottomView.getLocationOnScreen(location);
int bootomX = location[0];
int bottomY = location[1];
###对imageView的图片切换
iv.setBackgroundResource() ; // 设置背景资源
iv.setImageResource (); //设置前景资源
###让火箭往上升
> 核心点: 就是不断的捕获现在火箭想要到达的Y坐标。 380 ---> 0
//定义一个起始位置,和一个结束位置,然后让这个数字开始走,走多久( 500 s),规定一个时间。
ValueAnimator animator = ValueAnimator.ofInt(mRocketParams.y , 0 );
animator.setDuration(600);
animator.start();
//对动画执行监听
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//获取到现在这个数字走到了哪里
int value = (Integer) animation.getAnimatedValue();
Log.d("vv", "value=="+value);
mRocketParams.y =value ;
mWM.updateViewLayout(mRocketView, mRocketParams);
}
});
往屏幕上添加一个控件。
mWm.addView(view , params);
public class AddressToast implements OnTouchListener {
WindowManager.LayoutParams mParams;
WindowManager.LayoutParams mButtonParams;
WindowManager mWM;
Context mContext;
private ImageView mView,mButtonView;
public AddressToast(Context context){
mWM = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
this.mContext = context;
initRocketParams();
initButtonParams();
}
//底座的params
private void initButtonParams() {
mButtonParams = new WindowManager.LayoutParams();
mButtonParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
mButtonParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
mButtonParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
/* | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE*/
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
mButtonParams.format = PixelFormat.TRANSLUCENT;
//mParams.windowAnimations = com.android.internal.R.style.Animation_Toast;
mButtonParams.type = WindowManager.LayoutParams.TYPE_PHONE; //此处要添加一个权限。 SYSTEM_ALERT_WINDOW
mButtonParams.setTitle("Toast");
mButtonParams.gravity=Gravity.BOTTOM | Gravity.CENTER;
}
//火箭的params
private void initRocketParams() {
mParams = new WindowManager.LayoutParams();
mParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
mParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
mParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
/* | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE*/
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
mParams.format = PixelFormat.TRANSLUCENT;
//mParams.windowAnimations = com.android.internal.R.style.Animation_Toast;
mParams.type = WindowManager.LayoutParams.TYPE_PRIORITY_PHONE; //此处要添加一个权限。 SYSTEM_ALERT_WINDOW
mParams.setTitle("Toast");
mParams.gravity=Gravity.TOP | Gravity.LEFT;
}
public void show(){
mView=new ImageView(mContext);
mView.setBackgroundResource(R.drawable.rocket);
AnimationDrawable background = (AnimationDrawable) mView.getBackground();
background.start();
mView.setOnTouchListener(this);
mWM.addView(mView, mParams);
}
public void showButton(){
mButtonView=new ImageView(mContext);
mButtonView.setBackgroundResource(R.drawable.rocket1);
AnimationDrawable ButtonView = (AnimationDrawable) mButtonView.getBackground();
ButtonView.start();
mWM.addView(mButtonView, mButtonParams);
}
public void hide(){
if (mView != null) {
if (mView.getParent() != null) {
mWM.removeView(mView);
}
mView = null;
}
}
public void hideButton(){
if (mButtonView != null) {
if (mButtonView.getParent() != null) {
mWM.removeView(mButtonView);
}
mButtonView = null;
}
}
float downX, downY,moveX,moveY;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = event.getRawX();
downY = event.getRawY();
showButton();
break;
case MotionEvent.ACTION_MOVE:
moveX = event.getRawX();
moveY = event.getRawY();
int dx=Math.round(moveX-downX);
int dy=Math.round(moveY-downY);
mParams.x += dx;
mParams.y += dy;
//更新位置
mWM.updateViewLayout(mView, mParams);
downX=moveX;
downY=moveY;
//TODO 判断是否满足条件
if(isReadyToFly()){
System.out.println("满足条件。。。");
mButtonView.setBackgroundResource(R.drawable.desktop_bg_tips_3);
}else{
System.out.println("不满足条件。。。。。。。");
mButtonView.setBackgroundResource(R.drawable.rocket1);
AnimationDrawable ButtonView = (AnimationDrawable) mButtonView.getBackground();
ButtonView.start();
}
break;
case MotionEvent.ACTION_UP:
if(isReadyToFly()){
//获取屏幕宽度
getWidth();
//飞起
fiy();
}
hideButton();
break;
default:
break;
}
return false;
}
private void fiy() {
ValueAnimator animator=ValueAnimator.ofInt( mParams.y , 0);
animator.setDuration(600);
animator.start();
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int value = (Integer) animation.getAnimatedValue();
mParams.y=value;
mWM.updateViewLayout(mView, mParams);
}
});
Intent intent=new Intent(mContext,SmokeActivity.class);
// 由于咱们这里启动activity使用的上下文并不是activity的上下文, 系统在启动界面的时候
//会对上下文进行检验操作。如果activity的对象,那么需要添加一个标记,否则不允许启动界面。
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
}
private void getWidth() {
Display display = mWM.getDefaultDisplay();
Point point=new Point();
display.getSize(point);
int width=point.x;
mParams.x=width/2-mView.getWidth()/2;
//TODO 屏幕中间
mWM.updateViewLayout(mView, mParams);
mWM.updateViewLayout(mButtonView, mButtonParams);
}
private boolean isReadyToFly() {
//获取发射台的xy坐标
int[] location=new int[2];
mButtonView.getLocationOnScreen(location);
int butx=location[0];
int buty=location[1];
mView.getLocationOnScreen(location);
int viewx=location[0];
int viewy=location[1];
boolean isTop=buty-viewy<=mView.getHeight()/2;
boolean isLeft=butx-viewx<=mView.getWidth()/2;
boolean isRight=(mButtonView.getWidth()+butx)-viewx>=mView.getWidth()/2;
return isTop && isLeft && isRight;
}
}