91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

android實現長圖加載效果

發布時間:2020-09-06 16:15:08 來源:腳本之家 閱讀:149 作者:zhoushenxian 欄目:移動開發

長圖加載要用到一個關鍵的類BitmapRegionDecoder,長圖加載會使用到bitmap內存復用, 比如view大小是440*654,圖片的寬高是440*12000,那么這個時候就要獲取圖片的寬和高, 跟view的寬和高進行對比,獲取到一個縮小比例,那么會得到寬一個比例,高一個比例,用大的比例作為縮放因子,然后配合手勢滑動滑動長圖

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.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Scroller;
 
import java.io.IOException;
import java.io.InputStream;
 
 
public class BigView extends View implements GestureDetector.OnGestureListener, View.OnTouchListener {
  private static final String TAG = "BigView";
  private Scroller mScroller;
  private GestureDetector mGestureDetector;
  private BitmapFactory.Options mOptions;
  private Rect mRect;
  private int mImageWidth;
  private int mImageHeight;
  private BitmapRegionDecoder mDecoder;
  private int mViewWidth;
  private int mViewHeight;
  private float mScale;
  private Bitmap bitmap;
 
  public BigView(Context context) {
    this(context, null, 0);
  }
 
  public BigView(Context context, @Nullable AttributeSet attrs) {
    this(context, attrs, 0);
  }
 
  public BigView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    //指定要加載的矩形區域
    mRect = new Rect();
    //解碼圖片的配置
    mOptions = new BitmapFactory.Options();
    //手勢
    mGestureDetector = new GestureDetector(context, this);
    setOnTouchListener(this);
    // 滑動幫助
    mScroller = new Scroller(context);
  }
 
  /**
   * 由使用者輸入一張圖片 輸入流
   *
   * @param is
   */
  public void setImage(InputStream is) {
    //先讀取原圖片的 寬、高
    mOptions.inJustDecodeBounds = true;
    BitmapFactory.decodeStream(is, null, mOptions);
    mImageWidth = mOptions.outWidth;
    mImageHeight = mOptions.outHeight;
    //復用 內存復用
    mOptions.inMutable = true;
    //設置像素格式為 rgb565
    mOptions.inPreferredConfig = Bitmap.Config.RGB_565;
    mOptions.inJustDecodeBounds = false;
    //創建區域解碼器 用于區域解碼圖片
    try {
      mDecoder = BitmapRegionDecoder.newInstance(is, false);
    } catch (IOException e) {
      e.printStackTrace();
    }
    requestLayout();
  }
 
  /**
   * 測量 view的大小
   *
   * @param widthMeasureSpec
   * @param heightMeasureSpec
   */
  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    //獲得測量的view的大小
    mViewWidth = getMeasuredWidth();
    mViewHeight = getMeasuredHeight();
    //如果解碼器是null 表示沒有設置過要現實的圖片
    if (null == mDecoder) {
      return;
    }
    //確定要加載的圖片的區域
    mRect.left = 0;
    mRect.top = 0;
    mRect.right = mImageWidth;
//    Log.e(TAG,"縮放因子="+(mViewWidth*1.0f/mImageWidth*1.0f));
//    Log.e(TAG,"縮放因子="+(mViewHeight*1.0f/mImageHeight*1.0f));
    //獲得縮放因子
    mScale = mViewWidth / (float) mImageWidth;
 
    // 需要加載的高 * 縮放因子 = 視圖view的高
    // x * mScale = mViewHeight
    mRect.bottom = (int) (mViewHeight / mScale);
    Log.e(TAG,"l="+mRect.left);
    Log.e(TAG,"t="+mRect.top);
    Log.e(TAG,"r="+mRect.right);
    Log.e(TAG,"b="+mRect.bottom);
  }
 
  /**
   * 把圖片畫上去
   *
   * @param canvas
   */
  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    // 如果解碼器是null 表示沒有設置過要現實的圖片
    if (null == mDecoder) {
      return;
    }
    //復用上一張bitmap
    Log.e(TAG,"復用上一張bitmap="+bitmap);
    mOptions.inBitmap = bitmap;
    //解碼指定區域
    bitmap = mDecoder.decodeRegion(mRect, mOptions);
    //使用矩陣 對圖片進行 縮放
    Matrix matrix = new Matrix();
    matrix.setScale(mScale, mScale);
    //畫出來
 
    canvas.drawBitmap(bitmap, matrix, null);
  }
 
 
  /**
   * 手指按下屏幕的回調
   * @param e
   * @return
   */
  @Override
  public boolean onDown(MotionEvent e) {
    //如果滑動還沒有停止 強制停止
    if (!mScroller.isFinished()){
      mScroller.forceFinished(true);
    }
    //繼續接收后續事件
    return true;
  }
 
  @Override
  public void onShowPress(MotionEvent e) {
 
  }
 
  @Override
  public boolean onSingleTapUp(MotionEvent e) {
    return false;
  }
 
 
  @Override
  public void onLongPress(MotionEvent e) {
 
  }
 
  /**
   * 手指 不離開屏幕 拖動
   * @param e1 手指按下去 的事件 -- 獲取開始的坐標
   * @param e2 當前手勢事件 -- 獲取當前的坐標
   * @param distanceX x軸 方向移動的距離
   * @param distanceY y方向移動的距離
   * @return
   */
  @Override
  public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
    // 手指從下往上 圖片也要往上 distanceY是負數, top 和 bottom 在減
    // 手指從上往下 圖片也要往下 distanceY是正數, top 和 bottom 在加
    //改變加載圖片的區域
    mRect.offset(0, (int) distanceY);
    //bottom大于圖片高了, 或者 top小于0了
    if (mRect.bottom > mImageHeight){
      mRect.bottom = mImageHeight;
      mRect.top = mImageHeight-(int) (mViewHeight / mScale);
    }
    if (mRect.top < 0){
      mRect.top = 0;
      mRect.bottom = (int) (mViewHeight / mScale);
    }
    //重繪
    invalidate();
    return false;
  }
 
  /**
   * 手指離開屏幕 滑動 慣性
   * @param e1
   * @param e2
   * @param velocityX 速度 每秒x方向 移動的像素
   * @param velocityY y
   * @return
   */
  @Override
  public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
    /**
     * startX: 滑動開始的x坐標
     * startY: 滑動開始的y坐標
     * 兩個速度
     * minX: x方向的最小值
     * max 最大
     * y
     */
    //計算器
    mScroller.fling(0,mRect.top,
        0,(int)-velocityY,
        0,0,0,
        mImageHeight - (int) (mViewHeight / mScale));
    return false;
  }
 
  //獲取計算結果并且重繪
  @Override
  public void computeScroll() {
    //已經計算結束 return
    if (mScroller.isFinished()){
      return;
    }
    //true 表示當前動畫未結束
    if (mScroller.computeScrollOffset()){
      //
      mRect.top = mScroller.getCurrY();
      mRect.bottom = mRect.top+ (int) (mViewHeight / mScale);
      invalidate();
    }
  }
 
  @Override
  public boolean onTouch(View v, MotionEvent event) {
    //交由手勢處理
    return mGestureDetector.onTouchEvent(event);
  }
}

如果是面試關鍵二點,第一個要說出來這個類,第二個要知道使用了內存復用.

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

台中市| 高尔夫| 和政县| 汶川县| 广元市| 泗水县| 根河市| 兴文县| 威宁| 建湖县| 治多县| 栾城县| 福安市| 三河市| 永丰县| 沙洋县| 乳山市| 石渠县| 简阳市| 德保县| 慈利县| 青田县| 昌平区| 色达县| 清新县| 宝清县| 台中市| 措美县| 海门市| 丘北县| 长垣县| 元谋县| 乌兰察布市| 河曲县| 华宁县| 科技| 始兴县| 大港区| 四平市| 武鸣县| 墨竹工卡县|