Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/182.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android PhotoView在方向改变后保持缩放_Android_Image Processing_Imageview_Orientation Changes - Fatal编程技术网

Android PhotoView在方向改变后保持缩放

Android PhotoView在方向改变后保持缩放,android,image-processing,imageview,orientation-changes,Android,Image Processing,Imageview,Orientation Changes,我正在利用Chris Banes的课程来放大图像并查看它,但我希望这样,当我更改方向时,照片在更改后仍会放大 我了解如何执行此操作的基本知识,即当检测到方向更改时,将调用onSaveInstanceState,因此我尝试将实例保存在其中,然后在调用onCreate时将其放回PhotoView public class MainActivity extends ActionBarActivity { PhotoView mPhotoView; @Override protected void o

我正在利用Chris Banes的课程来放大图像并查看它,但我希望这样,当我更改方向时,照片在更改后仍会放大

我了解如何执行此操作的基本知识,即当检测到方向更改时,将调用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 );
    }
}
}

但这不起作用。我应该在bundle中存储什么才能应用回PhotoView以保持缩放级别?

好吧,经过大约10个小时的尝试,我已经找到了答案

为了保存缩放级别,我需要在捆绑包中保存两个东西:缩放级别(Scale)和显示矩形(RectF类型)

缩放级别-最小刻度和最大刻度之间的数字,在我的例子中介于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;
        }
@覆盖
创建时受保护的void(最终捆绑aSavedInstanceState)
{
super.onCreate(aSavedInstanceState);
mPhotoView=新的照片视图(本);
mPhotoView.setMaximumScale(16);
setContentView(mPhotoView);
mPhotoView.setImageResource(R.drawable.vm_app_图标);
mPhotoView.getViewTreeObserver().addOnPreDrawListener(新ViewTreeObserver.OnPreDrawListener())
{
公共布尔onPreDraw()
{
mPhotoView.getViewTreeObserver().removeOnPreDrawListener(此);
mViewHeight=mPhotoView.getMeasuredHeight();
mViewWidth=mPhotoView.getMeasuredWidth();
矩阵theMatrix=mPhotoView.getDisplayMatrix();
theMatrix.getValues(mbasematrix值);
mScreenBase=mbasematrix值[0];
int theWidth=mPhotoView.getWidth();
Log.e(标签,宽度+“”);
if(aSavedInstanceState!=null)
{
float[]offloats=新的float[9];
float theZoom=aSavedInstanceState.getFloat(“ZoomLevel”);
RectF theRect=aSavedInstanceState.getParcelable(“RectF”);
偷盗[0]=缩放;
偷盗[4]=缩放;
theFloats[2]=(theRect.left*mScreenBase)-(theZoom*mbasematrix值[2])+(mViewWidth/2);//左
theFloats[5]=(theRect.top*mScreenBase)-(theZoom*mbasematrix值[5])+(mViewHeight/2);//top
盗贼[8]=(浮动)1.0;
theFloats=检查边界(缩放、theFloats、theRect);
矩阵设置值(盗窃);
mPhotoView.setDisplayMatrix(theMatrix);//在PhotoViewAttacher中设置mSuppMatrix
矩阵theImageViewMatrix=mPhotoView.getDisplayMatrix();//获取新的mDrawMatrix
mPhotoView.setImageMatrix(theImageViewMatrix);//并将其应用于PhotoView(捕捉边界外问题)
}
返回true;
}
} );
}
专用浮点[]检查边界(最终浮点Azom、浮点[]浮点、最终RectF aRect)
{
if(aZoom==1.0)//如果变焦完全消失
{
漂浮物[2]=0;
漂浮物[5]=0;
返浮;
}
MaxLeftValue=((mViewHeight*aZoom)-mViewWidth+(aZoom*mbasematrixvalue[2]);
最大值=((mViewWidth*aZoom)-mViewHeight+(aZoom*mBaseMatrixValues[5]);
if(数学绝对值(浮式[2])>(最大左撇子值))
{
漂浮物[2]=-Math.abs(最大剩余值)+10;
}
else if(Math.abs(afloat[2])<(aZoom*mBaseMatrixValues[2]))
{
漂浮物[2]=-(Azom*mBaseMatrixValues[2]);
}
if(数学绝对值(漂浮物[5])>(最大值))
{
漂浮物[5]=-Math.abs(最大值)+10;
}
else if(Math.abs(afloates[5])<(aZoom*mBaseMatrixValues[5]))
{
漂浮物[5]=-(Azom*mBaseMatrixValues[5]);
}
如果(漂浮物[2]>0)
漂浮物[2]=-(mViewWidth/2);
否则如果(漂浮物[5]>0)
漂浮物[5]=-(mViewHeight/2);
返浮;
}

我可以知道从哪里可以获得“MBasMatrix值”吗?找不到1。什么是mBaseMatrixValues,2。mScreenBase 3。检查边界