2013-03-07 6 views
36

Gibt es eine Möglichkeit, eine Ansicht oben auf der Aktionsleiste zu rendern? Ich möchte eine kleine Tippbox erstellen, die den Benutzer auf ein Element in der Aktionsleiste verweist. Ich weiß, dass ein Toast mit einer festgelegten Ansicht über die Aktionsleiste gerendert wird. Weiß jemand, wie man das mit einer Aussicht macht?Anzeige über der Aktionsleiste

Ich habe versucht, FrameLayout mit layout_gravity="top" zu verwenden und eine Ansicht aufzublasen und sie dann dem Layout der laufenden Aktivität hinzuzufügen.

Ich bedanke mich im Voraus.

bearbeiten: Hier ist ein Bild von dem, was ich dachte war: enter image description here

bearbeiten: Vielleicht etwas genauer erklärt werden müssen. Ich suche nach einem Weg, oder um herauszufinden, ob es überhaupt möglich ist, der Ansichtshierarchie der Aktivität eine Sicht hinzuzufügen, so dass sie zuletzt gerendert wird.

Ähnlich wie CSS, ich möchte eine höhere z-Index-Reihenfolge für diese bestimmte Ansicht (die blaue schwebende Box im Bild), so dass es oben auf der Aktionsleiste Region in der Aktivität gerendert werden würde. Die Ansicht ist in keiner Weise mit der Aktionsleiste verknüpft, sie wird einfach darüber gezeichnet.

+0

nicht abdecken sollten Sie eine Lösung für dieses Problem gefunden? Ich möchte jetzt die gleiche Aufgabe in meiner App ausführen, sehe aber unten keine relevanten Antworten. –

+0

@MM Sehen Sie sich meine Antwort an. Habe es einfach hinzugefügt. – Sean

Antwort

21

Nachdem mit ihm selbst einige Zeit zu kämpfen, hier ist die Lösung (getestet - funktioniert gut):

Die allgemeinen Schritte sind:

  1. erstellen Wrapper Ansicht
  2. Detach die Bildschirmansicht Kinder, legen Sie den Wrapper, und fügen Sie die Kinder
  3. Aufpumpen Sie den Inhalt auf die Kinder
  4. Durch die Steuerung des Wrappers können Sie die Aktionsleiste und den darunter liegenden Inhalt genau steuern.
  5. Jetzt können Sie mit dem Wrapper "Brüder" zur Actionbar/Hauptbereich hinzufügen. Dieser Bruder ist genau das, was du in deinem Bild beschrieben hast.

Lassen Sie uns etwas Code sehen.

Erstellen Sie zuerst eine Methode zum Erstellen einer Wrapper-Ansicht. Der Wrapper wird zwischen dem gesamten Bildschirm und dem Inhalt Ihrer App platziert. ein ViewGroup zu sein, können Sie später seinen Inhalt völlig kontrollieren. Jetzt

private ViewGroup setContentViewWithWrapper(int resContent) { 
     ViewGroup decorView = (ViewGroup) this.getWindow().getDecorView(); 
     ViewGroup decorChild = (ViewGroup) decorView.getChildAt(0); 

     // Removing decorChild, we'll add it back soon 
     decorView.removeAllViews(); 

     ViewGroup wrapperView = new FrameLayout(this); 

     // You should set some ID, if you'll want to reference this wrapper in that manner later 
     // 
     // The ID, such as "R.id.ACTIVITY_LAYOUT_WRAPPER" can be set at a resource file, such as: 
     // <resources xmlns:android="http://schemas.android.com/apk/res/android"> 
     //  <item type="id" name="ACTIVITY_LAYOUT_WRAPPER"/> 
     // </resources> 
     // 
     wrapperView.setId(R.id.ACTIVITY_LAYOUT_WRAPPER); 

     // Now we are rebuilding the DecorView, but this time we 
     // have our wrapper view to stand between the real content and the decor 
     decorView.addView(wrapperView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 
     wrapperView.addView(decorChild, decorChild.getLayoutParams()); 
     LayoutInflater.from(this).inflate(getActivityLayout(), 
        (ViewGroup)((LinearLayout)wrapperView.getChildAt(0)).getChildAt(1), true); 

     return wrapperView; 
    } 

, stören die regelmäßige Activity Schöpfung und stattdessen setContentView verwenden, verwenden Sie die Methode, die wir erstellt haben.

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    // DON'T CALL `setContentView`, 
    // we are replacing that line with this code: 
    ViewGroup wrapperView = setContentViewWithWrapper(R.layout.activity_layout); 

    // Now, because the wrapper view contains the entire screen (including the notification bar 
    // which is above the ActionBar) I think you'll find it useful to know the exact Y where the 
    // action bar is located. 
    // You can use something like that: 
    ViewGroup actionBar = (ViewGroup)((LinearLayout)wrapperView.getChildAt(0)).getChildAt(0); 
    int topOffset = actionBar.getTop(); 

    // Now, if you'll want to add a view: 
    // 1. Create new view 
    // 2. Set padding top - use "topOffset" 
    // 3. Add the view to "wrapperView" 
    // 4. The view should be set at front. if not - try calling to "bringToFront()" 
} 

Das ist es.

Hinweise

  • Ich habe Android's hierarchy-viewer zu verstehen verwendet, was die richtige Hierarchie ist. (Nicht erraten jene 0 und 1 Indizes)
  • Wenn Sie irgendeine Art eines Menüs Schublade in Ihrer Tätigkeit verwenden, könnten Sie haben es ein wenig anders zu konfigurieren, da Schubladen schaffen bereits, dass Wrapper für Sie
  • ich habe durch einen Blick auf this great library

EDIT viel gelernt: siehe @ CristopherOyarzúnAltamirano Antwort für weitere Unterstützung auf neuere Android-Versionen

viel Glück!

+0

Hey Mann. Ich habe einige Probleme, diese Lösung für Android 4.4 zu implementieren. Ich habe diese Ausnahme, irgendwelche Ideen? com.android.internal.widget.ActionBarOverlayLayout kann nicht in android.widget.LinearLayout umgewandelt werden. – Dan1one

+2

Das ist Arbeit für ICS und Jelly, aber Ginger und Kitkat zeichnen Hierarchie anders. –

+0

@ CristopherOyarzúnAltamirano Das ist richtig. – Sean

0

Verwenden Sie die android:actionLayout in Ihrer Datei menu.xml.

<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android"> 
<item android:id="@+id/menu_id" 
     android:title="@string/menu_string_to_show" 
     android:icon="@drawable/ic_menu_icon_name" 
     android:showAsAction="always" 
     android:actionLayout="@layout/action_button_foo" /></menu> 

Dann wird Ihr action_button_foo.xml Layout erstellen:

<?xml version="1.0" encoding="utf-8"?><TextView xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:gravity="center" 
android:text="@string/menu_string_to_show" 
android:drawableLeft="@drawable/ic_menu_icon_name" 
android:background="@drawable/bg_btn_action_bar" 
android:clickable="true" /> 

zu behandeln Klicken Sie auf die folgenden Aktionen ausführen:

@Overridepublic boolean onCreateOptionsMenu(Menu menu) { 
getMenuInflater().inflate(R.menu.my_menu, menu); 

final MenuItem item = menu.findItem(R.id.menu_id); 
item.getActionView().setOnClickListener(new OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     onOptionsItemSelected(item); 
    } 
}); 

return super.onCreateOptionsMenu(menu);} 

das ist, wenn :)

+0

Danke für die schnelle Antwort! Aber ich glaube, das ist ein Menüelement für die Aktionsleiste erstellen? Ich möchte nur eine Ansicht über die Aktionsleiste zeichnen. Diese Ansicht sollte jedoch nicht Teil der Aktionsleiste sein, sie reagiert nicht. – lunaleaps

+0

Was meinst du mit einer Aussicht? –

+0

Es wäre ein TextView in einer Layoutdatei und einem Bildhintergrund. Wenn Sie das hinzugefügte Bild in meinem OP betrachten, wäre es die schwebende blaue Box – lunaleaps

1

ActionBar.setCustomView mit Versuchen (). Nur so kann das Aussehen dieses Bildschirmbereichs geändert werden. Sie können keine View in den Bereich "über" der ActionBar ziehen, da dieser Bereich grundsätzlich vom System gesteuert wird. Auf der anderen Seite können Sie Ihr eigenes Layout dafür bereitstellen.

Wenn Sie genauer erklären, was Sie zu tun versuchen, haben die Befragten möglicherweise bessere Design-Ideen.

+0

Cool, ich habe ein Bild von dem, was ich dachte, aufgenommen. Ich sehe, dass Toasts eine Sicht haben können. Und ich bin gespannt, wie sie ihre Ansichten an die Spitze der Aktionsleiste bringen. – lunaleaps

0

(Referenz: http://www.vogella.com/articles/AndroidActionBar/article.html)
Benutzerdefinierte Ansichten im ActionBar
Sie können auch eine benutzerdefinierte Ansicht auf die ActionBar hinzuzufügen. Verwenden Sie dazu die Methode setCustomView für die Klasse ActionView. Sie müssen auch die Anzeige von benutzerdefinierten Ansichten über die setDisplayOptions()-Methode aktivieren, indem Sie das Flag ActionBar.DISPLAY_SHOW_CUSTOM übergeben.

Zum Beispiel können Sie eine Layout-Datei definieren, die ein EditText Element enthält.

<?xml version="1.0" encoding="utf-8"?> 
<EditText xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/searchfield" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:inputType="textFilter" > 

Dieses Layout kann über den folgenden Code die ActionBar zugeordnet werden. Der Beispielcode erlaubt das Anhängen eines Listeners an die benutzerdefinierte Ansicht.

package com.vogella.android.actionbar.customviews; 

import android.app.ActionBar; 
import android.app.Activity; 
import android.os.Bundle; 
import android.view.KeyEvent; 
import android.widget.EditText; 
import android.widget.TextView; 
import android.widget.TextView.OnEditorActionListener; 
import android.widget.Toast; 

public class MainActivity extends Activity { 

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

ActionBar actionBar = getActionBar(); 
// add the custom view to the action bar 
actionBar.setCustomView(R.layout.actionbar_view); 
EditText search = (EditText) actionBar.getCustomView().findViewById(R.id.searchfield); 
search.setOnEditorActionListener(new OnEditorActionListener() { 

    @Override 
    public boolean onEditorAction(TextView v, int actionId, 
     KeyEvent event) { 
    Toast.makeText(MainActivity.this, "Search triggered", 
     Toast.LENGTH_LONG).show(); 
    return false; 
    } 
}); 
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM 
    | ActionBar.DISPLAY_SHOW_HOME); 
} 
} 
+0

Ah, okay, von dem, was ich verstehe, fügst du eine 'Toast'-Benachrichtigung hinzu, wenn ich auf die Aktionsleiste klicke, speziell auf 'EditText'. Ich habe mich gefragt, wie man eine Ansicht/ein Layout oben auf der Aktionsleiste visuell darstellt. Wie ich weiß, wie Android eine Ansichtshierarchie erstellt. Wie kann ich eine Ansicht einfügen, die zuletzt in der Hierarchie gerendert wird, so dass sie "über" der Aktionsleiste im Sinne der Z-Index-Sortierung oder "Bring View to Front" erscheint. Oder ist es überhaupt möglich? Egal, danke für deine Hilfe Vishal. – lunaleaps

+0

Sie sagen also, dass Sie eine benutzerdefinierte Ansicht in Action-Leiste ohne Verwendung von SetCustomView einfügen müssen. Ich denke, du musst zur benutzerdefinierten Aktionsleiste gehen. –

+0

Besser Sie gehen für benutzerdefinierte Aktionsleiste (Erstellen Sie Ihre eigene Aktionsleiste). Sie können damit machen, was Sie wollen. –

5

fand ich diese Abhilfe basierend auf @Sean Antwort:

 //This is for Jelly, ICS, Honeycomb 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2){ 
      LayoutInflater.from(this).inflate(resContent, (ViewGroup)((LinearLayout)wrapperView.getChildAt(0)).getChildAt(1), true);} 
     //This is for KitKat and Jelly 4.3 
     else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){ 
      LayoutInflater.from(this).inflate(resContent, (ViewGroup) (((ViewGroup) wrapperView.getChildAt(0)).getChildAt(0)), true);} 
     //This is for Ginger 
     else{ 
      LayoutInflater.from(this).inflate(resContent, (ViewGroup) ((LinearLayout)((FrameLayout) wrapperView.getChildAt(0)).getChildAt(0)).getChildAt(1), true);} 
+1

Ich habe Fehler bei Gingerbird-Geräten mit dieser Methode. Ich habe es so bearbeitet: LayoutInflater.from (this) .inflate (resContent, (ViewGroup) ((FrameLayout) decorChild), true); –

14

Es gibt einen viel einfacheren Weg, dies zu erreichen. ActionBar enthält sein Layout in der Klasse ActionBarContainer, die einfach von FrameLayout erbt. Um etwas über der ActionBar anzuzeigen, müssen Sie einen Verweis auf den ActionBarContainer abrufen und Ihre eigene benutzerdefinierte Ansicht hinzufügen. Hier ist der Code

29

Ich habe versucht, etwas anderes zu erreichen, aber ich brauchte eine ähnliche Lösung. Ich musste eine undurchsichtige Ebene zeichnen, die den gesamten Bildschirm abdeckte, sogar die Aktionsleiste - quasi wie ein Dialog.Ich tat das so:

das kann verwendet werden, um alles auf dem Bildschirm zu zeichnen.

2

Ich fand einen viel einfacheren Weg, dies zu tun. Ich habe gerade android: translationZ = "10dp" auf die Ansicht angewendet, die ich die Aktionsleiste abdecken muss.

Ich wählte 10DP aber es kann eigentlich alles, was Sie wollen so lange sein, wie es auf der ActionBar der Erhebung

<ImageView 
     android:layout_width="100dp" 
     android:layout_height="100dp" 
     android:translationZ="10dp" 
     android:src="@drawable/potatoe" /> 

auch überlegen ist, keine Sorge über folgende Warnung Android Studio:

"translationZ kann nicht mit API < 21" verwendet werden.

wird es ignoriert, aber man weiß nicht wirklich, weil die Symbolleiste Sie die Ansicht mit APIs nachsteht 21.