电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

Android 實現仿QQ拖拽氣泡效果的示例

瀏覽:132日期:2022-06-06 08:00:29
效果圖:

Android 實現仿QQ拖拽氣泡效果的示例

一、實現思路

在列表中默認使用自定義的TextView控件來展示消息氣泡,在自定義的TextView控件中重寫onTouchEvent方法,然后在DOWN、MOVE、UP事件中分別處理拖拽效果。

整個拖拽效果我們可以拆分成以下幾步來實現:1.默認狀態2.兩氣泡相連狀態3.兩氣泡分離狀態4.氣泡消失狀態

二、功能實現

默認狀態:用來做一個狀態的標識,無需特別處理。

兩氣泡相連狀態:繪制一個固定圓和一個移動圓,使用兩條貝塞爾曲線來實現兩氣泡連接的曲線,兩條貝塞爾曲線共用同一個控制點,然后根據MOVE事件中的坐標不斷重繪移動圓。

實現兩氣泡連接的效果,需要先計算出一些點的坐標,這也是整個拖拽氣泡效果的核心部分,具體如下圖:

Android 實現仿QQ拖拽氣泡效果的示例

如圖,A點到B點是一條二階貝塞爾曲線,C點到D點也是一條二階貝塞爾曲線,它們共用同一個控制點,所以我們要計算出A點、B點、C點、D點以及控制點的坐標。

首先來計算控制點的坐標,控制點的坐標和容易計算出,也就是固定圓的x坐標加上移動圓的x坐標,再除以2,固定圓的y坐標同理得出。

int controlX = (int) ((mBubStillCenter.x + mBubMoveCenter.x) / 2);int controlY = (int) ((mBubStillCenter.y + mBubMoveCenter.y) / 2);

根據圖中所標注的信息得知,∠a=∠d,∠b=∠c,∠a=∠θ,由此可知,我們求出∠θ所在的直角三角形的sin和cos值,就可以計算出A點、B點、C點、D點的坐標。

sin值可以通過移動圓的y坐標減去固定圓的y坐標,再除以兩圓心的距離,也就是O1到O2的距離。

cos值可以通過移動圓的x坐標減去固定圓的x坐標,再除以兩圓心的距離。

float sin = (mBubMoveCenter.y - mBubStillCenter.y) / mDist;float cos = (mBubMoveCenter.x - mBubStillCenter.x) / mDist;

有了sin和cos值,對應的A點、B點、C點、D點的坐標就好計算了

// A點float bubbleStillStartX = mBubStillCenter.x + mBubbleStillRadius * sin;float bubbleStillStartY = mBubStillCenter.y - mBubbleStillRadius * cos;// B點float bubbleMoveStartX = mBubMoveCenter.x + mBubbleMoveRadius * sin;float bubbleMoveStartY = mBubMoveCenter.y - mBubbleMoveRadius * cos;// C點float bubbleMoveEndX = mBubMoveCenter.x - mBubbleMoveRadius * sin;float bubbleMoveEndY = mBubMoveCenter.y + mBubbleMoveRadius * cos;// D點float bubbleStillEndX = mBubStillCenter.x - mBubbleStillRadius * sin;float bubbleStillEndY = mBubStillCenter.y + mBubbleStillRadius * cos;

接下來就是把這些貝塞爾曲線和直線連起來,就實現了兩氣泡相連的效果。

兩氣泡分離狀態:當拖拽的移動圓超出固定圓一定范圍時,就進入了兩氣泡分離狀態,此時我們只需要繪制移動圓即可。當拖拽的移動圓回到固定圓一定范圍時,此時會進入兩氣泡相連狀態,并且需要實現一個氣泡還原的效果。(這里會有個難點,就是移動圓我們可以在屏幕上任意拖動而不被遮擋,這里放到后面來實現。)

public void move(float curX, float curY) { mBubMoveCenter.x = curX; mBubMoveCenter.y = curY; mDist = (float) Math.hypot(curX - mBubStillCenter.x, curY - mBubStillCenter.y); if(mBubbleState == BUBBLE_STATE_CONNECT){ if(mDist < mMaxDist - MOVE_OFFSET){ mBubbleStillRadius = mBubbleRadius - mDist / 10; }else { mBubbleState = BUBBLE_STATE_APART; } } invalidate();}

mDist就是兩圓心的距離。

/** * 氣泡還原動畫 */private void startBubbleRestAnim() { mBubbleStillRadius = mBubbleRadius; ValueAnimator animator = ValueAnimator.ofObject(new PointEvaluator(), new PointF(mBubMoveCenter.x, mBubMoveCenter.y), new PointF(mBubStillCenter.x, mBubStillCenter.y)); animator.setDuration(200); animator.setInterpolator(input -> { float factor = 0.4f; return (float) (Math.pow(2, -10 * factor) * Math.sin((input - factor / 4) * (2 * Math.PI) / factor) + 1); }); animator.addUpdateListener(animation -> { mBubMoveCenter = (PointF) animation.getAnimatedValue(); invalidate(); }); animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mBubbleState = BUBBLE_STATE_DEFAULT; removeDragView(); if(mDragListener != null){mDragListener.onRestore(); } } }); animator.start();}

分享一個可視化插值器的網站,其中內置了一些插值器公式,還可以查看動畫演示效果。http://inloop.github.io/interpolator/

氣泡消失狀態:當拖拽的移動圓超出一定范圍時,并且松開了手指后,此時進入氣泡消失狀態,此時我們需要實現一個爆炸的動畫。

爆炸的動畫通過繪制一組圖片來實現

if(mBubbleState == BUBBLE_STATE_DISMISS){ if(mIsBurstAnimStart){ mBurstRect.set((int)(mBubMoveCenter.x - mBubbleMoveRadius), (int)(mBubMoveCenter.y - mBubbleMoveRadius),(int)(mBubMoveCenter.x + mBubbleMoveRadius), (int)(mBubMoveCenter.y + mBubbleMoveRadius)); canvas.drawBitmap(mBurstBitmapArray[mCurDrawableIndex], null, mBurstRect, mBurstPaint); }}

mCurDrawableIndex是圖片的索引,是通過屬性動畫來改變

/** * 氣泡爆炸動畫 */private void startBubbleBurstAnim() { ValueAnimator animator = ValueAnimator.ofInt(0, mBurstDrawablesArray.length); animator.setInterpolator(new LinearInterpolator()); animator.setDuration(1000); animator.addUpdateListener(animation -> { mCurDrawableIndex = (int) animator.getAnimatedValue(); invalidate(); }); animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mIsBurstAnimStart = false; if(mDragListener != null){mDragListener.onDismiss(); } } }); animator.start();}三、全屏拖拽效果實現

首先在DOWN事件中獲取當前觸摸位置在全屏所在位置,然后將當前view緩存為bitmap,并把此bitmap添加到rootview中,拖動的時候直接繪制此bitmap。

//獲得當前View在屏幕上的位置int[] cLocation = new int[2];getLocationOnScreen(cLocation);if(rootView instanceof ViewGroup){ mDragDotView = new DragDotView(getContext()); //設置固定圓和移動圓的圓心坐標 mDragDotView.setDragPoint(cLocation[0] + mWidth / 2, cLocation[1] + mHeight / 2, mRawX, mRawY); Bitmap bitmap = getBitmapFromView(this); if(bitmap != null){ mDragDotView.setCacheBitmap(bitmap); ((ViewGroup) rootView).addView(mDragDotView); setVisibility(INVISIBLE); }}/** * 將當前view緩存為bitmap,拖動的時候直接繪制此bitmap * @param view * @return */public Bitmap getBitmapFromView(View view){ Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); view.draw(canvas); return bitmap;}

至此,整個消息氣泡拖拽效果的核心部分就實現了

源碼地址:

https://github.com/loren325/CustomerView

以上就是Android 實現仿QQ拖拽氣泡效果的示例的詳細內容,更多關于Android 實現仿QQ拖拽氣泡效果的資料請關注好吧啦網其它相關文章!

標簽: qq
相關文章:
主站蜘蛛池模板: 驾驶人在线_专业学车门户网站| 氧氮氢联合测定仪-联测仪-氧氮氢元素分析仪-江苏品彦光电 | 游泳池设计|设备|配件|药品|吸污机-东莞市太平洋康体设施有限公司 | 铝单板_铝窗花_铝单板厂家_氟碳包柱铝单板批发价格-佛山科阳金属 | 山东聚盛新型材料有限公司-纳米防腐隔热彩铝板和纳米防腐隔热板以及钛锡板、PVDF氟膜板供应商 | 东莞市踏板石餐饮管理有限公司_正宗桂林米粉_正宗桂林米粉加盟_桂林米粉加盟费-东莞市棒子桂林米粉 | 专业生物有机肥造粒机,粉状有机肥生产线,槽式翻堆机厂家-郑州华之强重工科技有限公司 | 湖南自考_湖南自学考试网| 昆明挖掘机修理厂_挖掘机翻新再制造-昆明聚力工程机械维修有限公司 | 防火门|抗爆门|超大门|医疗门|隔声门-上海加汇门业生产厂家 | 扬子叉车厂家_升降平台_电动搬运车|堆高车-扬子仓储叉车官网 | 苏州防水公司_厂房屋面外墙防水_地下室卫生间防水堵漏-苏州伊诺尔防水工程有限公司 | 粉丝机械,粉丝烘干机,粉丝生产线-招远市远东粉丝机械有限公司 | 臭氧发生器_臭氧消毒机 - 【同林品牌 实力厂家】 | 天津次氯酸钠酸钙溶液-天津氢氧化钠厂家-天津市辅仁化工有限公司 | 楼承板设备-楼承板成型机-免浇筑楼承板机器厂家-捡来 | TTCMS自助建站_网站建设_自助建站_免费网站_免费建站_天天向上旗下品牌 | 刚性-柔性防水套管-橡胶伸缩接头-波纹管补偿器-启腾供水材料有限公司 | 换网器_自动换网器_液压换网器--郑州海科熔体泵有限公司 | 解放卡车|出口|济南重汽|报价大全|山东三维商贸有限公司 | 123悬赏网_发布悬赏任务_广告任务平台| 无锡网站建设_企业网站定制-网站制作公司-阿凡达网络 | 丙烷/液氧/液氮气化器,丙烷/液氧/液氮汽化器-无锡舍勒能源科技有限公司 | 药品冷藏箱厂家_低温冰箱_洁净工作台-济南欧莱博电子商务有限公司官网 | 影视模板素材_原创专业影视实拍视频素材-8k像素素材网 | 熔体泵|换网器|熔体齿轮泵|熔体计量泵厂家-郑州巴特熔体泵有限公司 | 安徽净化板_合肥岩棉板厂家_玻镁板厂家_安徽科艺美洁净科技有限公司 | SPC工作站-连杆综合检具-表盘气动量仪-内孔缺陷检测仪-杭州朗多检测仪器有限公司 | 浙江红酒库-冰雕库-气调库-茶叶库安装-医药疫苗冷库-食品物流恒温恒湿车间-杭州领顺实业有限公司 | 北京律师事务所_房屋拆迁律师_24小时免费法律咨询_云合专业律师网 | 不锈钢搅拌罐_高速搅拌罐厂家-无锡市凡格德化工装备科技有限公司 | 企典软件一站式企业管理平台,可私有、本地化部署!在线CRM客户关系管理系统|移动办公OA管理系统|HR人事管理系统|人力 | 管理会计网-PCMA初级管理会计,中级管理会计考试网站 | 骨密度检测仪_骨密度分析仪_骨密度仪_动脉硬化检测仪专业生产厂家【品源医疗】 | 电渗析,废酸回收,双极膜-山东天维膜技术有限公司 | 空压机网_《压缩机》杂志 | 民用音响-拉杆音响-家用音响-ktv专用音响-万昌科技 | 电竞学校_电子竞技培训学校学院-梦竞未来电竞学校官网 | 台湾阳明固态继电器-奥托尼克斯光电传感器-接近开关-温控器-光纤传感器-编码器一级代理商江苏用之宜电气 | 硬齿面减速机[型号全],ZQ减速机-淄博久增机械| 湖南长沙商标注册专利申请,长沙公司注册代理记账首选美创! |