2011-10-25 3 views
18

windowIsFloating alors qu'un excellent guichet unique pour créer Dialog UI de style a beaucoup de --- bugs --- quirks.Comment créer une activité transparente SANS windowIsFloating

Celui que je suis aux prises est en ce moment qui il a attribué la largeur/hauteur de l'ancêtre haut comme "wrap_content "plutôt que la largeur/hauteur de l'écran. Cela signifie que la conception de l'interface utilisateur habituelle d'utiliser "match_parents" se propager vers le haut .. pour devenir "wrap_content" Bad fois

alors, ce que je voudrais vraiment est de créer une activité et une mise en page comme ceci:

<LinearLayout android:layout_height="wrap_content" 
       android:layout_width="match_parent" 
       android:orientation="vertical" 
       android:id="@+id/containerPageConatiner" 
       android:background="@drawable/windowBackground"> 
    <View   android:layout_width="match_parent" 
        android:layout_height="0dp" 
        android:layout_weight="1"/> 
    <FrameLayout android:id="@+id/singlePane" 
        android:layout_height="wrap_content" 
        android:layout_width="match_parent" 
        android:layout_gravity="center_horizontal|center_vertical" 
        android:padding="10dp"/>  
    <View   android:layout_width="match_parent" 
        android:layout_height="0dp" 
        android:layout_weight="1"/>       
</LinearLayout> 

qui produit une interface utilisateur montrant une seule fenêtre (@ id/singlePane) sur l'activité qui l'a appelée

Quelqu'un at-il le juste à droite ensemble de styles nécessaires pour créer un fond transparent Activité?

Répondre

29

Merci à @PolamReddy qui m'a poussé vers réponse que je voulais:

Le thème Theme.Translucent.NoTitleBar.Fullscreen et ses ancêtres contiennent tous les attributs dont vous avez besoin pour créer une fenêtre translucide. Afin d'obtenir tout sauf windowIsFloating je suis passé par la pile des ancêtres et sorti l'ensemble des attributs:

<style name="Theme.CustomTheme.TransparentActivity"> 
    <item name="android:windowBackground">@android:color/transparent</item> 
    <item name="android:colorBackgroundCacheHint">@null</item> 
    <item name="android:windowIsTranslucent">true</item> 
    <item name="android:windowAnimationStyle">@android:style/Animation</item> 
    <item name="android:windowNoTitle">true</item> 
    <item name="android:windowContentOverlay">@null</item> 
    <item name="android:windowFullscreen">true</item> 
</style> 

Ce style doit être affecté à la Activity dans le AndroidManifest.xml plutôt que la vue racine d'une mise en page.

6

utilisation comme celui-ci pour l'activité dans le fichier manifeste (thème représente la transparence de cette activité.)

<activity android:name=".Settings"  
      android:theme="@android:style/Theme.Translucent.NoTitleBar"/> 
0

La réponse acceptée fonctionne correctement, jusqu'à ce que j'ai besoin d'avoir un EditText dans la fenêtre de style de dialogue, car le clavier IME doux ne pousserait pas le "dialogue" sans windowIsFloating. Je dois donc m'attaquer de front au 'bug'.

Comme avec le cas dans la question, je dois avoir la largeur définie à "match_parent" tandis que la hauteur peut rester "wrap_content". En utilisant windowIsFloating, je finis par mettre en place un ViewTreeObserver, parcourir l'arborescence pendant la mise en page et forcer la fenêtre flottante à la largeur désirée. L'approche est la suivante (en onCreate() de l'activité) -

setContentView(contentView); 

// set up the ViewTreeObserver 
ViewTreeObserver vto = contentView.getViewTreeObserver(); 
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
    int displayWidth = -1; 
    DisplayMetrics metrics = null; 
    View containerView = null; 

    @Override 
    public void onGlobalLayout() {    
     if (containerView == null) { 
      // traverse up the view tree 
      ViewParent v = contentView.getParent(); 
      containerView = contentView; 
      while ((v != null) && (v instanceof View)) { 
       containerView = (View) v; 
       v = v.getParent(); 
      } 
     } 
     if (metrics == null) { 
      metrics = new DisplayMetrics(); 
     } 
     Display display = getWindowManager().getDefaultDisplay(); 
     display.getMetrics(metrics); 
     if (displayWidth != metrics.widthPixels) { 
      displayWidth = metrics.widthPixels; 
      WindowManager.LayoutParams params = 
        (WindowManager.LayoutParams) containerView.getLayoutParams(); 
      // set the width to the available width to emulate match_parent 
      params.width = displayWidth; 
      // windowIsFloating may also dim the background 
      // do this if dimming is not desired 
      params.dimAmount = 0f; 
      containerView.setLayoutParams(params); 
      getWindowManager().updateViewLayout(containerView, params); 
     } 
    } 
}); 

Cela fonctionne jusqu'à Android 7 jusqu'à présent (même en mode écran partagé), mais on peut attraper l'exception de fonte possible pour la coulée de WindowManager.LayoutParams en cas modifications de mise en œuvre futures, et ajouter removeOnGlobalLayoutListener(); dans un endroit approprié.

Questions connexes