當前位置:首頁 » 安卓系統 » androidfling

androidfling

發布時間: 2023-05-25 14:49:57

『壹』 NestedScrollView+RecyclerView 滑動卡頓簡單解決方案

以下xml是當前布畝伏局:
<code>
<android.support.v4.widget.NestedScrollView
xmlns:android=" http://schemas.android.com/apk/res/android "
android:layout_width="match_parent"
android:layout_height="match_parent"

<LinearLayout
android:id="@+id/linerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"


<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</code>

NestedScrollView中包含了LinearLayout,LinearLayout包含了一系列的組件,其中迅襪攜包括RecyclerView,RecyclerView和NestedScrollView都有滾動事件,這種情況下進行滑動操作,fling的操作體驗很差,幾乎就是手指離開的時好中候,滑動停止.

以下xml是改動後的布局:
<android.support.v7.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" android:nestedScrollingEnabled="false" />
android:nestedScrollingEnabled="false"
官方文檔:
Enable or disable nested scrolling for this view.
If this property is set to true the view will be permitted to initiate nested scrolling operations with a compatible parent view in the current hierarchy. If this view does not implement nested scrolling this will have no effect. Disabling nested scrolling while a nested scroll is in progress has the effect of stopping the nested scroll.
這里設置為false,放棄自己的滑動,交給外部的NestedScrollView處理,就沒有出現卡頓的現象了,並且有fling的效果

『貳』 android 關於手勢事件onFling

touch事件中先return給手勢事件(return gestureDetector.onTouchEvent(event); ),在onFling中判斷,如果速度大於一個值就執行,應該就可以的

『叄』 Android 里的手勢監聽SimpleOnGestureListener 綁定到LinearLayout 或 RelativeLayout 不觸發 onFling()

讓OnTouch方法 返回 true;
這樣寫試試
public boolean onTouch(View v, MotionEvent event) {
detector.onTouchEvent(event);
return true;

}
不行的話 你了解下這些事件里返回值的意義,懂了 就有解決思路了

『肆』 android fragment怎麼監聽上下滑動

view 或者 activity 實現 OnGestureListener 介面。
在 onScroll 方則陪舉法中實現上下亂納滑動:
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
Log.d("Fling", "Fling Happened!");
float x1 = e1.getX(), x2 = e2.getX();

if (x1 -x2 >孫碧 120) {
if (mDirection != EAST) {
mNextDirection = WEST;
}
Log.d(this.getClass().getName(), "To LEFT" + "(" + x1
+ "," + x2 + ")");
return (true);
} else if (x1 - x2 < -120) {
if (mDirection != WEST) {
mNextDirection = EAST;
}
Log.d(this.getClass().getName(), "To Right" + "(" + x1
+ "," + x2 + ")");
return (true);
}

return false;
}

『伍』 Android的手勢GestureDetector, onFling之前肯定有onscroll嗎

Fling之前必然有scroll,因為Fling就是scroll達到一定速度的後續結果。
你在onScroll時,是無法判定之後會不會有fling,這個判定只能在ACTION_UP之後,通過計算手勢的速度來決定。
你可能說,我可以中間根據scroll的速度來判斷,可是呢,ta可能很快的滾過,但是馬上慢下來,再慢慢抬起。所以在最後抬起之前判斷,是做不到完全准確的。

『陸』 android ontouch事件return true和return false的區別

1,return false說明你還沒消費onTouch事件,在執行完你onTouch裡面的代碼之後,onTouch事件並沒有結束。就是會自動地執行Gallery這個view里onTouch代碼(這個為默認).所以這就是為什麼沒增加你的處理的時候就只自動地調用Gallery的onTouch,若你在onTouch裡面增加你的代碼並且return false就會執行你的處理和默認的處理。

2,return true說明你已經消費完了onTouch事件,在執行完你的onTouch裡面的代碼之後,這個onTouch事件就結束了。也就是說不會再調用默認的onTouch事件了。在onTouch裡面有很多種的處理比如move,down,up....,若你在move裡面return false,那麼接著的fling,up等後面的事件也不會處理的。

『柒』 Android自定義View之區塊選擇器

先來看下效果吧:

我們來分析這個view需要實現哪些效果。

別害怕有這么多的功能,我們一個一個來實現。首先是刻度尺,這個簡單。由於完整的刻度尺是比屏幕寬度大的,因此我們先來了解幾個概念:

這裏手機屏幕的寬度是width,刻度尺的寬度的時maxWidth,我們其實只需要繪制手機屏幕可見的部分就可以了,這里的offset表示手機屏幕的左邊與刻度尺左邊的偏移量。

了解了這個概念,我們就來開始寫吧,定義一個View,處理下構造都指向3個參數的那個,然後統一做初始化:

我們在onMeasure中處理了wrap_content的高度。然後在onSizeChanged中獲取尺寸參數:

接著就開始繪制吧:

這里的titles代表了刻度的標識,每一個元素代表一個刻度(這里我位元組寫死了,實際上可以通過方法set,也不一定是時間,能代表刻度的都可以)。通過rate設置長短刻度的比例,這里我設置了1:1。運行一下看看,目前僅僅能看到從0開始,看不到完整的刻度尺,我們需要實現touch事件產生移動才有效果。

我們重寫onTouchEvent來實現滑動效果:

我們計算出每次move事件的X方向的變化量dx,然後通過這個dx改變offset,並且處理一下邊界的情況。然後調用postInvalidate刷新界面。
運行一下看看!現在我們可以滑動刻度尺了。但是好像還有點問題,平時我們使用ScrollView的時候用力劃一下,可以看到手指離開了屏幕,但是內容還可以繼續滾動。而目前我們自定義的這個view只能通過手指滑動,如果手指離開屏幕就不能滑動了。這樣的體驗顯然不夠好,我們來實現這個慣性滑動的效果吧!

要實現慣性滑動,我們需要用到兩個類:VelocityTracker,OverScroller。
VelocityTracker簡介
view滑動助手類OverScroller

velocityTracker.computeCurrentVelocity方法的第二個參數表示最大慣性速度,這里我設置8000,避免刻度尺過快的滑動。通過調用scroller.fling方法將計算出的速度交給scroller,然後在computeScroll方法中獲取當前值,並與上一次的值做差算出變化量dx,同樣用這個dx變化offset刷新界面實現滑動效果。

刻度尺完成了,接下來是不可選的灰色區域。我採用兩個int值表示在刻度尺的區域,刻度尺的每個刻度表示一個最小單位,前一個int表示在刻度尺的起始位置,後一個int表示占據的刻度數量。

我用一個list存放設置的不可選區域,然後在另一個list中存放轉換成RectF的位置信息。這里的RectF是在相對於整體刻度尺而言的,因此繪制到屏幕的時候需要減去offset,並且需要考慮只有部分在屏幕可見的情況。避免在onDraw方法中創建過多臨時變數,我聲明一個成員變數tempRect,用來保存繪制時的臨時參數。

完成了不可選區域,可選區域也是同樣的。由於只能有一個可選區域,我們只需要定義一個RectF。額外需要考慮與不可選區域相交時會變色,我定了一個overlapping表示是否相交,通過RectF的intersects方法判斷。

通過前面的分析,我們知道這個view中的事件有很多種:點擊,移動刻度尺,移動選中區域,擴展選中區域。我們定義這四種類型便於後續的事件處理:

然後改造一下onTouchEvent:

performClick會在你重寫onTouchEvent時as提示你需要重寫的方法,因為你可能沒有考慮到如果給這個view設置OnClickListener的情況。如果你沒有在onTouchEvent中調用performClick,那麼setOnClickListener方法就失效了。

你可能注意到這一次比較復雜,並且還有一個linking欄位,表示是否正在聯動,我解釋一下這個聯動的概念:通過gif其實你可能注意到,當我移動或者擴展選中區域的時候,如果移動到了屏幕的邊界,後面的刻度尺就會跟著移動,實際上這個時候選中區域在屏幕中的位置沒有改變,只是刻度尺移動了。一開始我也是通過dx來改變offset,但是存在一個問題,移動到屏幕邊緣之後,手指可以移動的區域已經很小了,不會產生足夠的dx(手指不移動的話,不會有新的touch事件產生)。最好的體驗是我把手機移動到屏幕邊緣,刻度尺就會自己按照一定的速率移動直到最大offset或者最小offset。於是我使用了Handler,當滿足條件後發送消息,表示開始進行聯動,會按照固定速度產生一個dx改變offset。當然,在離開屏幕邊緣的時候還需要及時取消handler的任務。

至此,功能基本已經實現了,運行一下看看效果吧~

後面需要做什麼那?現在這個view只能自己玩,我需要它與其他view有交互,比如選中什麼區域,狀態的改變生么的。

聲明兩個介面,並在適當時候回調它們的方法,這樣外部就能感知view的狀態變化。

後面的話就是根據業務添加一些api了,例如添加不可選區域,改變刻度范圍什麼,一切都看需求了。

想學習更多Android知識,或者獲取相關資料請加入Android開發交流群:1018342383。 有面試資源系統整理分享,Java語言進階和Kotlin語言與Android相關技術內核,APP開發框架知識, 360°Android App全方位性能優化。Android前沿技術,高級UI、Gradle、RxJava、小程序、Hybrid、 移動架構師專題項目實戰環節、React Native、等技術教程!架構師課程、NDK模塊開發、 Flutter等全方面的 Android高級實踐技術講解。還有在線答疑

『捌』 如何在android中實現swipe的手勢功能及頁面拖動動畫

SimpleOnGestureListener. 你只需要實現自己所關心的手勢就可以了.
Swipe在android裡面是叫Fling ^_^
首先創建自己的一個手勢detector類:

private static final int SWIPE_MIN_DISTANCE = 120; private static final int SWIPE_MAX_OFF_PATH = 250; private static final int SWIPE_THRESHOLD_VELOCITY = 200;然後在onFling方法中, 判斷是不是一個合理的swipe動作: if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { viewFlipper.setInAnimation(slideLeftIn); viewFlipper.setOutAnimation(slideLeftOut); viewFlipper.showNext(); } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { viewFlipper.setInAnimation(slideRightIn); viewFlipper.setOutAnimation(slideRightOut); viewFlipper.showPrevious(); }里的viewFlipper是含有多個view的一個container, 可以很方便的調用prev/next view, 加上animation動畫, 可以達到一些不錯的效果:
viewFlipper = (ViewFlipper)findViewById(R.id.flipper); slideLeftIn = AnimationUtils.loadAnimation(this, R.anim.slide_left_in); slideLeftOut = AnimationUtils.loadAnimation(this, R.anim.slide_left_out); slideRightIn = AnimationUtils.loadAnimation(this, R.anim.slide_right_in); slideRightOut = AnimationUtils.loadAnimation(this, R.anim.slide_right_out); 自定義的animation可以查看具體的XML, 比如從左邊進來的一個動畫:

『玖』 如何優雅地在Android上實現iOS的圖片預覽

原文博客鏈接

用過 iOS 的都知道,擬物理的回彈效果在上面非常普遍,因為這是 iOS 系統支持的一套 UI 框架,但是 Android 就沒有了,就拿圖片查看器來講,iOS 的效果就是感覺一張圖片被綁定在了彈簧裝置上,滑動很自然,Android 沒有自帶的圖片查看器,需要自己實現

市面上主流的圖片查看器都沒有回彈的效果,一部分原因是沒有這個需求,還有一部分是實現麻煩,這里講述一個個人認為最好的方案

一個圖片查看器,要求可以滑動 Fling,觸碰到邊界的時候回彈,有越界孝喚回彈的效果,支持雙指縮放,雙擊縮放

咋一看需求,應該好寫,滾動的時候用 Scroller 來解巧態凱決,回彈效果直接用 ValueAnimator ,設置插值器為減速插值器來解決。看似簡單,但是因為是仿物理效果,中間牽扯到從滾動到回彈的時候( Scroller 動畫切換到 ValueAnimator 動畫)的閉老速度銜接問題,要看上去從滾動到開始回彈至結束沒有突兀,中間的特判邊界處理是很麻煩的,還要牽扯到縮放,所以不考慮這種方案

既然是要模擬現實中的物理效果,為何不在每一幀根據當前的狀態得到對用的加速度,然後去計算下一幀的狀態位置,這樣只要模擬現實中的物理加速度不就可以實現了嗎,那些邊界特判之類的就可以去見閻王了

方案確定完畢,接下來就是選定加速度的方程,要模擬彈簧的效果,拉力很簡單,用胡克定律嘛! F = k * dx ,摩擦力呢? Ff = μ*FN ? 這里推薦一個更加好的方案,借鑒自 Rebound 庫,這是 Facebook 的一個彈簧動畫庫,設定一個目的數值,它會根據當前的拉力,摩擦力,速度然後變化到目標值,加速度方程為

其中 tension 為彈性系數, friction 為摩擦力系數,為什麼讓摩擦力和速度成正比呢?如果摩擦力和速度成正比,那麼就不存在靜摩擦力,也就是不存在物體靜止情況下拉力小於摩擦力的情況(因為速度為0的時候,阻力為0,除非拉力為0),物體肯定會向目標地點靠近,遏制了物體摩擦力過大而無法達到目的地情況

為了方便接入各種 View ,設計一個 ZoomableGestureHelper 類

設計目的,我只需要知道視圖的大小邊界 (bounds) 和內部可滾動回彈的邊界 (innerBounds),就可以通過計算得到一個新的轉換矩陣

對於物理狀態,需要一個類 SpringPhysicsState 來做存儲,裡麵包含了速度、拉力系數、摩擦力系數,不保存位置,因為位置是通過 getBounds 動態計算得到的

速度分解成水平方向和垂直方向,因為處理方法一樣,下面只講述垂直方向的計算

狀態1 :其中一邊有越界

分析一下上圖中的位置,藍色部分為內部圖片,它被拖動越界了,此時的合力應該為 tension * dx - friction * v , v 為圖片在 y 軸方向上的速度,( dx 和 v 都是矢量,我暫且設置向右和向下為正),之後就直接調用 invalidate(); ,就可以播放動畫了。

狀態2:兩邊都沒越界

此時因為兩邊都沒有越界,所以應該不存在拉力,可以認為此時 dx 為0,摩擦力需要注意下,因為可以支持滑動( Fling ),所以此時的摩擦力要比之前越界回彈時候的摩擦力小,至於具體數值,文末會給出

狀態3:兩邊都超出

此時兩邊都超出邊界,藍色區域應該和紅色區域中心綁定,所以此時的 dx 為 dxBottom - dxTop (注意符號,因為 dx 為矢量,所以不能是 dxTop - dxBottom )

縮放的方法和移動一致,設定 tension 和 friction ,邊界設定為外面紅色的框框,藍色區域無法某一邊充滿紅色區域的時候,有拉力,否則沒拉力,摩擦力一直存在,至於雙擊放大和放小,只需要在雙擊的時候給縮放狀態設置一個初速度,然後 invalidate(); ,搞定!是不是很簡單啊

時間這一個參數在計算中是非常重要的,這關繫到當前微分狀態的數值變化,假如用歐拉方法模擬速度和位置的變化, x' = x + v * dt , v' = v + a * dt ,公式可以看出時間決定了動畫的快慢,為了接近現實物理時間,這里採用的時間單位為秒(計算機中常用的是毫秒)

確定了單位,還需要控制一下時間間隔的數值范圍,我們不能讓兩次 computeScroll 的時間間隔過於短或者過於長,這里採用的策略為固定每次計算時候的時間間隔,如果兩次 computeScroll 的時間間隔小於此時間間隔,那麼保存累計時間間隔,等待下一次 computeScroll ,直到大於等於固定的時間間隔,再用 while 循環一步一步的計算

結束判定是唯一的一個坑,因為計算機只是在 dt 時間內模擬速度和位移的變化,不是通過微積分計算的,存在誤差,比如歐拉方法 x' = x + v * dt 和 v' = v + a * dt 計算得到的 x' 和 v' 都是近似數值,把 dt 這段時間內的變化看成了勻變速運動

所以結束判定還需要設置一個閾值,當速度和偏移量小於此數值的時候,可以認定為達到了目的地

對於 ViewPager 的適配有些問題,如果在 Down 的時候 requestDisallow true 移動過程中到了左右邊界又 requestDisallow false ,此時 ViewPager 會有一個突變( 突變可恥但有用 ),而且多指頭的時候可能會崩潰,這是 ViewPager 的 Bug,具體細節請看源碼

『拾』 android中listview如何支持上下滑動,左右滑動且左右滑動時可以指定固定列數

左右滑動可以用gallery,不知道LZ想要什麼樣的效果呢,不過提醒一下,不要用scrollview嵌套listview,效果不好哦~~

熱點內容
聽ti密碼是多少 發布:2025-02-12 08:22:15 瀏覽:288
淘寶上傳視頻憑證 發布:2025-02-12 08:06:46 瀏覽:878
java畫 發布:2025-02-12 08:01:00 瀏覽:549
光遇安卓官服是在哪裡下載 發布:2025-02-12 07:47:47 瀏覽:648
安卓手機如何關閉程序打開廣告 發布:2025-02-12 07:31:06 瀏覽:469
新版影視大全不能緩存 發布:2025-02-12 07:31:04 瀏覽:976
sql兩個欄位in 發布:2025-02-12 07:29:45 瀏覽:771
漂亮網站源碼 發布:2025-02-12 07:26:40 瀏覽:760
執行腳本前 發布:2025-02-12 07:14:49 瀏覽:472
android天氣預報介面 發布:2025-02-12 07:12:43 瀏覽:703