10

Ho riscontrato alcuni problemi di ritorno dalla modalità Immersive in un ActionBarActivity. Ho creato una semplice app per illustrare questo problema. C'è un layout con un solo pulsante per attivare la modalità immersiva. Quando si "ritorna" dalla modalità immersiva, la barra delle azioni viene spostata verso il basso dalla sua posizione originale, all'incirca alla stessa distanza che solitamente viene spostata dalla parte superiore dello schermo.Barra di azione visualizzata in modo errato quando si ritorna dalla modalità immersiva

Ho provato questo su un Nexus 4 con Lollipop. Questo comportamento non è avvenuto pre-Lollipop.

Screenshots before, immersed, after.

Un semplice ActionBarActivity che illustra questo problema:

public class MainActivity extends ActionBarActivity { 
    private boolean immersed; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
    } 

    @TargetApi(Build.VERSION_CODES.KITKAT) 
    private void enterImmersiveMode() { 
     if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 
      getWindow().getDecorView().setSystemUiVisibility(
        View.SYSTEM_UI_FLAG_LAYOUT_STABLE 
        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 
        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 
        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 
        | View.SYSTEM_UI_FLAG_FULLSCREEN 
        | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY 
        ); 
      immersed = true; 
     } 
    } 

    @TargetApi(Build.VERSION_CODES.KITKAT) 
    private void leaveImmersiveMode() { 
     if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 
      getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); 
      immersed = false; 
//   recreate(); 
     } 
    } 

    public void toggleImmersive(View v) { 
     if (immersed) { 
      leaveImmersiveMode(); 
     } else { 
      enterImmersiveMode(); 
     } 
    } 
} 

Niente di speciale nel manifesto:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.immersivetest" 
    android:versionCode="1" 
    android:versionName="1.0" > 

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

    <application 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="ImmersiveTest" 
     android:theme="@style/Theme.AppCompat" > 
     <activity 
      android:name=".MainActivity" 
      android:label="ImmersiveTest" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

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

</manifest> 

layout di Trivial:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context="com.example.immersivetest.MainActivity" > 

    <Button 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_centerInParent="true" 
     android:text="toggle immersive" 
     android:onClick="toggleImmersive" 
     /> 

</RelativeLayout> 

La soluzione che uso al momento è chiamare recreate() dopo aver lasciato la modalità immersiva, ma è così sembra un po '"glitch".

Se utilizzo lo minSdkVersion e utilizzo Activity anziché ActionBarActivity, ad esempio non utilizzare la libreria di supporto, quindi non si verifica questo comportamento.

Comprendo che la modalità immersiva è disponibile solo in KitKat + e che non è necessario utilizzare lo ActionBarActivity dalla libreria di supporto, ma il prodotto finito dovrà essere eseguito su api versioni 8+ e la modalità immersiva è facoltativa extra.

Alcune altre soluzioni che ho pensato e licenziati per ora:

  1. Avere un lanciatore involucro Activity che immediatamente in avanti a livello di codice a un ActionBarActivity per le versioni API inferiori.
  2. Avere più apk dalla versione api.

Ciascuna di queste opzioni sembra avere molta manutenzione aggiuntiva.

C'è qualcos'altro che potrei provare? Ci sono errori evidenti nel codice qui sopra, rispetto al ritorno dalla modalità immersiva?

Aggiornamento

allora ho aggiornato il Nexus 4 a 5.1 e la libreria di supporto al rev 22.1.1 e il comportamento è sempre lo stesso. Ho anche aggiornato il codice per utilizzare il nuovo AppCompatActivity dal momento che ActionBarActivity è ora deprecato. Il comportamento è, ancora una volta, lo stesso.

public class MainActivity extends AppCompatActivity { 
    // no changes here 
} 

Aggiornamento

Questo comportamento strano estende anche alle modalità orizzontale.Oltre all'offset nella parte superiore dello schermo, c'è anche un offset a destra dello schermo tra la fine della barra delle azioni e i pulsanti di navigazione. È interessante notare che questo offset sembra essere la dimensione della "barra" del pulsante di navigazione, cioè maggiore dell'offset in alto.

Immagini di paesaggi before, immersed, after.

+0

hai provato con barra degli strumenti invece barra delle azioni? –

+0

Ho provato esattamente cosa c'è nel codice qui sopra, non sto nemmeno facendo nulla in particolare con la barra delle azioni, è solo lì per impostazione predefinita. –

+1

Hai trovato la risposta? Sto avendo lo stesso problema – vijay

risposta

0

Utilizzare una barra degli strumenti ... Ho avuto lo stesso problema e il passaggio a una barra degli strumenti anziché a CustomContentView l'ha risolto.

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 

e impostare il tema del vostro attività a @ stile/Theme.AppCompat.NoActionBar

0

avuto lo stesso problema, fissato con questo: la vostra funzione leaveImmersiveMode() dovrebbe utilizzare questi flag invece:

getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 
       | View.SYSTEM_UI_FLAG_FULLSCREEN); 
Problemi correlati