亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統(tǒng) > Android > 正文

Android仿QQ消息提示點拖拽功能

2019-10-21 21:26:29
字體:
供稿:網(wǎng)友

很久以前,發(fā)現(xiàn)QQ有一個很有趣的功能,就是未讀消息的紅點是可以拖拽的,而且在任何地方都可以隨意拖拽,并且有一個彈性的動畫,非常有趣,而且也是一個非常方便的功能,于是總想仿制一個,雖說仿制,但也只是他的拖拽功能,彈性效果還是能力有限。

不多說 先上效果

Android,仿QQ,提示點,拖拽

一個自定義的view 使用方式也很簡單

<com.weizhenbin.show.widget.VanishView  android:layout_width="30dp"  android:layout_height="30dp"  android:text="5"  android:layout_alignParentBottom="true"  android:gravity="center"  android:textColor="#fff"  android:id="@+id/vv"  android:layout_marginBottom="35dp"  android:layout_marginLeft="80dp"  android:background="@drawable/shape_red_bg"/>

然后先看下源碼

 

** * Created by weizhenbin on 16/6/1. * <p/> * 一個可以隨意拖動的view */public class VanishView extends TextView { private Context context; /**窗口管理器*/ private WindowManager windowManager; /**用來存儲鏡像的imageview*/ private ImageView iv; /** 狀態(tài)欄高度*/ private int statusHeight = 0; /**按下的坐標x 相對于view自身*/ private int dx = 0; /**按下的坐標y 相對于view自身*/ private int dy = 0; /**鏡像bitmap*/ private Bitmap tmp; /**按下的坐標x 相對于屏幕*/ private float downX = 0; /**按下的坐標y 相對于屏幕*/ private float downY = 0; /**屬性動畫 用于回彈效果*/ private ValueAnimator animator; /**窗口參數(shù)*/ private WindowManager.LayoutParams mWindowLayoutParams; /**接口對象*/ private OnListener listener; public VanishView(Context context) {  super(context);  init(context); } public VanishView(Context context, AttributeSet attrs) {  super(context, attrs);  init(context); } public VanishView(Context context, AttributeSet attrs, int defStyleAttr) {  super(context, attrs, defStyleAttr);  init(context); } private void init(Context context) {  this.context = context;  windowManager = ((Activity) context).getWindowManager();  statusHeight = getStatusHeight(context); } @Override public boolean onTouchEvent(MotionEvent event) {  switch (event.getAction()) {   case MotionEvent.ACTION_DOWN:    dx = (int) event.getX();    dy = (int) event.getY();    downX = event.getRawX();    downY = event.getRawY();    addWindow(context, event.getRawX(), event.getRawY());    setVisibility(INVISIBLE);    break;   case MotionEvent.ACTION_MOVE:    mWindowLayoutParams.x = (int) (event.getRawX() - dx);    mWindowLayoutParams.y = (int) (event.getRawY() - statusHeight - dy);    windowManager.updateViewLayout(iv, mWindowLayoutParams);    break;   case MotionEvent.ACTION_UP:    int distance=distance(new MyPoint(event.getRawX(), event.getRawY()), new MyPoint(downX, downY));    if(distance<400) {     scroll(new MyPoint(event.getRawX(), event.getRawY()), new MyPoint(downX, downY));    }else {     if(listener!=null){      listener.onDismiss();     }     windowManager.removeView(iv);    }    break;  }  return true; } /**  * 構(gòu)建一個窗口 用于存放和移動鏡像  * */ private void addWindow(Context context, float downX, float dowmY) {  mWindowLayoutParams = new WindowManager.LayoutParams();  mWindowLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;  mWindowLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;  iv = new ImageView(context);  mWindowLayoutParams.format = PixelFormat.RGBA_8888;  mWindowLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;  mWindowLayoutParams.x = (int) (downX - dx);  mWindowLayoutParams.y = (int) (dowmY - statusHeight - dy);  //獲取view的鏡像bitmap  this.setDrawingCacheEnabled(true);  tmp = Bitmap.createBitmap(this.getDrawingCache());  //釋放緩存  this.destroyDrawingCache();  iv.setImageBitmap(tmp);  windowManager.addView(iv, mWindowLayoutParams); } /**  * 使用屬性動畫 實現(xiàn)緩慢回彈效果  * */ private void scroll(MyPoint start, MyPoint end) {  animator = ValueAnimator.ofObject(new MyTypeEvaluator(), start, end);  animator.setDuration(200);  animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {   @Override   public void onAnimationUpdate(ValueAnimator animation) {    MyPoint point = (MyPoint) animation.getAnimatedValue();    mWindowLayoutParams.x = (int) (point.x - dx);    mWindowLayoutParams.y = (int) (point.y - statusHeight - dy);    windowManager.updateViewLayout(iv, mWindowLayoutParams);   }  });  animator.addListener(new AnimatorListenerAdapter() {   @Override   public void onAnimationEnd(Animator animation) {    super.onAnimationEnd(animation);    windowManager.removeView(iv);    setVisibility(VISIBLE);   }  });  animator.start(); } /**  * 計算兩點的距離  */ private int distance(MyPoint point1, MyPoint point2) {  int distance = 0;  if (point1 != null && point2 != null) {   float dx = point1.x - point2.x;   float dy = point1.y - point2.y;   distance = (int) Math.sqrt(dx * dx + dy * dy);  }  return distance; } /**  * 獲取狀態(tài)欄的高度  */ private static int getStatusHeight(Context context) {  int statusHeight = 0;  Rect localRect = new Rect();  ((Activity) context).getWindow().getDecorView().getWindowVisibleDisplayFrame(localRect);  statusHeight = localRect.top;  if (0 == statusHeight) {   Class<?> localClass;   try {    localClass = Class.forName("com.android.internal.R$dimen");    Object localObject = localClass.newInstance();    int i5 = Integer.parseInt(localClass.getField("status_bar_height").get(localObject).toString());    statusHeight = context.getResources().getDimensionPixelSize(i5);   } catch (Exception e) {    e.printStackTrace();   }  }  return statusHeight; } class MyPoint {  float x;  float y;  public MyPoint(float x, float y) {   this.x = x;   this.y = y;  }  @Override  public String toString() {   return "MyPoint{" +     "x=" + x +     ", y=" + y +     '}';  } } class MyTypeEvaluator implements TypeEvaluator<MyPoint> {  @Override  public MyPoint evaluate(float fraction, MyPoint startValue, MyPoint endValue) {   MyPoint point = startValue;   point.x = startValue.x + fraction * (endValue.x - startValue.x);   point.y = startValue.y + fraction * (endValue.y - startValue.y);   return point;  } } /**事件回調(diào)借口*/ public interface OnListener{  void onDismiss(); } public void setListener(OnListener listener) {  this.listener = listener; }

實現(xiàn)這一功能其實也不難,這個功能涉及到以下幾個知識點

使用WindowManager添加一個view
使用ValueAnimator屬性動畫實現(xiàn)回彈效果
getX和getRawX,getY和getRawY的區(qū)別

1.使用WindowManager添加一個view

 /**  * 構(gòu)建一個窗口 用于存放和移動鏡像  * */ private void addWindow(Context context, float downX, float dowmY) {  mWindowLayoutParams = new WindowManager.LayoutParams();  mWindowLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;  mWindowLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;  iv = new ImageView(context);  mWindowLayoutParams.format = PixelFormat.RGBA_8888;  mWindowLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;  mWindowLayoutParams.x = (int) (downX - dx);  mWindowLayoutParams.y = (int) (dowmY - statusHeight - dy);  //獲取view的鏡像bitmap  this.setDrawingCacheEnabled(true);  tmp = Bitmap.createBitmap(this.getDrawingCache());  //釋放緩存  this.destroyDrawingCache();  iv.setImageBitmap(tmp);  windowManager.addView(iv, mWindowLayoutParams); }

這一步是為了投影一個鏡像來達到拖動view的一個假像效果,使用imageview來顯示。這里為了使投影沒用偏移需要了解getX getRawX getY getRawY的區(qū)別

Android,仿QQ,提示點,拖拽

getX和getY 是相對于view自身的,getRawX和getRawY是像對屏幕的,這里還要扣除掉狀態(tài)欄的高度。

2.移動

 windowManager.updateViewLayout(iv, mWindowLayoutParams);

3.使用ValueAnimator屬性動畫實現(xiàn)回彈效果

這里自定義了TypeEvaluator實現(xiàn)點的位移動畫

class MyTypeEvaluator implements TypeEvaluator<MyPoint> {  @Override  public MyPoint evaluate(float fraction, MyPoint startValue, MyPoint endValue) {   MyPoint point = startValue;   point.x = startValue.x + fraction * (endValue.x - startValue.x);   point.y = startValue.y + fraction * (endValue.y - startValue.y);   return point;  } } /**  * 使用屬性動畫 實現(xiàn)緩慢回彈效果  * */ private void scroll(MyPoint start, MyPoint end) {  animator = ValueAnimator.ofObject(new MyTypeEvaluator(), start, end);  animator.setDuration(200);  animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {   @Override   public void onAnimationUpdate(ValueAnimator animation) {    MyPoint point = (MyPoint) animation.getAnimatedValue();    mWindowLayoutParams.x = (int) (point.x - dx);    mWindowLayoutParams.y = (int) (point.y - statusHeight - dy);    windowManager.updateViewLayout(iv, mWindowLayoutParams);   }  });  animator.addListener(new AnimatorListenerAdapter() {   @Override   public void onAnimationEnd(Animator animation) {    super.onAnimationEnd(animation);    windowManager.removeView(iv);    setVisibility(VISIBLE);   }  });  animator.start(); }

通過屬性動畫實現(xiàn)一個回彈效果

4.觸發(fā)消失的時機

 /**  * 計算兩點的距離  */ private int distance(MyPoint point1, MyPoint point2) {  int distance = 0;  if (point1 != null && point2 != null) {   float dx = point1.x - point2.x;   float dy = point1.y - point2.y;   distance = (int) Math.sqrt(dx * dx + dy * dy);  }  return distance; }

計算兩點之間的距離來觸發(fā)一個回調(diào)事件。

int distance=distance(new MyPoint(event.getRawX(), event.getRawY()), new MyPoint(downX, downY));    if(distance<400) {     scroll(new MyPoint(event.getRawX(), event.getRawY()), new MyPoint(downX, downY));    }else {     if(listener!=null){      listener.onDismiss();     }     windowManager.removeView(iv);    }

代碼分析就到這里,實現(xiàn)這個功能的核心代碼都在這里。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識閱讀請移步到Android開發(fā)頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
日本韩国精品一区二区在线观看| 妖精视频一区二区三区| 国产精品久久久久久久app| 国产成人久久久精品一区| 视频国产在线观看| 在线观看岛国av| 欧美成人性福生活免费看| 亚洲精选av在线| 国产韩日精品| 国产麻豆精品| 欧美日韩久久久久久| 在线免费日韩| 欧美日韩一区二区在线观看视频| 亚洲国产视频二区| 国内自拍偷拍视频| 性欧美长视频| 国产免费无码一区二区| 亚洲精品国产手机| 午夜精品视频在线观看一区二区| 亚洲欧美精品中文第三| 欧美xxxx黑人| 久久亚洲国产精品一区二区| 日本一区视频在线| 超碰国产在线观看| 亚洲一区二区在线观看视频| av播放官网| 亚洲黄色精品| 四虎影视国产精品| 日韩精品一区二区三区丰满| 成人亲热视频网站| 亚洲一区二区三区四区五区中文| 69xxx免费| 最新亚洲国产| 免费看黄色a级片| 欧美一区二区大胆人体摄影专业网站| 欧美亚洲国产日韩2020| 91精品国产色综合久久不卡蜜臀| 欧美重口另类| 波多野结衣家庭教师视频| 99久热在线精品996热是什么| 欧美另类一区二区| 中文字幕国产一区| 色呦呦久久久| 国产色a在线| 久久久久久国产精品| 中文字幕乱码亚洲精品一区| 9191国产精品| 国产精品一区二区不卡| 国产一区二区三区精彩视频| 日本美女xxx| 加勒比婷婷色综合久久| 欧美1区2区3| 男人影院在线观看| 久久av国产紧身裤| 91日本在线观看| 亚洲在线视频免费观看| 好吊日在线视频| 欧美夫妻性视频| 我想看黄色大片| 三级黄色片免费观看| 久久草.com| 三级中文字幕在线观看| 波多野结衣加勒比| 中日韩脚交footjobhd| 性欧美16一18| 激情亚洲成人| 中文字幕永久视频| 国产精品久久久久久户外露出| 亚洲免费在线观看视频| 久久激情免费视频| 加勒比在线日本| 亚洲精品日韩一| 一日本道久久久精品国产| 日韩电影免费看| 亚洲丝袜自拍清纯另类| 欧美日韩一区二区三区在线电影| 潘金莲一级淫片aaaaa免费看| 中文字幕日韩av综合精品| 黄色免费的网站| 黄色的电影在线-骚虎影院-骚虎视频| 中文字幕第99页| 久久久久久天堂| 在线视频国产日韩| 国产精品综合一区二区| 日韩欧美在线观看强乱免费| 欧美久久久久中文字幕| 久久精品人人爽人人爽| 一区二区三区www| 久久天堂国产精品| 国产精品久久久久9999吃药| 国内精品400部情侣激情| 在线一区二区三区做爰视频网站| 国产日韩换脸av一区在线观看| 国产a级片免费看| 日韩中文在线不卡| 99t1这里只有精品| 视频一区二区三区在线| 国产成人在线免费观看| 色先锋av男人资源先锋影院| 8050国产精品久久久久久| 国产99久久久欧美黑人| 国产精品欧美激情在线观看| 亚洲va天堂va欧美ⅴa在线| 国产一区私人高清影院| 欧美风情第一页| 欧美日韩加勒比精品一区| 男女羞羞网站| 久久久久99精品一区| 99国产精品久久久久久久成人热| 日韩精品极品视频在线观看免费| 6080yy午夜一二三区久久| 在线电影院国产精品| www欧美com| 狠狠色噜噜狠狠色综合久| 天堂8中文在线最新版在线| a美女胸又www黄视频久久| 九九热在线视频观看这里只有精品| 国产精品―色哟哟| 亚洲综合日韩在线| 欧美亚洲一区在线| 懂色av粉嫩av浪潮av| 日本午夜精品视频在线观看| 国模私拍国内精品国内av| 亚洲视频免费观看| 日韩av手机在线免费观看| 亚洲免费一级片| 91精品国产福利在线观看麻豆| 亚洲精品乱码久久久久久蜜桃动漫| 一级黄色大片视频| 精品久久人妻av中文字幕| 亚洲精品久久久久久久蜜桃| 亚洲爆乳无码一区二区三区| 午夜精品一区二区在线观看的| 亚洲国产欧美国产第一区| 极品盗摄国产盗摄合集| 一级少妇精品久久久久久久| 亚洲乱码国产乱码精品精可以看| 精品欧美色视频网站在线观看| 最近2019年好看中文字幕视频| 亚洲一区二区精品视频| 国产极品尤物在线| www.eeuss影院| 91视频免费在线| 99久久er| 欧美在线日韩| 国产视频在线一区| 天堂久久av| 99久久人妻无码精品系列| 久久久精品日韩欧美| 五月婷婷综合久久| 色多多视频在线播放| 91丝袜呻吟高潮美腿白嫩在线观看| 国产欧美日韩中文字幕| 国产美女永久无遮挡| 9797在线看片亚洲精品| 曰本三级日本三级日本三级| 性猛交xxxx乱大交孕妇印度| 欧洲金发美女大战黑人| 国产精品视频一区二区三区四| 99成人免费视频| 成人影视亚洲图片在线| 久久国产生活片100| 欧美亚洲日本精品| 欧美午夜精品一区二区三区| 国产精品视频一区二区久久| 少妇精品无码一区二区| 精品一区二区三区视频日产| 黄色国产精品视频| 国产无遮挡在线观看| 欧美在线三级| 中国女人特级毛片| 欧美吻胸吃奶大尺度电影| 狂野欧美激情性xxxx欧美| 国产精品无码av在线播放| 国产精品久久久久9999赢消| 久久久久久视频| 五月婷婷开心中文字幕| hd国产人妖ts另类视频| 久久久久免费看| 精品欧美一区二区精品少妇| 福利网址在线观看| 在线中文字幕网站| 国产成人综合欧美精品久久| 8x8x最新地址| av电影免费在线| 成人av在线播放| 一区二区三区国产好的精华液| 精品国产一区二区三区在线观看| 一区视频在线看| 久久婷婷丁香| 日韩激情av| 一区二区三区www污污污网站| 黄色一级大片在线免费看产| 亚洲iv一区二区三区| 中文字幕自拍vr一区二区三区| 精品久久av| 超碰91在线| 亚洲欧洲色图综合| www黄色在线观看视频| 国产女主播一区二区三区| 精品一区电影国产| 一区二区三区四区日韩| 成人小视频免费看| 亚洲免费在线视频观看| 欧美精产国品一二三区| 亚洲国产精品一区制服丝袜| 精品国产第一福利网站| 国产蜜臀97一区二区三区| 9久re热视频在线精品| 久久国产亚洲精品无码| 日本熟妇人妻中出| 国产欧美精品一二三| 青春草视频在线| 亚洲日本精品| 成人中文字幕视频| 一区二区在线免费| 日本成人在线网站| 午夜免费福利影院| 久久天堂国产精品| yellow中文字幕久久| www999久久| 精品国产不卡一区二区| 国产中文字幕在线视频| www.av蜜桃| 成人av色网站| 手机在线电影一区| 欧美国产免费| www.亚洲成人| 亚洲最大福利视频网| 日韩免费av一区| 亚洲女人****多毛耸耸8| 国产视频精品va久久久久久| 无码国产色欲xxxx视频| 久久影院午夜精品| 暖暖视频日本免费| 菠萝蜜视频在线观看一区| 欧美裸体bbwbbwbbw| 免费观看又污又黄在线观看国产| 久久国产精品国产精品| 国产麻豆视频精品| 不要播放器的av网站| 免费久久99精品国产| 国产又黄又嫩又滑又白| 国产极品国产极品| 九九视频免费在线观看| 日韩综合第一页| 欧美 变态 另类 人妖| 日韩av在线直播| 中文字幕在线观看免费高清| 国产成人精品1024| 亚洲综合网站在线观看| 欧美亚洲免费高清在线观看| 涩涩视频在线观看免费| 丝袜足控免费网站xx网站| 一级特黄大欧美久久久| 日韩欧美的一区| 动漫精品一区一码二码三码四码| 奇米影视第四色777| 久久草在线看| 精品一区二区三区中文字幕老牛| 久久久久毛片免费观看| 五月天视频一区| 岛国精品视频在线播放| 欧美激情在线一区| 免费欧美日韩国产三级电影| 中文字幕佐山爱一区二区免费| 9l亚洲国产成人精品一区二三| 日韩一区免费| caoporm超碰国产精品| 青青青免费在线视频| 午夜一区二区三区| 中文字幕在线免费观看视频| 欧美日韩国产综合新一区| avav免费在线观看| 制服丝袜中文字幕在线观看| 一道本视频在线观看| 中文字幕在线视频网站| av午夜在线观看| 国产亚洲精品精华液| www.成人免费视频| 蜜桃视频在线观看成人| 视频在线91| 青青操国产视频| 亚洲三区四区| 中文字幕免费不卡| 99久久久久免费精品国产| 青草青青国产| 国产一区在线播放| 亚洲激情视频在线观看| 欧美国产一区视频在线观看| 性史性dvd影片农村毛片| 国产三级视频在线播放线观看| 中文字幕一区二区5566日韩| 免费看日b视频| 欧美一级日韩一级| 日韩欧美aaaaaa| 紧缚奴在线一区二区三区| 大陆一级毛片| 中文字幕 国产精品| 欧美日韩黄色大片| 欧美日韩中文字幕综合视频| 亚洲一区二区三区四区在线播放| 日韩精品欧美一区二区三区| 亚洲欧美综合另类| 丰满熟女人妻一区二区三区| 丰满岳乱妇一区二区| 四虎免费在线观看视频| 亚洲高清视频的网址| www青青草原| 日本视频一区二区| 久久久久久亚洲综合影院红桃| 黑人精品一区| 欧美日韩视频专区在线播放| 久久国产欧美日韩精品| 国产人久久人人人人爽| 亚洲国产精品嫩草影院久久av| 日韩一区免费视频| 欧美劲爆第一页| fc2成人免费人成在线观看播放| 国产精品国产亚洲精品看不卡| 欧美精品免费看| 久久精品一区二区三区中文字幕| 亚洲wwwav| 四虎成人在线| 欧美wwwwwww| 极品少妇xxxx偷拍精品少妇| 在线观看涩涩| 色欲av永久无码精品无码蜜桃|