2015-10-14 91 views
6

我正在手動處理complex view的旋轉,包括恢復propper的位置和大小。在這一刻,我正在嘗試在onLayout(更好的想法是快速)中做到這一點。有時候它很好,但第一次輪換通常是錯誤的,或者沒有孩子的觀點。如何正確恢復旋轉後的視圖狀態

private int oldOrientation = -1; 

    /** 
    * Override method to configure the dragged view and secondView layout properly. 
    */ 
    @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 
    Log.e("mylayout", "onLayout " + df.format(new Date(Calendar.getInstance().getTimeInMillis()))); 
    if (isInEditMode()) { 
     super.onLayout(changed, left, top, right, bottom); 
    } else { 
     dragView.setVisibility(INVISIBLE); 
     if (isDragViewAtTop() && (oldOrientation != getResources().getConfiguration().orientation || oldOrientation == -1)) { 
     dragView.layout(left, top, right, transformer.getOriginalHeight()); 
     secondView.layout(left, transformer.getOriginalHeight(), right, bottom); 
     ViewHelper.setY(dragView, top); 
     ViewHelper.setY(secondView, transformer.getOriginalHeight()); 
     ViewHelper.setX(dragView, left); 
     ViewHelper.setX(secondView, left); 
     oldOrientation = getResources().getConfiguration().orientation; 
     } else if (isClosedAtLeft() && (
      oldOrientation != getResources().getConfiguration().orientation 
       || oldOrientation == -1)) { 
     dragView.layout(left, top, right, transformer.getOriginalHeight()); 
     secondView.layout(left, transformer.getOriginalHeight(), right, bottom); 
     ViewHelper.setY(dragView, top); 
     ViewHelper.setY(secondView, transformer.getOriginalHeight()); 
     ViewHelper.setX(dragView, left); 
     ViewHelper.setX(secondView, left); 
     closeToLeft(); 
     oldOrientation = getResources().getConfiguration().orientation; 
     } else if (isClosedAtRight() && (
      oldOrientation != getResources().getConfiguration().orientation 
       || oldOrientation == -1)) { 
     dragView.layout(left, top, right, transformer.getOriginalHeight()); 
     secondView.layout(left, transformer.getOriginalHeight(), right, bottom); 
     ViewHelper.setY(dragView, top); 
     ViewHelper.setY(secondView, transformer.getOriginalHeight()); 
     ViewHelper.setX(dragView, left); 
     ViewHelper.setX(secondView, left); 
     closeToRight(); 
     oldOrientation = getResources().getConfiguration().orientation; 
     } else if ((oldOrientation != getResources().getConfiguration().orientation 
      || oldOrientation == -1)) { 
     dragView.layout(left, top, right, transformer.getOriginalHeight()); 
     secondView.layout(left, transformer.getOriginalHeight(), right, bottom); 
     ViewHelper.setY(dragView, top); 
     ViewHelper.setY(secondView, transformer.getOriginalHeight()); 
     ViewHelper.setX(dragView, left); 
     ViewHelper.setX(secondView, left); 
     smoothSlideTo(SLIDE_BOTTOM); 
     oldOrientation = getResources().getConfiguration().orientation; 
     } 
     dragView.setVisibility(VISIBLE); 
    } 
    } 

在這段代碼中,我嘗試輪換,之後恢復初始上海技術交易所時onLayout被調用,然後將其移動到的地方,有觀點旋轉前(有4個狀態,出creen的左,出屏幕右側,屏幕頂端或右下角)。

編輯:

<?xml version="1.0" encoding="utf-8"?> 
<manifest 
    package="com.github.pedrovgs.sample" 
    xmlns:android="http://schemas.android.com/apk/res/android"> 

    <uses-sdk android:minSdkVersion="8" /> 

    <!-- Permissions --> 

    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" /> 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

    <uses-feature 
     android:glEsVersion="0x00020000" 
     android:required="true" /> 

    <!-- Application configuration --> 

    <application 
     android:name=".DraggablePanelApplication" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme"> 

     <!-- Maps API KEY --> 

     <meta-data 
      android:name="com.google.android.maps.v2.API_KEY" 
      android:value="AIzaSyC1rMU-mkhoyTvBIdTnYU0dss0tU9vtK48" /> 

     <!-- Main Activity --> 

     <activity 
      android:name=".activity.MainActivity" 
      android:configChanges="keyboardHidden|orientation|screenSize" 
      android:label="@string/app_name"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 

     <!-- Places sample --> 

     <activity 
      android:name=".activity.PlacesSampleActivity" 
      android:configChanges="keyboardHidden|orientation|screenSize" 

      android:label="@string/places_sample_activity_title" /> 

     <!-- TV Shows sample --> 

     <activity 
      android:name=".activity.TvShowsActivity" 
      android:label="@string/tv_shows_sample_activity_title" /> 


     <!-- Youtube Sample --> 

     <activity 
      android:name=".activity.YoutubeSampleActivity" 
      android:configChanges="keyboardHidden|orientation|screenSize" 

      android:label="@string/youtube_sample_activity_title" /> 


     <!-- Video Sample --> 

     <activity 
      android:name=".activity.VideoSampleActivity" 
      android:configChanges="keyboardHidden|orientation|screenSize" 

      android:label="@string/video_sample_activity_title" /> 

     <meta-data 
      android:name="com.google.android.gms.version" 
      android:value="@integer/google_play_services_version" /> 

    </application> 

</manifest> 

樣活性XML

<?xml version="1.0" encoding="utf-8"?> 

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:draggable_panel="http://schemas.android.com/apk/res-auto" 
    android:id="@+id/fl_container" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <!-- Movie Thumbnail --> 

    <ImageView 
     android:id="@+id/iv_thumbnail" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     style="@style/image_view"/> 

    <!-- DraggablePanel --> 

    <com.github.pedrovgs.DraggablePanel 
     android:id="@+id/draggable_panel" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     draggable_panel:x_scale_factor="@dimen/x_scale_factor" 
     draggable_panel:y_scale_factor="@dimen/y_scale_factor" 
     draggable_panel:top_fragment_height="@dimen/top_fragment_height" 
     draggable_panel:top_fragment_margin_right="@dimen/top_fragment_margin" 
     draggable_panel:top_fragment_margin_bottom="@dimen/top_fragment_margin" 
     draggable_panel:enable_horizontal_alpha_effect="false"/> 

</FrameLayout> 
+0

爲什麼ü沒有使用清單吧..?你可以忽略旋轉,如果你沒有做一些特殊的旋轉... –

+0

@sourabhbans你是'android:configChanges =「locale | keyboardHidden | orientation | screenSize」 '?我使用它,這就是爲什麼我問關於手動處理的觀點(而不是活動) – Yarh

+0

好吧..我認爲這是錯誤的.. –

回答

1

您紛紛伸出ViewGroup而不是View,但還沒有添加任何childDraggableView在XML或代碼。我在DraggableView中看不到任何addChild或任何與兒童有關的代碼。您已使用topFragment,bottomFragment等,並且您使用addFragmentToView()ViewGroup內部進行碎片交易。餿主意!

我知道這很難,很費時間。但是你需要退後一步,思考這個視圖的設計。我強烈建議你把這些topFragment等作爲子女加入DraggableView,並且在這個視圖裏面沒有FragmentManager並執行addTransaction

一旦您開始將片段作爲孩子添加到您的ViewGroup,很多併發症就會消失。我從過去的經歷中這樣說。 onLayout()用於在ViewGroup內安排Child Views。一旦你旋轉設備,onLayout()將再次被調用,並會按你的意願安排子視圖。這將是非常簡單的。一旦你像這樣開始概念化,拖動操作將變得非常簡單。

如果您認爲作爲ViewGroup中的孩子是荒謬的,請參閱ViewPager代碼here。這使用片段作爲輸入,但仍將它們視爲佈局中的子項。

  1. 儘量處理所有與onLayout()本身相關的東西。
  2. 請勿在onSaveInstanceState()中保存位置數據。在此僅保存textdrawable數據。
  3. 總是建議不要覆蓋onCofigurationChanged()

您現在可能無法做到這一點,但從長遠來看,您可能需要重構並按照這種方式進行。

記住的onLayout()的真正目的:

從佈局時調用這個觀點應該在大小和位置分配給每個 其子。帶孩子的衍生課程應覆蓋此方法,並調用其每個孩子的佈局。

2

如果你想深入的布放你View是你對於不需要這些你ViewActivity

android:configChanges="keyboardHidden|orientation|screenSize" 

如果在旋轉後設置了這個,android care更少的是否重新創建你的Activity,從而重新繪製,重新測量,重新定位等等。

所以如果你在的位置[10 100]開始你的應用程序,你的ImageView有時候會被假定放置[10 100],有時它甚至會給你離奇的屏外座標。

+0

sithout它會在視頻流中暫停 – Yarh

0

嘗試使用onConfigrationChange()重寫方法 此方法將處理旋轉。

0

假設您正在創建自己的自定義視圖。如果是這樣,你應該使用View類提供的標準機制。

@Override 
protected void onRestoreInstanceState(Parcelable state) { 
    // Restore state 
} 

@Override 
protected Parcelable onSaveInstanceState() { 
    // Save state 
} 
0

我想這是一個很好的方式

@Override 
    protected Parcelable onSaveInstanceState() { 
     Parcelable superState = super.onSaveInstanceState(); 
     return new YourParcelableObject(superState, yourValues); 
    } 

    @Override 
    protected void onRestoreInstanceState(Parcelable state) { 
     YourParcelableObject savedState = (SavedState) state; 
     super.onRestoreInstanceState(savedState.getSuperState()); 

     //restote other values from YourParcelableObject 
    }