2015-10-14 11 views
6

Io sto tentando di gestire la rotazione per complex view manualmente, incluso il ripristino della posizione e della dimensione dell'elica. In questo momento sto cercando di farlo in onLayout (le idee migliori sono velcome). A volte funziona bene, ma spesso la prima rotazione è errata o la vista viene disegnata senza childs.come ripristinare correttamente lo stato di visualizzazione dopo le rotazioni

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); 
    } 
    } 

In questo codice, provo a ripristinare STTE iniziale dopo la rotazione, quando onLayout viene chiamato e quindi spostarlo luogo, la vista era prima della rotazione (ci sono 4 stati, su creen a sinistra, su schermo a destra, in alto a destra o in basso a destra).

Edit:

<?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> 

attività XML di esempio

<?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

perché sono u non usare manifestano per questo ..? Puoi ignorare la rotazione se non stai facendo qualcosa di speciale sulla rotazione ... –

+0

@sourabhbans parla di 'android: configChanges =" locale | keyboardHidden | orientation | screenSize " '? lo uso, questo è il motivo per cui ti sto chiedendo di gestire manualmente la vista (non l'attività) – Yarh

+0

Ok .. sory ho frainteso .. –

risposta

1

Hai esteso un ViewGroup invece di un View e tuttavia non hanno aggiunto alcun child alla DraggableView in XML o nel codice. Non vedo alcun addChild o qualsiasi codice relativo all'infanzia in DraggableView. Hai utilizzato topFragment, bottomFragment, ecc. E hai utilizzato addFragmentToView() per effettuare la transazione di frammenti all'interno dello ViewGroup. Cattiva idea!

So che è difficile e richiede tempo. Ma devi fare un passo indietro e pensare al design di questa vista. Ti suggerisco caldamente di trattare questi topFragment, ecc. Come bambini nello DraggableView, e di non avere un FragmentManager all'interno di questa vista ed eseguire addTransaction.

Dopo aver iniziato ad aggiungere i frammenti come bambini al tuo ViewGroup, molte complicazioni andranno via. Dico questo dalla mia esperienza passata. onLayout() viene utilizzato per disporre lo Child Views all'interno dello ViewGroup. Una volta ruotato il dispositivo, verrà nuovamente chiamato onLayout() e verranno organizzate le visualizzazioni figlio come desiderato. Sarebbe molto semplice. L'operazione di trascinamento sarà molto semplice una volta avviata la concettualizzazione in questo modo.

Se pensate avendo Framgents come bambino nel ViewGroup è assurdo, gentilmente guardare il codice hereViewPager. Questo utilizza i frammenti come input, ma li trattiamo ancora come bambini per il layout.

  1. Provare a gestire tutte le informazioni relative alla posizione nello onLayout() stesso.
  2. Non salvare i dati di posizione in onSaveInstanceState(). Salva solo i dati text o drawable in questo.
  3. È sempre consigliabile non eseguire l'override di onCofigurationChanged().

Potresti non essere in grado di farlo ora, ma nel lungo periodo potresti voler refactoring e farlo in questo modo.

ricordare il vero scopo di onLayout():

Chiamato dal layout quando questo punto di vista dovrebbe assegnare una dimensione e la posizione di ciascuno dei suoi figli. Le classi derivate con i bambini dovrebbero sostituire questo metodo e il layout di chiamata su ciascuno dei propri figli.

2

Se si sta tentando di andare in profondità nel layout del View s non è necessario questo per l' Activity

tuoi View
android:configChanges="keyboardHidden|orientation|screenSize" 

se impostato dopo la rotazione, cura Android meno se ricreare il tuo Activity quindi ridisegnare, -re-misurare, -re-posizionare re-etc-etc.

quindi se si avvia l'app con un ImageView posizionamento [10 100] dopo aver ragazzo rotazione vostra sarà assunto ImageView da collocare [10 100] a volte si potrebbe anche dare strano fuori campo coordinate.

+0

sithout, ci sarà una pausa nel flusso video – Yarh

0

Provare a utilizzare il metodo di sovrascrittura onConfigrationChange() questo metodo gestirà la rotazione.

0

Supponendo che si sta creando la propria visualizzazione personalizzata. In tal caso, dovresti utilizzare i meccanismi standard forniti dalla classe View.

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

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

Credo che questo è un buon modo

@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 
    } 
Problemi correlati