7

Ho un'attività con uno DrawerLayout. Il nostro cliente ci richiede di modificare dinamicamente il colore della barra delle azioni e il colore della barra di stato corrispondente di questa attività, in base all'elemento selezionato dallo DrawerLayout. Questo è fatto facilmente. Tuttavia, il mio problema è che non riesco a mantenere trasparente la barra di stato quando cambio dinamicamente il colore della barra di stato. Quando apro il cassetto, la barra di stato di colore copre la parte superiore della DrawerLayout in questo modo:Android: barra di stato trasparente con azione dinamicaBar colori e DrawerLayout

wrong layout

Tuttavia, vorrei che la mia DrawerLayout a guardare come questo:

correct layout

Questo Posso fare con la seguente riga:

<item name="android:windowTranslucentStatus">true</item> 

Howeve r, il mio problema non è che non posso impostare la trasparenza della barra di stato. Il mio problema è che il cambio dinamico della barra di stato e il colore della barra delle azioni non funziona con windowTranslucentStatus. Il colore della barra di stato rimane colorPrimaryDark (il colore giallo senape visibile sulla barra di stato nelle immagini sopra) anche dopo che ho chiamato getWindow().setStatusBarColor().

Ora, ho seguito il tutorial this e this e this stackoverflow tra molte altre, ma non è stato in grado di risolvere il problema. Tutti questi articoli dicono che lo ActionBar si sposterà in alto, sotto la barra di stato (in modo che la barra di stato si sovrapponga alla barra delle azioni) dopo aver impostato windowTranslucentStatus su true. In seguito, dovrei essere in grado di aggiungere un po 'di padding alla barra delle azioni e semplicemente cambiare il colore della barra delle azioni si tradurrebbe in una barra di stato più scura dello stesso colore poiché la barra di stato è effettivamente traslucida e si sovrappone alla mia barra delle azioni. Tuttavia, per qualche ragione, questo non accade nel mio caso. La barra delle operazioni rimane dov'è se imposto fitsSystemWindows su true o false o rimuovo del tutto l'attributo. La barra delle azioni è sempre sotto la barra di stato che, ovviamente, è sempre gialla se si imposta la trasparenza.

Ho anche provato a impostare un alfa sul colore della barra di stato quando lo si modifica a livello di codice. Questo rende la barra di stato un po 'trasparente, ma sembra strano dato che non è più scuro scuro. Anche la rimozione di CoordinatorLayout non è di aiuto. Ho passato diverse ore a cercare di risolvere questo problema e ora sono abbastanza frustrato. Qualsiasi aiuto è molto apprezzato.

mio activity_main:

<?xml version="1.0" encoding="utf-8"?> 
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
xmlns:tools="http://schemas.android.com/tools" 
android:id="@+id/drawer_layout" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:fitsSystemWindows="true" 
tools:openDrawer="start"> 

<include 
    layout="@layout/app_bar_main" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" /> 

<android.support.design.widget.NavigationView 
    android:id="@+id/nav_view" 
    android:layout_width="wrap_content" 
    android:layout_height="match_parent" 
    android:layout_gravity="start" 
    android:fitsSystemWindows="true"> 

    <include layout="@layout/nav_header_main" /> 

    <android.support.v7.widget.RecyclerView 
     android:id="@+id/nav_menu_recyclerview" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_marginTop="@dimen/nav_header_height" 
     android:clipToPadding="false" 
     android:paddingLeft="@dimen/activity_horizontal_margin" 
     android:paddingRight="@dimen/activity_horizontal_margin" 
     android:paddingTop="@dimen/size_14dp" 
     app:layoutManager="LinearLayoutManager" /> 
</android.support.design.widget.NavigationView> 

</android.support.v4.widget.DrawerLayout> 

E qui è la XML per la mia app_bar_main:

<?xml version="1.0" encoding="utf-8"?> 
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:fitsSystemWindows="true"> 

<android.support.design.widget.AppBarLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:theme="@style/AppTheme.AppBarOverlay" 
    app:elevation="0dp"> 


    <FrameLayout 
     android:id="@+id/toolbar_container" 
     android:layout_width="match_parent" 
     android:layout_height="?attr/actionBarSize" 
     app:popupTheme="@style/AppTheme.PopupOverlay"> 

     <android.support.v7.widget.Toolbar 
      android:id="@+id/toolbar" 
      android:layout_width="match_parent" 
      android:layout_height="?attr/actionBarSize" 
      android:background="?attr/colorPrimary" /> 

     <com.quintype.sakshipost.Widgets.CustomMaterialSearchView 
      android:id="@+id/search_view" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" /> 
    </FrameLayout> 

</android.support.design.widget.AppBarLayout> 

<include layout="@layout/content_main" /> 

</android.support.design.widget.CoordinatorLayout> 

risposta

6

Il tuo problema è causato dal fatto che getWindow().setStatusBarColor() non funziona bene con lo DrawerLayout. Al fine di mantenere il proprio stato barra translucida, oltre ad essere in grado di cambiare il suo colore, è necessario seguire la procedura di seguito:

Add/modificare la seguente tema nel file v21/styles.xml come di seguito:

<style name="AppTheme.NoActionBar" parent="AppTheme"> 
    <item name="windowActionBar">false</item> 
    <item name="windowNoTitle">true</item> 
    <item name="android:windowTranslucentStatus">true</item> 
</style> 

Questo è il tema utilizzato dallo standard DrawerLayout (presupponendo, ovviamente, che si stia utilizzando questo tema nell'attività con lo DrawerLayout). Ciò renderà la barra di stato traslucida, come già sai.

Successivamente, rimuovere android:fitsSystemWindows="true" dal CoordinatorLayout nel app_bar_main.

Avanti, ovunque si sta modificando il colore della barra barra degli strumenti/di stato, utilizzare drawerLayout.setStatusBarBackground(colorDrawable) utilizzando lo stesso colore che si usa per la barra degli strumenti (assumendo, naturalmente, che il riferimento al vostro DrawerLayout si chiama drawerLayout).Si noti che il metodo drawerLayout.setStatusBarBackground() prende un oggetto Drawable, a differenza del metodo window.setStatusBarColor(), che prende un colore int, quindi potrebbe essere necessario convertire il vostro colore a un drawable utilizzando qualcosa di simile a questo:

new ColorDrawable(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary)) 

Questo farà in modo che il vostro la barra di stato è traslucida e dà la possibilità di cambiare i colori. Spero che tu sia in grado di farlo funzionare.

-2

Lo faccio nella mia app come questo.

<style name="AppTheme" parent="Theme.AppCompat.Dark"> 
    <!-- Customize your theme here. --> 
    <item name="colorPrimary">@color/colorPrimary</item> 

il colorPrimary imposta il colore della barra di stato, ma solo se si riavvia l'attività.

quindi impostarlo su un colore nero trasparente, quindi nel codice riavviare l'attività.Puoi creare più di uno stile negli stili, con diversi valori colorPrimary, quindi nella tua attività fai questo.

//onClick or condition statement here 
setTheme(R.style.AppThemeLight); 
setContentView(R.layout.activity_link_manager_light); 
restart(); 


public void restart(){ 
Intent i = getBaseContext().getPackageManager() 
      .getLaunchIntentForPackage(getBaseContext().getPackageName()); 
    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
    startActivity(i); 
} 

Non credo che è necessario reimpostare il contentView a meno che non si sta passando layout così, non è sicuro che si può provare a reimpostare alla stessa disposizione, se non funziona senza di essa.

Questo sicuramente funziona per me ma non ho mai provato ad usare un valore trasparente.

È possibile utilizzare questo metodo per reimpostare l'intero tema dell'app e passare a un nuovo layout con colori diversi in esso codificati, lasciare tutti gli ID uguali sul layout e nel codice si otterrà l'id corretto per quanto tempo quando si fa riferimento a findViewByID DOPO aver impostato setContentView sul layout corretto con l'ID che si chiama da qualche parte. Gli ID di ogni layout sono diversi, ma otterrai sempre l'ID del layout correntemente impostato con setContentView nel momento in cui chiami findViewByID.

è anche possibile salvare il tema attuale in un file sharedpref e utilizzare un interruttore per impostare il tema su AppLaunch prima setContentView è chiamata (altrimenti il ​​colore barra di stato non cambierà)

considerano questo codice. Questo è in prossimità della partenza della onCreate dal modo in cui

String Theme; 
    SaveData = getSharedPreferences(SaveFileName,0); 
    Theme = SaveData.getString("Theme","Default Theme"); 
switch(Theme){ 
     case "Light Theme": 
      setTheme(R.style.AppThemeLight); 
      setContentView(R.layout.activity_link_manager_light); 
      ListTextViewID = R.id.AppListTextViewLight; 
      ListRowID = R.layout.app_list_item_light; 
      break; 

Il modo in cui ho impostato l'apptheme prima ho impostato la contentView è il motivo per il cambiamento di colore di stato funziona.

+0

Potrebbe non aver capito completamente la mia domanda. Posso facilmente impostare il colore della barra di stato usando 'getWindow(). SetStatusBarColor (int color);' Non è necessario riavviare l'attività per questo, né chiamare 'setContentView()' più volte. Tuttavia, il mio obiettivo è impostare la barra di stato su _transparent_ e disegnare la barra di azione _underneath_ it. (Inoltre, riavviare un'attività più volte per una questione così banale è un trucco molto poco elegante.) –

+0

O sì, mi sono perso, beh, puoi farlo anche cambiando il tema genitore da ".NoActionBar" a ".Light" che aggiungi una barra delle azioni e puoi impostare il colore anche usando il tema. questo farà tutto ciò che vuoi ma non so come farlo senza riavviare l'applicazione. –

+0

è anche possibile aggiungere una barra di azione personalizzata in modo programmatico mediante una visualizzazione lineare o vista in cui la barra delle azioni sarebbe, e nasconderla e visualizzarla programmaticamente: "View.setVisibility (View.GONE);" "View.setVisibility (View.VISIBLE);" –

0

Come doc dice here, FLAG_TRANSLUCENT_STATUS non deve essere impostato.

Per questo effetto, la finestra deve essere disegnando la barra sistema sfondi con FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS e FLAG_TRANSLUCENT_STATUS non deve essere impostato.

+0

Avevo provato anche questo, ma questo comporta lo stesso comportamento della prima schermata. Voglio che assomigli al secondo, ma posso ancora cambiare il colore della barra di stato. Potrei anche semplicemente rendere trasparente la barra di stato ed estendere la barra delle azioni sotto di essa. Ma non sono nemmeno in grado di farlo. :( –