簡體   English   中英

Android PhotoView在方向改變后保持縮放

[英]Android PhotoView Keep Zoom After Orientation Change

我正在使用Chris Banes的PhotoView類能夠放大圖像並看到它,但我想這樣做,以便當我改變方向時,照片仍將在更改后放大。

我理解如何執行此操作的基礎知識,當檢測到方向更改時,將調用onSaveInstanceState,因此我嘗試將實例保存在那里,然后在調用onCreate時將其放回到PhotoView中。

public class MainActivity extends ActionBarActivity
{
PhotoView mPhotoView;

@Override
protected void onCreate( Bundle aSavedInstanceState )
{
    super.onCreate( aSavedInstanceState );

    mPhotoView = new PhotoView(this);
    mPhotoView.setMaximumScale( 12 );
    setContentView( mPhotoView );
    mPhotoView.setImageResource( R.drawable.vm_app_icon);

    if (aSavedInstanceState != null)
    {
        RectF theRect = aSavedInstanceState.getParcelable( "Rect" );
        if ( theRect != null)
        {
            Matrix theMatrix = new Matrix();
            theMatrix.setScale( theRect.bottom, theRect.left, theRect.right, theRect.top );
            mPhotoView.setDisplayMatrix( theMatrix );

        }
    }
}

@Override
protected void onSaveInstanceState( final Bundle outState )
{
    super.onSaveInstanceState( outState );
    RectF theRect = mPhotoView.getDisplayRect();
    if (theRect != null)
    {
        outState.putParcelable( "Rect", theRect );
    }
}
}

但這不起作用。 我應該在捆綁中存儲什么才能應用回PhotoView以保持縮放級別?

好吧,經過10個小時的嘗試,我已經弄清楚了。

為了保存縮放級別,我需要在Bundle,Scale(縮放級別)和DisplayRect(RectF類型)中保存兩件事。

縮放級別 - MinScale和MaxScale之間的數字,在我的實例中介於1和16之間

RectF包含四個值,由於某種原因,這些值是當前視圖相對於當前屏幕方向的左上角的坐標。 即使它保持左上角坐標我不想圍繞它旋轉,我想圍繞中心旋轉,所以我需要找到矩形的中心,然后將該值除以“ScreenBase”,這是一個將標准化值並使其能夠轉換為差異平面的值。 這是我如何保存它:

@Override
    protected void onSaveInstanceState( final Bundle outState )
    {
        super.onSaveInstanceState( outState );

        Matrix theMatrix = mPhotoView.getDisplayMatrix();
        float[] theFloat = new float[9];
        theMatrix.getValues( theFloat );
        RectF theRect = mPhotoView.getDisplayRect();


        if (theRect != null)
        {
            if( theRect.left > ( mViewWidth / 2 ) || ( theRect.left >= 0 ) )
            {
                theRect.left = 0;
            }
            else
            {
                theRect.left = ( theRect.left - ( mViewWidth / 2 ) ) / mScreenBase;
            }

            if( theRect.top > ( mViewHeight / 2 ) || ( theRect.top >= 0 ) )
            {
                theRect.top = 0;
            }
            else
            {
                theRect.top = ( theRect.top - ( mViewHeight / 2 ) ) / mScreenBase;

            }
            outState.putParcelable( "RectF", theRect );

            outState.putFloat( "ZoomLevel", mPhotoView.getScale() );
        }
    }

然后當我們在另一側拾取它時,我們必須對數字進行大量操作,以使新屏幕空間的左上角居中於同一位置(如果出現邊界問題則操縱它),這里是我是怎么做到的

@Override
    protected void onCreate( final Bundle aSavedInstanceState )
    {
        super.onCreate( aSavedInstanceState );

        mPhotoView = new PhotoView( this );
        mPhotoView.setMaximumScale( 16 );
        setContentView( mPhotoView );
        mPhotoView.setImageResource( R.drawable.vm_app_icon );

        mPhotoView.getViewTreeObserver().addOnPreDrawListener( new ViewTreeObserver.OnPreDrawListener()
        {
            public boolean onPreDraw()
            {
                mPhotoView.getViewTreeObserver().removeOnPreDrawListener( this );
                mViewHeight = mPhotoView.getMeasuredHeight();
                mViewWidth = mPhotoView.getMeasuredWidth();
                Matrix theMatrix = mPhotoView.getDisplayMatrix();
                theMatrix.getValues( mBaseMatrixValues );
                mScreenBase = mBaseMatrixValues[ 0 ];
                int theWidth = mPhotoView.getWidth();
                Log.e(TAG, theWidth + "");

                if( aSavedInstanceState != null )
                {
                    float[] theFloats = new float[ 9 ];
                    float theZoom = aSavedInstanceState.getFloat( "ZoomLevel" );
                    RectF theRect = aSavedInstanceState.getParcelable( "RectF" );
                    theFloats[ 0 ] = theZoom;
                    theFloats[ 4 ] = theZoom;
                    theFloats[ 2 ] = ( theRect.left * mScreenBase ) - ( theZoom * mBaseMatrixValues[ 2 ] ) + ( mViewWidth / 2 ); //Left
                    theFloats[ 5 ] = ( theRect.top * mScreenBase ) - ( theZoom * mBaseMatrixValues[ 5 ] ) + ( mViewHeight / 2 ); //Top
                    theFloats[ 8 ] = (float) 1.0;

                    theFloats = CheckBoundaries( theZoom, theFloats, theRect );

                    theMatrix.setValues( theFloats );
                    mPhotoView.setDisplayMatrix( theMatrix ); //Sets the mSuppMatrix in the PhotoViewAttacher

                    Matrix theImageViewMatrix = mPhotoView.getDisplayMatrix(); //Gets the new mDrawMatrix
                    mPhotoView.setImageMatrix( theImageViewMatrix ); //And applies it to the PhotoView (catches out of boundaries problems)
                }
                return true;
            }
        } );
    }

        private float[] CheckBoundaries(final float aZoom, float[] aFloats, final RectF aRect )
        {
            if( aZoom == 1.0 ) //If the zoom is all the way out
            {
                aFloats[ 2 ] = 0;
                aFloats[ 5 ] = 0;
                return aFloats;
            }

            theMaxLeftValue = ( ( mViewHeight * aZoom ) - mViewWidth + ( aZoom * mBaseMatrixValues[ 2 ] ) );
            theMaxTopValue = ( ( mViewWidth * aZoom ) - mViewHeight + ( aZoom * mBaseMatrixValues[ 5 ] ) );
            if( Math.abs( aFloats[ 2 ] ) > ( theMaxLeftValue ) )
            {
                aFloats[ 2 ] = -Math.abs( theMaxLeftValue ) + 10;
            }
            else if( Math.abs( aFloats[ 2 ] ) < ( aZoom * mBaseMatrixValues[ 2 ] ) )
            {
                aFloats[ 2 ] = -( aZoom * mBaseMatrixValues[ 2 ] );
            }

            if( Math.abs( aFloats[ 5 ] ) > ( theMaxTopValue ) )
            {
                aFloats[ 5 ] = -Math.abs( theMaxTopValue ) + 10;
            }
            else if( Math.abs( aFloats[ 5 ] ) < ( aZoom * mBaseMatrixValues[ 5 ] ) )
            {
                aFloats[ 5 ] = -( aZoom * mBaseMatrixValues[ 5 ] );
            }

            if( aFloats[ 2 ] > 0 )
                aFloats[ 2 ] = -( mViewWidth / 2 );
            else if( aFloats[ 5 ] > 0 )
                aFloats[ 5 ] = -( mViewHeight / 2 );

            return aFloats;
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM