還是無法實現長圖滑動效果

 

package com.example.picturetest;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.os.Build;
import android.os.Bundle;

import java.io.IOException;
import java.io.InputStream;

public class MainActivity extends AppCompatActivity {

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        BigView bigView = findViewById(R.id.bigView);

        try {
            InputStream is = getAssets().open("big.jpg");
            bigView.setImage(is);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
package com.example.picturetest;


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.KeyEvent;
import android.view.MotionEvent;
import android.view.View;

import android.widget.Scroller;

import androidx.annotation.RequiresApi;

import java.io.IOException;
import java.io.InputStream;

@RequiresApi(api = Build.VERSION_CODES.M)
public class BigView extends View implements GestureDetector.OnGestureListener,View.OnTouchListener{


    private  Rect mRect;
    private BitmapFactory.Options mOptions;
    private GestureDetector mGestureDector;
    private Scroller mScrpiler;
    private int mImageWidth;
    private int mImageHeight;
    private BitmapRegionDecoder mDecoder;
    private int mViewWidth;
    private  int mViewHeight;
    private float mScale;
    private Bitmap mBitmap;

    public BigView(Context context, Rect mRect) {
        super(context);
    }

    public BigView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public BigView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        //手勢識別




    }



    //第二步,設置圖片得到圖片的位置
    public void setImage(InputStream is){
        mGestureDector  = new GestureDetector(getContext(), this);

        mScrpiler = new Scroller(getContext());
        setOnTouchListener(this);

        //第一步,設置BigView所需要的一些成員變量
        mRect = new Rect();
        //內存複用
        mOptions = new BitmapFactory.Options();

        //滾動類
        //獲取圖片寬和高,注意不能將圖片整個加載進內存
        BitmapFactory.decodeStream(is,null, mOptions);
        mOptions.inJustDecodeBounds = true;
        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的狂傲,測量加載的圖片到底縮放成什麼樣子
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //得到view的寬高
        mViewWidth = getMeasuredWidth();
        mViewHeight = getMeasuredHeight();

        //確定加載圖片的區域
        mRect.left = 0;
        mRect.top = 0;
        mRect.right = mImageWidth;
        //計算縮放因子
        mScale = mViewWidth /(float)mImageWidth;
        mRect.bottom = (int)(mViewHeight/mScale);
       // mRect = new Rect( 0,0,mImageWidth,(int)(mViewHeight/mScale));

    }


    //第四步,畫出具體的內容

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //判斷解碼是不是爲null,如果解碼器沒有拿到,表示沒有設置過圖片
        if(mDecoder == null){
            return;
        }
        //真正的內存複用
        mOptions.inBitmap = mBitmap;
        //指定解碼區域
        mBitmap = mDecoder.decodeRegion(mRect,mOptions);
        //得到一個矩陣進行縮放,相當於得到view的大小
        Matrix matrix = new Matrix();
        matrix.setScale(mScale,mScale);
        canvas.drawBitmap(mBitmap,matrix,null);
    }





    //第五步,處理點擊事件
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        mScrpiler.startScroll(0, 0, 0, 0);

        //直接將事件交給手勢事件處理
        return  mGestureDector.onTouchEvent(motionEvent);
    }

    //第六步 手按下去
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        //如果沒有停止 則強行停止
        if(!mScrpiler.isFinished()){
            mScrpiler.forceFinished(true);
        }
        //繼續接收後序事件
        return  true;
    }

    @Override
    public boolean onDown(MotionEvent motionEvent) {
        return false;
    }

    @Override
    public void onShowPress(MotionEvent motionEvent) {

    }

    @Override
    public boolean onSingleTapUp(MotionEvent motionEvent) {
        return false;
    }




        @Override
    public void onLongPress(MotionEvent motionEvent) {

    }



    //第七步 處理滑動事件 e1 開始事件,手滑按下去開始獲取座標 e2獲取當前事件座標  xy xy軸移動的距離
//    public boolean onScroll(MotionEvent e1,MotionEvent e2,float distanceX,float distanceY){
//        //上下移動的時候,mRect需要改變顯示的區域
//        mRect.offset(0,(int)distanceY);
//        //移動時,處理到達頂部和底部的情況
//        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;
//    }

    @Override
    //第八步,處理慣性問題
    public boolean onFling(MotionEvent e1, MotionEvent e2,float valocityX,float velocityY ){
        mScrpiler.fling(0,mRect.top,0,(int)-velocityY,0,0,0,mImageHeight - (int)(mViewHeight/mScale));
        return  false;
    }

    //第九步  處理計算結果
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        //上下移動的時候,mRect需要改變顯示的區域
        mRect.offset(0,(int)distanceY);
        //移動時,處理到達頂部和底部的情況
        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;
    }

    @Override
    public void computeScroll() {
        if(mScrpiler.isFinished()){
            return;
        }
        if(mScrpiler.computeScrollOffset()){
            mRect.top = mScrpiler.getCurrY();
            mRect.bottom = mRect.top + (int)(mViewHeight/mScale);
            //mRect = new Rect(0,mScrpiler.getCurrY(),0, mRect.top + (int)(mViewHeight/mScale));
            invalidate();
        }
    }


}

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.example.picturetest.BigView
        android:id="@+id/bigView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:ignore="MissingConstraints" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章