日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

360加速球效果实现

發(fā)布時(shí)間:2023/12/10 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 360加速球效果实现 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

效果演示:
懸浮小球在移動(dòng)時(shí)會(huì)換成一張圖片,當(dāng)松開時(shí),會(huì)自動(dòng)停靠在一側(cè),并且恢復(fù)原來的形式。
點(diǎn)擊懸浮小球,會(huì)從屏幕底部滑入一個(gè)菜單欄。
雙擊加速球,會(huì)有水不斷注入的動(dòng)畫效果,并且水面逐漸平靜下來。
單擊加速球,水面會(huì)震蕩,最后恢復(fù)平靜。

這個(gè)的實(shí)現(xiàn)是觀看了慕課網(wǎng)視頻后,在其基礎(chǔ)上做了一些適當(dāng)?shù)男薷?#xff0c;如:在android23以上,如何申請(qǐng)動(dòng)態(tài)權(quán)限。因?yàn)檫@個(gè)實(shí)現(xiàn)需要用到一個(gè)危險(xiǎn)權(quán)限,彈出窗口。有興趣的可以前往:http://www.imooc.com/learn/693。

整體思路:
可以看下項(xiàng)目結(jié)構(gòu)。在MainActivity開啟了一個(gè)服務(wù)MyFloatService,這個(gè)服務(wù)獲得了FloatViewManager管理類的實(shí)例,view包下有懸浮球的view以及加速球的view。而這個(gè)管理類則可控制這些view的顯示,隱藏,位置。開啟服務(wù)后,顯示了懸浮球,通過對(duì)懸浮球進(jìn)行Touch事件的監(jiān)聽,實(shí)現(xiàn)了拖動(dòng)改變圖片,自動(dòng)停靠在一側(cè),單擊出現(xiàn)菜單欄。在菜單欄的FloatMenuView類中,實(shí)現(xiàn)了對(duì)自身的Touch監(jiān)聽,雙擊出現(xiàn)水不斷注入效果,單擊水面震蕩。單擊加速球其他的地方則隱藏菜單欄。

源碼已經(jīng)開放在github上:https://github.com/My-Zzw/FloatView360Demo

在這篇文章中,簡(jiǎn)單提一下使用到的技巧,以及一些主要的思路,一些思想,一些需要注意的地方。

1.權(quán)限問題
當(dāng)點(diǎn)擊主界面的開啟懸浮窗按鈕時(shí),開啟MyFloatService服務(wù)。當(dāng)服務(wù)創(chuàng)建時(shí),進(jìn)行判斷,如果運(yùn)行在大于等于6.0系統(tǒng)上,則跳轉(zhuǎn)到應(yīng)用信任界面,允許該應(yīng)用所有權(quán)限。在這個(gè)項(xiàng)目中,需要用到 SYSTEM_ALERT_WINDOW 權(quán)限,記得要在manifest中注冊(cè)。

@Overridepublic void onCreate() {FloatViewManager manager = FloatViewManager.getInstance(this);manager.showFloatCircleView();//彈出一個(gè)窗口,需要權(quán)限。>=23,需要?jiǎng)討B(tài)申請(qǐng)。super.onCreate();}

2.在FloatViewManager中,是如何控制懸浮球以及菜單欄顯示和隱藏的。
首先已經(jīng)實(shí)例化了懸浮球View和菜單欄的View

//實(shí)例化懸浮球ViewfloatCircleView = new FloatCircleView(context);//實(shí)例化菜單ViewfloatMenuView = new FloatMenuView(context);

已經(jīng)實(shí)例化了View。那么View要顯示在界面,就需要一些布局參數(shù),比如view的寬和高,位置在哪里?所以需要一個(gè) WindowManager.LayoutParams 對(duì)象。這樣,要顯示的view已經(jīng)拿到,如何顯示也拿到,那么就可以添加到界面顯示了。顯示到界面上讓用戶看到,需要實(shí)例化一個(gè) WindowManager 的對(duì)象,通過其addView方法添加到窗口。例如顯示懸浮窗。

//顯示菜單欄private void showFloatMenuView() {WindowManager.LayoutParams params2 = new WindowManager.LayoutParams();params2.width = getScreenWidth();params2.height = getScreenHeight() - getStatusHeigt();//高度為全屏。params2.gravity = Gravity.BOTTOM | Gravity.LEFT;params2.x = 0;params2.y = 0;params2.type = WindowManager.LayoutParams.TYPE_PHONE;//布局參數(shù)的類型為手機(jī)類型。意味著 在所有頁(yè)面的上面。params2.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;//不和其他應(yīng)用搶焦點(diǎn)params2.format = PixelFormat.RGBA_8888;//設(shè)置透明度windowManager.addView(floatMenuView, params2);//通過manager添加視圖到窗口。第一個(gè)參數(shù)為要添加的view,第二個(gè)為view的布局參數(shù)}

3.實(shí)現(xiàn)懸浮窗在點(diǎn)擊移動(dòng)時(shí)變成一張火箭的圖片,松開時(shí)自動(dòng)附著在其中一側(cè)。
首先對(duì)懸浮窗注冊(cè)一個(gè)事件監(jiān)聽器。類型為觸摸事件。

//注冊(cè)觸摸事件監(jiān)聽器 floatCircleView.setOnTouchListener(circleViewOnTouchListener);

接著實(shí)現(xiàn)這個(gè)事件監(jiān)聽器的觸發(fā)事件。當(dāng)用戶按下,移動(dòng),抬起時(shí)。
需要說明的是,當(dāng)監(jiān)聽到用戶在移動(dòng)這個(gè)懸浮球時(shí),調(diào)用了懸浮球?qū)ο蟮膕etDrawState方法通知到這個(gè)懸浮球在移動(dòng)中,那么懸浮球?qū)ο缶蜁?huì)調(diào)用invalidate進(jìn)行重繪。在onDraw方法去drawBitmap。
當(dāng)用戶松開時(shí),判斷最后松開的懸浮窗x坐標(biāo)如果大于或者小于屏幕的一半,修改懸浮窗的params.x布局參數(shù)的x坐標(biāo)。最后調(diào)用updateViewLayout方法,更新懸浮窗。

//監(jiān)聽的內(nèi)部類private View.OnTouchListener circleViewOnTouchListener = new View.OnTouchListener() {@Overridepublic boolean onTouch(View view, MotionEvent motionEvent) {switch (motionEvent.getAction()) {case MotionEvent.ACTION_DOWN://當(dāng)按下的時(shí)候,獲取相對(duì)屏幕密度的xy坐標(biāo)startX = motionEvent.getRawX();startY = motionEvent.getRawY();startX0 = motionEvent.getRawX();startY0 = motionEvent.getRawY();break;case MotionEvent.ACTION_MOVE://移動(dòng)的時(shí)候,懸浮球跟著移動(dòng)//獲取移動(dòng)中的坐標(biāo)float x = motionEvent.getRawX();float y = motionEvent.getRawY();//偏移量float dx = x - startX;float dy = y - startY;//獲取布局參數(shù)對(duì)象。重新設(shè)置懸浮球的xy位置params.x += dx;params.y += dy;//移動(dòng)的過程中,改變樣式。通知在移動(dòng)。floatCircleView.setDrawState(true);//刷新界面。指定用新的 布局參數(shù)params 刷新 floatCircleView在界面的顯示windowManager.updateViewLayout(floatCircleView,params);//起始位置變化為移動(dòng)后的位置startX = x;startY = y;break;case MotionEvent.ACTION_UP://當(dāng)抬起時(shí),懸浮球附著在兩旁float endX = motionEvent.getRawX();//獲取最后的X坐標(biāo)//進(jìn)行判斷.當(dāng)在屏幕中間線右邊或者左邊的時(shí),往兩邊靠攏if (endX > getScreenWidth()/2){params.x = getScreenWidth() - floatCircleView.width;} else {params.x = 0;}//當(dāng)抬起時(shí),通知移動(dòng)狀態(tài)停止。并且懸浮球會(huì)重新繪制自身樣式floatCircleView.setDrawState(false);//刷新界面。刷新的是懸浮球floatCircleView在界面的布局參數(shù)。而懸浮球樣式的改變?cè)谄鋬?nèi)部。windowManager.updateViewLayout(floatCircleView,params);//解決可能有的 觸摸事件和點(diǎn)擊事件 的沖突.//如果移動(dòng)后的X坐標(biāo) 大于 起始的X坐標(biāo)6個(gè)單位距離,則認(rèn)為是觸摸事件,要終止點(diǎn)擊事件的執(zhí)行if (Math.abs(endX - startX0) > 6){//取絕對(duì)值return true;//返回true的時(shí)候,則不會(huì)繼續(xù)往下執(zhí)行到 onClick 事件。} else {return false;}default:break;}return false;}};

4.獲取狀態(tài)欄高度。
這里是采用了反射去獲取。這樣的好處是能獲取到程序運(yùn)行到具體的設(shè)備或者模擬器的狀態(tài)欄高度。

//獲取狀態(tài)欄的高度public int getStatusHeigt (){//通過反射的方法獲取狀態(tài)欄的高度try {Class<?> c = Class.forName("com.android.internal.R$dimen");//反射.class獲取類Object o = c.newInstance();//實(shí)例化這個(gè)類,得到一個(gè)具體的對(duì)象Field field = c.getField("status_bar_height");//獲取這個(gè)類的field(域)。這個(gè)域的對(duì)象類型是 這個(gè)類里面的一個(gè)屬性int x = (Integer)field.get(o);//再?gòu)木唧w對(duì)象的一個(gè)屬性的值return context.getResources().getDimensionPixelSize(x);//返回。值轉(zhuǎn)換成px} catch (Exception e) {e.printStackTrace();return 0;}}

5.隱藏懸浮球或者菜單欄。
例如隱藏菜單欄,拿到窗口管理對(duì)象remove即可。

//隱藏 菜單欄public void hideFloatMenuView() {windowManager.removeView(floatMenuView);}

6.懸浮球 FloatCircleView 的實(shí)現(xiàn)。

通過實(shí)際效果可以知道,其實(shí)現(xiàn)原理很簡(jiǎn)單。首先是如何繪制。
繪制:繪制有兩種狀態(tài)。一是不移動(dòng)狀態(tài)下的繪制,使用兩只畫筆,一個(gè)畫筆繪制圓形,一個(gè)畫筆繪制文本。另一個(gè)是移動(dòng)狀態(tài)下的繪制。移動(dòng)狀態(tài)下是將一個(gè)在drawable下的資源圖片進(jìn)行繪制。

// 繪制方法@Overrideprotected void onDraw(Canvas canvas) {//如果移動(dòng)中,則顯示圖片,否則正常顯示if (draw){canvas.drawBitmap(bitmap,0,0,null);} else {//繪制圓形canvas.drawCircle(width/2,height/2,width/2,circlePaint);//繪制文本float textWidth = textPaint.measureText(text);//用畫筆去測(cè)量文本的寬度float x = width/2 - textWidth/2;//確定文本的x坐標(biāo)Paint.FontMetrics metrics = textPaint.getFontMetrics();//獲得畫筆繪制下的文本規(guī)格 // 確定文本的y坐標(biāo).descent ascent,基準(zhǔn)線下的高度,基準(zhǔn)線下的高度。為什么不是除2,而是除4?為什么是+而不是-? // + 是因?yàn)槲谋镜某跏嘉恢迷趫A的上方。除4 則可能是因?yàn)橛心J(rèn)的行距。以后凡是需要精確的數(shù)值,則可以將其都顯示出來,再一個(gè)個(gè)去測(cè)試值。float y = height/2 + (metrics.descent - metrics.ascent)/4;canvas.drawText(text,x,y ,textPaint);}}

如何通知到懸浮球什么時(shí)候在移動(dòng)?通過調(diào)用下面這個(gè)方法。這個(gè)方法會(huì)改變狀態(tài)的標(biāo)識(shí),并且調(diào)用invalidate去重新繪制。

// 在移動(dòng)中,則進(jìn)行狀態(tài)的改變public void setDrawState(boolean b) {draw = b;invalidate();//每當(dāng)狀態(tài)改變的時(shí)候,需要重新執(zhí)行draw方法,進(jìn)行重新繪制}

要保證移動(dòng)時(shí)候,改變的圖片的大小也要和懸浮球大小一致,則需要

// 初始化移動(dòng)需要的bitmap。并且縮放到合適大小Bitmap src = BitmapFactory.decodeResource(getResources(), R.drawable.hj);bitmap = Bitmap.createScaledBitmap(src,width,height,true);

7.進(jìn)度球 ProcessView 的實(shí)現(xiàn)。

進(jìn)度球放置在了菜單欄里面。通過實(shí)際效果知道,需要三支畫筆。繪制圓形,繪制水,繪制文本。

7.1 雙擊進(jìn)度球動(dòng)畫效果的實(shí)現(xiàn):水不斷被注入,并且水面越來越平緩

圖解是這樣的:

一支畫筆繪制了圓形,另外一支畫筆在圓形上繪制了一個(gè)“矩形”,不過這個(gè)矩形有點(diǎn)特殊的是上面的邊是個(gè)曲線,其他三邊都是直線。
在繪制這個(gè)特殊的矩形,是用畫筆通過Path路徑去繪制,先用lineTo方法依次繪制三條直線的邊,在繪制到這個(gè)曲線的時(shí)候再用rQuadTo方法繪制曲線,也叫貝塞爾曲線。
那么動(dòng)畫效果:水不斷被注入,并且水面越來越平緩。是如何實(shí)現(xiàn)的呢?
水不斷注入,其實(shí)就是這個(gè)特殊的矩形不斷的重新繪制,繪制。并且每次繪制時(shí),矩形的高都是不斷增加的,在時(shí)間很短的情況下,感覺水面在不斷的升高。
水面越來越平緩,則是每次在重新繪制的時(shí)候,貝塞爾曲線的振幅不斷的在減小。
需要了解貝塞爾曲線可能才能明白在說什么,所以有不明白的可以去百度下Android貝塞爾曲線。

繪制的矩形是在覆蓋在圓形上,那么矩形超出圓形的部分如何隱藏?
我們可以在初始化畫筆時(shí),設(shè)置繪制矩形的畫筆的過度模式,也就是圖像混合模式。當(dāng)矩形畫筆繪制的圖像和其他圖像混合時(shí),設(shè)置其模式為重疊。也就是說,只顯示重疊的部分。

//下面這句代碼則是 設(shè)置了progressPaint畫筆繪制的圖像,只顯示重疊部分progressPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

7.2 單擊進(jìn)度球動(dòng)畫效果的實(shí)現(xiàn):水面不斷震蕩,最后平緩。

圖解:

其實(shí)還是不斷的去重新繪制矩形,不過矩形的高度不需要變化,但是貝塞爾曲線需要變化,每繪制一次貝塞爾曲線,那么在下一次則繪制相反的貝塞爾曲線,再下一次則恢復(fù)原來的貝塞爾曲線即可。
并且在每次重新繪制的時(shí)候,同樣需要將振幅減小。

如何每次去計(jì)算振幅的減小 以及 如何判斷哪次需要將貝塞爾曲線取反。讀者可以查看代碼結(jié)合注釋。這里不詳細(xì)介紹。

//在這進(jìn)行繪制.@Overrideprotected void onDraw(Canvas canvas) {//畫圓bitmapCanvas.drawCircle(width/2,height/2,width/2,circlePaint);//繪制水波紋進(jìn)度。基本思想是繪制一個(gè)矩形。不過矩形除了上面的邊使用貝塞爾曲線外,其他都是直線。path.reset();//重置path的所有屬性//起始點(diǎn)定義。重新規(guī)定路徑的起始坐標(biāo),默認(rèn)為(0,0)。moveTo()移動(dòng)畫筆。//這里將起始點(diǎn)的x移動(dòng)到右邊,y則是變化的。也就是矩形的右上角的點(diǎn)float y = (1 - (float)current_progress/max_progress) * height;path.moveTo(width,y);//第二個(gè)點(diǎn)定義。右下角,繪制直線。也就是右面的邊path.lineTo(width,height);//第三個(gè)點(diǎn)定義。左下角,繪制直線。也就是下面的邊path.lineTo(0,height);//第四個(gè)點(diǎn)定義。左上角,繪制直線。也就是左面的邊path.lineTo(0,y);//繪制上面的邊。也就是貝塞爾曲線。//根據(jù)進(jìn)度球?qū)挾?#xff0c;設(shè)定需要的貝塞爾曲線的周期。如:250的寬度,那么7個(gè)周期為40的即可。//繪制貝賽爾曲線需要起始點(diǎn),控制點(diǎn)和結(jié)束點(diǎn)。rQuadTo方法只需要兩個(gè)參數(shù),起始點(diǎn)默認(rèn)為 未閉合路徑的最后一個(gè)點(diǎn)。//一個(gè)循環(huán)意味著一個(gè)周期的貝塞爾曲線if (!isSingleTab){//雙擊//雙擊效果:貝塞爾曲線逐漸變得平緩,最后成為直線的效果。//其實(shí)就是控制了貝賽爾曲線的振幅。也就是參數(shù)的控制點(diǎn)的y坐標(biāo)。使得y坐標(biāo)逐漸變成0。也就是rQuadTo中的第二個(gè)參數(shù)//在這里設(shè)定了振幅為10的話,也就是控制點(diǎn)的y坐標(biāo),隨著當(dāng)前進(jìn)度不斷增加到接近目標(biāo)進(jìn)度,那么百分比就會(huì)不斷增加//這時(shí)用1減去他們的百分比,就會(huì)不斷減小。用這結(jié)果去乘振幅。就能使得振幅不斷減小.float d = (1 - ((float)current_progress / progress)) * 10;for (int i = 0; i < 7 ; i++){path.rQuadTo(10,d,20,0);path.rQuadTo(10,-d,20,0);}} else {//單擊//單擊效果:水不斷震蕩,最后便于平緩。//其實(shí)就是貝塞爾曲線每次周期不斷取反,也就是高的變低,低的變高.//這里是水波紋波動(dòng)50次,也就是50個(gè)周期.為什么要模2?//因?yàn)閏ount是每次減1。如果模2的結(jié)果是0,那么為一個(gè)周期。再減1,模2的結(jié)果不是0.則為另外一個(gè)周期,就可以去實(shí)現(xiàn)相反的效果。//要使得貝賽爾曲線逐漸變得平緩,和上面寫的一樣道理。使得振幅不斷減小.注意count是每次-1//第一解決貝塞爾曲線不斷取反。第二解決貝塞爾曲線振幅也就是控制點(diǎn)的y坐標(biāo)不斷減小。//以后凡是遇到類似這種,需要多個(gè)來配合的,那么先解決一個(gè),再解決下一個(gè)。float d = (float)count/50 * 10;if (count%2 == 0){for (int i = 0; i < 7 ; i++){path.rQuadTo(20,d,40,0);path.rQuadTo(20,-d,40,0);}} else {for (int i = 0; i < 7 ; i++){path.rQuadTo(20,-d,40,0);path.rQuadTo(20,d,40,0);}}}path.close();//路徑閉合bitmapCanvas.drawPath(path,progressPaint);//繪制文本String text = (int)(((float)current_progress/max_progress) * 100) + "%";//獲取文本寬度。便于規(guī)定繪制文本時(shí)候的x坐標(biāo)float textWidth = textPaint.measureText(text);//獲取文本規(guī)格。便于規(guī)定繪制文本時(shí)候的y坐標(biāo);Paint.FontMetrics metrics = textPaint.getFontMetrics();float baseLine = height/2 - (metrics.ascent + metrics.descent)/2;//開始繪制文本bitmapCanvas.drawText(text, width/2-textWidth/2,baseLine,textPaint);//利用自定義bitmap的畫布繪制完畢后。再通過顯示的畫布,繪制這自定義的bitmapcanvas.drawBitmap(bitmap,0,0,null);}

7.3 如何不斷去重新繪制?
可以采用Timer定時(shí)器去不斷重繪。但是這里使用的是 Handle.postDelayed 方法。這里面有個(gè)小技巧。也就是postDelayed 方法去執(zhí)行runable的代碼時(shí),如果條件沒達(dá)到,則再次調(diào)用自身,如果條件達(dá)到則remove。比如雙擊動(dòng)畫:
被雙擊的時(shí),先執(zhí)行一次

//開啟雙擊動(dòng)畫private void startDoubleTapAnimation() {//利用handler執(zhí)行一個(gè)延遲50毫秒的線程。//每次線程首先將當(dāng)前進(jìn)度++,并且判斷。//如果當(dāng)前進(jìn)度沒有達(dá)到指定進(jìn)度,先重新繪制,然后再延遲50毫秒后執(zhí)行同樣的線程//如果達(dá)到了,則讓當(dāng)前進(jìn)度為0,并且關(guān)閉。//本質(zhì)的效果像開了個(gè)定時(shí)器,每隔50毫秒去執(zhí)行,當(dāng)達(dá)到一定條件停止執(zhí)行handler.postDelayed(new DoubleTabRunable(),50);}

接著在執(zhí)行的方法去做判斷,也就是DoubleTabRunable

//雙擊時(shí),需要執(zhí)行的線程。刷新數(shù)據(jù),重繪界面。class DoubleTabRunable implements Runnable {@Overridepublic void run() {current_progress++;if (current_progress <= progress){invalidate();//重新繪制,調(diào)用onDraw方法。因?yàn)閏urrent_progress是變化的,所以重新繪制會(huì)使得進(jìn)度條有變化。handler.postDelayed(this,50);//再次調(diào)用自己} else {current_progress = 0;handler.removeCallbacks(this);}}}

7.4 進(jìn)度球的繪制,先繪制在了一個(gè)自定義的bitmap中,繪制完畢后,再講這個(gè)bitmap繪制在界面中顯示。

//自己畫圖。創(chuàng)建一個(gè)空的bitmap,并且在這bitmap上傳入一個(gè)畫布才能進(jìn)行繪制。bitmap = Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_8888);bitmapCanvas = new Canvas(bitmap);

8.菜單欄中放置進(jìn)度球。
FloatMenuView 繼承了LinearLayout。所以這個(gè)類本質(zhì)還是一個(gè)View。既然是View的話就會(huì)有樣式。
之前的懸浮球FloatCircleView 和 進(jìn)度球 ProcessView 都是通過畫筆在OnDraw中去繪制樣式。
在FloatMenuView ,則是事先將一個(gè)寫好的xml格式的布局文件寫好,通過View.inflate方法找到這個(gè)xml格式的布局文件后,再通過addView方法添加這個(gè)布局文件到FloatMenuView ,也就是將這個(gè)找到的布局文件和FloatMenuView 綁定。這樣在其他地方實(shí)例化FloatMenuView 后,顯示在窗口的話,樣子就是xml布局文件的樣式。

View root = View.inflate(getContext(), R.layout.float_menu_view,null);//找到xml文件樣式 ... ...addView(root);//將xml樣式文件添加到這個(gè)View。也就是綁定。

那么進(jìn)度球是如何顯示到了菜單欄中?很簡(jiǎn)單,在菜單欄的xml布局文件中,也就是剛剛說的FloatMenuView 綁定的這個(gè)xml布局文件。在里面將其實(shí)例化

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#33000000"><LinearLayout android:id="@+id/linearLayout"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#F02F3942"android:layout_alignParentBottom="true"android:clickable="true"><!--左上角文本提示--><LinearLayout android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><ImageView android:layout_width="50dp"android:layout_height="50dp"android:layout_marginLeft="10dp"android:layout_gravity="center_vertical"android:src="@drawable/four"/><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="22sp"android:textColor="#1296db"android:text="四月加速球"android:layout_marginLeft="10dp"android:layout_gravity="center_vertical"/></LinearLayout><!--實(shí)例化自定義的進(jìn)度球--><view.ProcessView android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:layout_margin="10dp"/></LinearLayout></RelativeLayout>

8.1或者說是bug,或者說是技巧吧,在這里用到了。具體原因不是很清楚,以后有待查證。
當(dāng)點(diǎn)擊進(jìn)度球(包括灰色區(qū)域)以外的地方,需要隱藏菜單欄(進(jìn)度球是菜單欄的子控件)。但是點(diǎn)擊事件監(jiān)聽的是整個(gè)父控件,也就是菜單欄。而點(diǎn)擊進(jìn)度球是有其自身動(dòng)畫效果需要實(shí)現(xiàn)的。
也就是子控件不需要因?yàn)楦缚丶o監(jiān)聽到。
這樣解決:給進(jìn)度球在xml文件或者通過代碼的方式設(shè)置一個(gè)屬性:clickable=”true”。
當(dāng)給整個(gè)父控件設(shè)置了點(diǎn)擊或者觸摸的監(jiān)聽,如果不需要其子控件也給監(jiān)聽到(或者子控件的監(jiān)聽有額外的事件處理)時(shí),給子控件設(shè)置屬性:clickable=”true”。

最后,感謝你耐心的看完。水平有限,不足或者有誤之處,請(qǐng)諒解!!!

源碼已經(jīng)開放在github上:https://github.com/My-Zzw/FloatView360Demo

總結(jié)

以上是生活随笔為你收集整理的360加速球效果实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产第一草草影院 | 免费在线中文字幕 | 精久久久久 | 亚洲成a人在线观看 | 日韩国产欧美一区 | 亚洲综合在线成人 | 少妇日韩 | 欧美做受高潮中文字幕 | 一级特黄肉体裸片 | 精品国产乱码久久久久夜深人妻 | 色偷偷免费费视频在线 | 久草资源网站 | 精品91在线 | 亚洲 欧美 另类 综合 偷拍 | 福利精品视频 | 久久婷婷一区二区 | 性欧美熟妇videofreesex | 麻豆视频在线观看免费 | 天堂一区二区三区四区 | 99久久婷婷国产一区二区三区 | 欧美激情久久久久久久 | 成人欧美精品一区二区 | 国产99久久久国产精品免费看 | 成人www| 欧美极品少妇xxxxⅹ免费视频 | 内射中出日韩无国产剧情 | 国产中文视频 | 欧美日韩国产一区二区 | 婷婷激情四射 | 国产精品aⅴ| 在线欧美国产 | 亚洲制服另类 | 99在线视频观看 | 黄色生活毛片 | 狠狠综合久久 | 日本精品免费在线观看 | av午夜天堂 | 在线观看免费高清在线观看 | 天天爱天天做天天爽 | 不卡二区 | 波多野结衣在线观看一区二区三区 | 日韩亚洲欧美在线 | 五月婷久久 | 亚洲羞羞| 成人精品动漫 | 永久免费的av网站 | 国产无遮挡免费观看视频网站 | 日韩美女一级片 | 国产精品第100页 | 日本乱偷中文字幕 | 欧美日韩亚洲一区二区 | 一区二区三区不卡视频在线观看 | 草色噜噜噜av在线观看香蕉 | 日韩美女视频在线观看 | 男人的天堂av网 | 无码国产精品久久一区免费 | 亚洲久久一区 | av全黄| 国产成人8x视频一区二区 | 一区二区三区影院 | 男生和女生差差的视频 | 亚洲第1页 | 99av国产精品欲麻豆 | 亚洲av无码一区二区乱子仑 | 国产日韩av一区二区 | 欧美在线v | 日韩精品一区二区在线观看 | aise爱色av | 久久久少妇 | 国产www精品 | 国产xxxxx在线观看 | 欧美成人精品激情在线观看 | av片免费在线| 开元在线观看视频国语 | 成人精品福利视频 | 国产精品v欧美精品v日韩 | 在线免费观看小视频 | 国产综合婷婷 | 国产一区二区亚洲 | 久久深夜视频 | 精品在线一区二区三区 | 日韩精品人妻无码一本 | 欧美操操| 国产激情在线播放 | 国产九九精品 | 欧美成人小视频 | 毛片国产精品 | 久久午夜精品视频 | 国产精品无码久久久久一区二区 | 欧美成网站 | 大地资源中文在线观看免费版 | 制服.丝袜.亚洲.另类.中文 | 午夜在线一区二区三区 | 亚洲三级欧美 | 午夜精品美女久久久久av福利 | 精品国产一区二区三区性色 | 国产情侣久久 | 国产精品久久免费视频 | 国产色播av在线 |