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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

【Android 内存优化】自定义组件长图组件 ( 长图滚动区域解码 | 手势识别 GestureDetector | 滑动计算类 Scroller | 代码示例 )

發(fā)布時(shí)間:2025/6/17 Android 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Android 内存优化】自定义组件长图组件 ( 长图滚动区域解码 | 手势识别 GestureDetector | 滑动计算类 Scroller | 代码示例 ) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 一、GestureDetector 創(chuàng)建與設(shè)置
  • 二、GestureDetector 觸摸事件傳遞
  • 三、觸摸滑動(dòng)操作
  • 四、慣性滑動(dòng)操作
  • 五、長(zhǎng)圖滑動(dòng)組件代碼示例
  • 六、運(yùn)行效果
  • 七、源碼及資源下載



官方文檔 API : BitmapRegionDecoder


在【Android 內(nèi)存優(yōu)化】自定義組件長(zhǎng)圖組件 ( 獲取圖像寬高 | 計(jì)算解碼區(qū)域 | 設(shè)置圖像解碼屬性 復(fù)用 像素格式 | 圖像繪制 ) 博客中完成了圖像的區(qū)域解碼 , 并顯示在界面中 ; 本篇博客中主要完成長(zhǎng)圖滑動(dòng)功能 , 觸摸滑動(dòng) , 慣性滑動(dòng) , 操作 ;





一、GestureDetector 創(chuàng)建與設(shè)置



1 . 自定義組件中設(shè)置手勢(shì)識(shí)別類 :


① 手勢(shì)監(jiān)聽(tīng)器實(shí)現(xiàn) : 自定義組件實(shí)現(xiàn) GestureDetector.OnGestureListener 接口 , 并重寫(xiě) onDown , onShowPress , onSingleTapUp , onScroll , onLongPress , onFling 五個(gè)方法 ;

② 觸摸監(jiān)聽(tīng)器 : 自定義組件實(shí)現(xiàn) OnTouchListener 觸摸監(jiān)聽(tīng)器 , 并重寫(xiě) onTouch 方法 ;

③ 創(chuàng)建手勢(shì)識(shí)別對(duì)象 : 創(chuàng)建 GestureDetector 對(duì)象 , 傳入本組件作為手勢(shì)監(jiān)聽(tīng)器 ;

mGestureDetector = new GestureDetector(context, this);

④ 為組件設(shè)置觸摸監(jiān)聽(tīng)器 : 為本自定義組件設(shè)置觸摸監(jiān)聽(tīng)器 ;

setOnTouchListener(this);

2 . 代碼示例 :

/*** 長(zhǎng)圖展示自定義 View 組件**/ public class LongImageView extends View implements GestureDetector.OnGestureListener, View.OnTouchListener {public static final String TAG = "LongImageView";/*** 手勢(shì)識(shí)別*/private GestureDetector mGestureDetector;/*** 滑動(dòng)類*/private Scroller mScroller;public LongImageView(Context context) {this(context, null, 0);}public LongImageView(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public LongImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);// 手勢(shì)識(shí)別mGestureDetector = new GestureDetector(context, this);// 設(shè)置觸摸監(jiān)聽(tīng)器setOnTouchListener(this);// 滑動(dòng)輔助類mScroller = new Scroller(context);}@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)public LongImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);}@Overridepublic void computeScroll() {}/*下面的方法是手勢(shì)識(shí)別監(jiān)聽(tīng)器實(shí)現(xiàn)的方法*/@Overridepublic boolean onDown(MotionEvent e) {return true;}@Overridepublic void onShowPress(MotionEvent e) {}@Overridepublic boolean onSingleTapUp(MotionEvent e) {return false;}/*** 手指滑動(dòng)事件, 此時(shí)手指沒(méi)有離開(kāi)屏蔽** 隨著滾動(dòng) , 改變圖片的解碼區(qū)域 ;** @param e1 滑動(dòng)的起始按下事件 DOWN 事件* @param e2 當(dāng)前事件 MOVE 事件* @param distanceX 水平方向移動(dòng)距離* @param distanceY 垂直方向移動(dòng)距離* @return*/@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {return false;}@Overridepublic void onLongPress(MotionEvent e) {}/*** 慣性滑動(dòng)** @param e1* @param e2* @param velocityX x 方向速度* @param velocityY y 方向速度* @return*/@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {return false;}/*下面的方法是觸摸監(jiān)聽(tīng)器實(shí)現(xiàn)方法*/@Overridepublic boolean onTouch(View v, MotionEvent event) {// 將觸摸事件交給手勢(shì)處理return mGestureDetector.onTouchEvent(event);} }



二、GestureDetector 觸摸事件傳遞



1 . 觸摸事件傳遞給 GestureDetector : 在 View.OnTouchListener 觸摸監(jiān)聽(tīng)器的 onTouch 觸摸回調(diào)方法中 , 將觸摸事件傳遞給 mGestureDetector 處理 ;

@Overridepublic boolean onTouch(View v, MotionEvent event) {// 將觸摸事件交給手勢(shì)處理return mGestureDetector.onTouchEvent(event);}

2 . 傳遞按下后事件 :GestureDetector.OnGestureListener 監(jiān)聽(tīng)器中的 onDown 方法中 , 要將返回值設(shè)置成 false , 此時(shí)事件才能傳遞下去 ;

@Overridepublic boolean onDown(MotionEvent e) {// 觸摸按下 , 此處注意 , 如果想要接收后續(xù)事件 , 此時(shí)需要設(shè)置成 true 返回值return true;}



三、觸摸滑動(dòng)操作



1 . 觸摸滑動(dòng)操作 :


① onScroll 方法 : 觸摸滑動(dòng)主要在 GestureDetector.OnGestureListener 監(jiān)聽(tīng)器中的 onScroll 方法中實(shí)現(xiàn) , 該方法是觸摸滑動(dòng)事件 , 手指全程沒(méi)有離開(kāi)屏幕 ;

② 區(qū)域解碼操作 : 調(diào)用 mRect.offset 方法 , 重新設(shè)置解碼區(qū)域 , 該方法可以移動(dòng) x 軸 , y 軸的解碼 ,

  • 向上滑動(dòng)分析 : 當(dāng)向上滑動(dòng)時(shí) , 觸摸坐標(biāo)由大變小 , distanceY 小于 0 , 應(yīng)的圖片也向上滑動(dòng) , 解碼區(qū)域的 top 和 bottom 減小 ;

  • 向下滑動(dòng)分析 : 當(dāng)向下滑動(dòng)時(shí) , 觸摸坐標(biāo)由小變大 , distanceY 大于 0 , 對(duì)應(yīng)的圖片也向下滑動(dòng) , 解碼區(qū)域的 top 和 bottom 增加 ;

③ 解碼區(qū)域限制 : 解碼的最底部不能超過(guò)圖片高度 , 解碼的最頂部不能小于 0 ; 分別針對(duì)這兩種情況進(jìn)行各種限制 ;

if(mRect.bottom >= mImageHeight){mRect.bottom = mImageHeight;mRect.top = (int) (mImageHeight - mViewHeight / mScale);}if(mRect.bottom <= 0){mRect.top = 0;mRect.bottom = (int) (mViewHeight / mScale);}

④ 目的完成 : 該方法的目的就是重新計(jì)算 Rect 圖像解碼區(qū)域 , 計(jì)算好之后 , 調(diào)用 invalidate 方法 , 最終會(huì)在 onDraw 方法中解碼 Rect 區(qū)域圖片 , 并顯示到自定義組件中 ;



2 . 代碼示例

/*** 手指滑動(dòng)事件, 此時(shí)手指沒(méi)有離開(kāi)屏蔽** 隨著滾動(dòng) , 改變圖片的解碼區(qū)域 ;** @param e1 滑動(dòng)的起始按下事件 DOWN 事件* @param e2 當(dāng)前事件 MOVE 事件* @param distanceX 水平方向移動(dòng)距離* @param distanceY 垂直方向移動(dòng)距離* @return*/@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {/*重新設(shè)置解碼區(qū)域 , 該方法可以移動(dòng) x 軸 , y 軸的解碼當(dāng)向上滑動(dòng)時(shí) , 觸摸坐標(biāo)由大變小 , distanceY 小于 0 ,對(duì)應(yīng)的圖片也向上滑動(dòng) , 解碼區(qū)域的 top 和 bottom 減小 ;當(dāng)向下滑動(dòng)時(shí) , 觸摸坐標(biāo)由小變大 , distanceY 大于 0 ,對(duì)應(yīng)的圖片也向下滑動(dòng) , 解碼區(qū)域的 top 和 bottom 增加 ;*/mRect.offset(0, (int) distanceY);/*高度都不能超出范圍*/if(mRect.bottom >= mImageHeight){mRect.bottom = mImageHeight;mRect.top = (int) (mImageHeight - mViewHeight / mScale);}if(mRect.bottom <= 0){mRect.top = 0;mRect.bottom = (int) (mViewHeight / mScale);}// 重新繪制組件invalidate();return false;}



四、慣性滑動(dòng)操作



慣性滑動(dòng)需要借助 Scroller 進(jìn)行輔助計(jì)算 ;


1 . Scroller 創(chuàng)建 : 在自定義組件的構(gòu)造函數(shù)中創(chuàng)建 Scroller 對(duì)象;

mScroller = new Scroller(context);

2 . 慣性滑動(dòng)回調(diào)方法 : 當(dāng)發(fā)生慣性滑動(dòng)時(shí) , 此時(shí)手指已經(jīng)離開(kāi)屏幕 , 會(huì)自動(dòng)回調(diào) GestureDetector.OnGestureListener 監(jiān)聽(tīng)器的 onFling 方法 , 主要在這個(gè)方法中根據(jù)監(jiān)聽(tīng)到的速度值 , 計(jì)算慣性滑動(dòng)的量 ;


3 . 慣性滑動(dòng)計(jì)算 : 調(diào)用 Scroller 的 fling 方法 , 進(jìn)行計(jì)算 , 在某時(shí)刻可以調(diào)用 Scroller 對(duì)象的 getCurrY 獲取當(dāng)前滑動(dòng)到了哪里 ;

/*** 慣性滑動(dòng)** @param e1* @param e2* @param velocityX x 方向速度* @param velocityY y 方向速度* @return*/@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {/*使用 Scroller 輔助計(jì)算滑動(dòng)距離這里使用 Scroller 計(jì)算 mRect 區(qū)域的 top 值*/mScroller.fling(0, mRect.top, // x , y 起始位置0, (int) -velocityY, // x , y 速度0, 0, // x 的最小值和最大值0, (int) (mImageHeight - mViewHeight / mScale)); // y 的最小值和最大值return false;}

4 . 設(shè)置慣性滑動(dòng)區(qū)域 : 慣性滑動(dòng)后 , View 組件的 computeScroll 方法會(huì)自動(dòng)回調(diào) , 在這里計(jì)算 區(qū)域解碼的 Rect 區(qū)域 , 計(jì)算完成后重繪組件 ;

/*** View 組件方法 , 父容器請(qǐng)求子容器更新其 mScrollX 和 mScrollY 值*/@Overridepublic void computeScroll() {// 如果 Scroller 計(jì)算慣性滑動(dòng)結(jié)束 , 就不再計(jì)算if(mScroller.isFinished()){return;}// 動(dòng)畫(huà)還在繼續(xù)執(zhí)行if(mScroller.computeScrollOffset()) {mRect.top = mScroller.getCurrY();mRect.bottom = mRect.top + (int) (mViewHeight / mScale);// 重新繪制組件invalidate();}}



五、長(zhǎng)圖滑動(dòng)組件代碼示例



package kim.hsl.lgl;import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.BitmapRegionDecoder; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Rect; import android.os.Build; import android.util.AttributeSet; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; import android.widget.Scroller;import androidx.annotation.Nullable; import androidx.annotation.RequiresApi;import java.io.IOException; import java.io.InputStream;/*** 長(zhǎng)圖展示自定義 View 組件**/ public class LongImageView extends View implements GestureDetector.OnGestureListener, View.OnTouchListener {public static final String TAG = "LongImageView";/*** 矩形區(qū)域*/private Rect mRect;/*** Bitmap 解碼選項(xiàng)*/private BitmapFactory.Options mOptions;/*** 圖片寬度*/private int mImageWidth;/*** 圖片高度*/private int mImageHeight;/*** 組件寬度*/private int mViewWidth;/*** 組件高度*/private int mViewHeight;/*** 圖像區(qū)域解碼器*/private BitmapRegionDecoder mBitmapRegionDecoder;/*** 顯示的 Bitmap 圖像*/private Bitmap mBitmap;/*** 圖片解析的縮放因子*/private float mScale;/*** 手勢(shì)識(shí)別*/private GestureDetector mGestureDetector;/*** 滑動(dòng)類*/private Scroller mScroller;/*** 代碼中創(chuàng)建組件調(diào)用該方法* @param context View 組件運(yùn)行的上下文對(duì)象 , 一般是 Activity ,* 可以通過(guò)該上下獲取當(dāng)前主題 , 資源等*/public LongImageView(Context context) {this(context, null, 0);}/*** 布局文件中使用組件調(diào)用該方法 ;* 當(dāng) View 組件從 XML 布局文件中構(gòu)造時(shí) , 調(diào)用該方法* 提供的 AttributeSet 屬性在 XML 文件中指定 ;* 該方法使用默認(rèn)的風(fēng)格 defStyleAttr = 0 ,* 該組件的屬性設(shè)置只有 Context 中的主題和 XML 中的屬性 ;** @param context View 組件運(yùn)行的上下文環(huán)境 ,* 通過(guò)該對(duì)象可以獲取當(dāng)前主題 , 資源等* @param attrs XML 布局文件中的 View 組件標(biāo)簽中的屬性值*/public LongImageView(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}/*** 布局文件中加載組件 , 并提供一個(gè)主題屬性風(fēng)格 ;* View 組件使用該構(gòu)造方法 , 從布局中加載時(shí) , 允許使用一個(gè)特定風(fēng)格 ;* 如 : 按鈕類的構(gòu)造函數(shù)會(huì)傳入 defStyleAttr = R.attr.buttonStyle 風(fēng)格作為參數(shù) ;** @param context View 組件運(yùn)行的上下文環(huán)境 ,* 通過(guò)該對(duì)象可以獲取當(dāng)前主題 , 資源等* @param attrs XML 布局文件中的 View 組件標(biāo)簽中的屬性值* @param defStyleAttr 默認(rèn)的 Style 風(fēng)格* 當(dāng)前的應(yīng)用 Application 或 Activity 設(shè)置了風(fēng)格主題后 , 才生效*/public LongImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);// 解碼區(qū)域mRect = new Rect();// 解碼選項(xiàng)mOptions = new BitmapFactory.Options();// 手勢(shì)識(shí)別mGestureDetector = new GestureDetector(context, this);// 設(shè)置觸摸監(jiān)聽(tīng)器setOnTouchListener(this);// 滑動(dòng)輔助類mScroller = new Scroller(context);}/*** 布局文件中加載組件 , 并提供一個(gè)主題屬性屬性 , 或風(fēng)格資源 ;* 該構(gòu)造方法允許組件在加載時(shí)使用自己的風(fēng)格 ;** 屬性設(shè)置優(yōu)先級(jí) ( 優(yōu)先級(jí)從高到低 )* 1. 布局文件中的標(biāo)簽屬性 AttributeSet* 2. defStyleAttr 指定的默認(rèn)風(fēng)格* 3. defStyleRes 指定的默認(rèn)風(fēng)格* 4. 主題的屬性值** @param context View 組件運(yùn)行的上下文環(huán)境 ,* 通過(guò)該對(duì)象可以獲取當(dāng)前主題 , 資源等* @param attrs XML 布局文件中的 View 組件標(biāo)簽中的屬性值* @param defStyleAttr 默認(rèn)的 Style 風(fēng)格* 當(dāng)前的應(yīng)用 Application 或 Activity 設(shè)置了風(fēng)格主題后 , 才生效* @param defStyleRes style 資源的 id 標(biāo)識(shí)符 , 提供組件的默認(rèn)值 ,* 只有當(dāng) defStyleAttr 參數(shù)是 0 時(shí) , 或者主題中沒(méi)有 style 設(shè)置 ;* 默認(rèn)可以設(shè)置成 0 ;*/@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)public LongImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);}/*** 設(shè)置顯示的圖片* @param inputStream*/public void setImage(InputStream inputStream){// 讀取圖片的尺寸數(shù)據(jù)mOptions.inJustDecodeBounds = true;// 解碼圖片 , 圖片相關(guān)的尺寸數(shù)據(jù)保存到了 mOptions 選項(xiàng)中BitmapFactory.decodeStream(inputStream, null, mOptions);// 獲取圖片寬高mImageWidth = mOptions.outWidth;mImageHeight = mOptions.outHeight;// 設(shè)置 Bitmap 內(nèi)存復(fù)用mOptions.inMutable = true; // 設(shè)置可變mOptions.inPreferredConfig = Bitmap.Config.RGB_565; // 設(shè)置像素格式 RGB 565mOptions.inJustDecodeBounds = false; // 讀取完畢之后, 就需要解析實(shí)際的 Bitmap 圖像數(shù)據(jù)了try {// Bitmap 區(qū)域解碼器mBitmapRegionDecoder = BitmapRegionDecoder.newInstance(inputStream, false);} catch (IOException e) {e.printStackTrace();}// 設(shè)置圖片完畢后 , 刷新自定義組件requestLayout();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);// 獲取測(cè)量的自定義 View 組件寬高mViewWidth = getMeasuredWidth();mViewHeight = getMeasuredHeight();// 根據(jù)組件的寬高 , 確定要加載的圖像的寬高if(mBitmapRegionDecoder != null){mRect.left = 0;mRect.top = 0;// 繪制的寬度就是圖像的寬度mRect.right = mImageWidth;// 根據(jù)圖像寬度 和 組件寬度 , 計(jì)算出縮放比例// 組件寬度 / 圖像寬度 = 縮放因子mScale = (float)mViewWidth / (float)mImageWidth;/*加載的圖像高度寬度 , 與組件的高度寬度比例一致mViewWidth / 加載的圖像寬度 = mViewHeight / 加載的圖像高度此處加載的圖像寬度就是實(shí)際的寬度加載的圖像高度 = mViewHeight / ( mViewWidth / 加載的圖像寬度 )mViewWidth / 加載的圖像寬度 就是縮放因子加載的圖像高度 = mViewHeight / 縮放因子*/// 根據(jù)縮放因子計(jì)算解碼高度mRect.bottom = (int) (mViewHeight / mScale);}}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);if(mBitmapRegionDecoder == null) return;// 內(nèi)存復(fù)用mOptions.inBitmap = mBitmap;// 解碼圖片mBitmap = mBitmapRegionDecoder.decodeRegion(mRect, mOptions);// 設(shè)置繪制的圖像縮放 , x 軸和 y 軸都在 Bitmap 大小的區(qū)域基礎(chǔ)上 , 縮放 mScale 倍Matrix matrix = new Matrix();matrix.setScale(mScale, mScale);canvas.drawBitmap(mBitmap, matrix, null);}/*** View 組件方法 , 父容器請(qǐng)求子容器更新其 mScrollX 和 mScrollY 值*/@Overridepublic void computeScroll() {// 如果 Scroller 計(jì)算慣性滑動(dòng)結(jié)束 , 就不再計(jì)算if(mScroller.isFinished()){return;}// 動(dòng)畫(huà)還在繼續(xù)執(zhí)行if(mScroller.computeScrollOffset()) {mRect.top = mScroller.getCurrY();mRect.bottom = mRect.top + (int) (mViewHeight / mScale);// 重新繪制組件invalidate();}}/*下面的方法是手勢(shì)識(shí)別監(jiān)聽(tīng)器實(shí)現(xiàn)的方法*/@Overridepublic boolean onDown(MotionEvent e) {// 觸摸按下之后 , 就不能在滑動(dòng)了 , 如果圖片還在按之前的慣性滑動(dòng) , 此時(shí)需要強(qiáng)行終止滑動(dòng)if(!mScroller.isFinished()){// 強(qiáng)制終止 Scroller 滑動(dòng)mScroller.forceFinished(true);}// 觸摸按下 , 此處注意 , 如果想要接收后續(xù)事件 , 此時(shí)需要設(shè)置成 true 返回值return true;}@Overridepublic void onShowPress(MotionEvent e) {}@Overridepublic boolean onSingleTapUp(MotionEvent e) {return false;}/*** 手指滑動(dòng)事件, 此時(shí)手指沒(méi)有離開(kāi)屏蔽** 隨著滾動(dòng) , 改變圖片的解碼區(qū)域 ;** @param e1 滑動(dòng)的起始按下事件 DOWN 事件* @param e2 當(dāng)前事件 MOVE 事件* @param distanceX 水平方向移動(dòng)距離* @param distanceY 垂直方向移動(dòng)距離* @return*/@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {/*重新設(shè)置解碼區(qū)域 , 該方法可以移動(dòng) x 軸 , y 軸的解碼當(dāng)向上滑動(dòng)時(shí) , 觸摸坐標(biāo)由大變小 , distanceY 小于 0 ,對(duì)應(yīng)的圖片也向上滑動(dòng) , 解碼區(qū)域的 top 和 bottom 減小 ;當(dāng)向下滑動(dòng)時(shí) , 觸摸坐標(biāo)由小變大 , distanceY 大于 0 ,對(duì)應(yīng)的圖片也向下滑動(dòng) , 解碼區(qū)域的 top 和 bottom 增加 ;*/mRect.offset(0, (int) distanceY);/*高度都不能超出范圍*/if(mRect.bottom >= mImageHeight){mRect.bottom = mImageHeight;mRect.top = (int) (mImageHeight - mViewHeight / mScale);}if(mRect.bottom <= 0){mRect.top = 0;mRect.bottom = (int) (mViewHeight / mScale);}// 重新繪制組件invalidate();return false;}@Overridepublic void onLongPress(MotionEvent e) {}/*** 慣性滑動(dòng)** @param e1* @param e2* @param velocityX x 方向速度* @param velocityY y 方向速度* @return*/@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {/*使用 Scroller 輔助計(jì)算滑動(dòng)距離這里使用 Scroller 計(jì)算 mRect 區(qū)域的 top 值*/mScroller.fling(0, mRect.top, // x , y 起始位置0, (int) -velocityY, // x , y 速度0, 0, // x 的最小值和最大值0, (int) (mImageHeight - mViewHeight / mScale)); // y 的最小值和最大值return false;}/*下面的方法是觸摸監(jiān)聽(tīng)器實(shí)現(xiàn)方法*/@Overridepublic boolean onTouch(View v, MotionEvent event) {// 將觸摸事件交給手勢(shì)處理return mGestureDetector.onTouchEvent(event);} }



六、運(yùn)行效果



橫屏長(zhǎng)圖滾動(dòng)效果 :


豎屏長(zhǎng)圖滾動(dòng)效果 :





七、源碼及資源下載



源碼及資源下載地址 :

  • ① GitHub 工程地址 : Long_Graph_Loading

  • ② LongImageView.java 主界面代碼地址 : LongImageView.java , 這是上述示自定義組件代碼 ;

總結(jié)

以上是生活随笔為你收集整理的【Android 内存优化】自定义组件长图组件 ( 长图滚动区域解码 | 手势识别 GestureDetector | 滑动计算类 Scroller | 代码示例 )的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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