Jak wyświetlić widok niestandardowy w ActionBar?

92

Chcę wyświetlić wyszukiwanie niestandardowe na pasku akcji (używam do tego ActionBarSherlock).

Mam to:

wprowadź opis obrazu tutaj

Ale chcę, aby układ niestandardowy (pole edittext) zajmował całą dostępną szerokość.

Zaimplementowałem niestandardowy układ zgodnie z sugestią tutaj .

Oto mój niestandardowy układ search.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    style="?attr/actionButtonStyle"
    android:layout_width="fill_parent"
    android:layout_height="match_parent"
    android:layout_gravity="fill_horizontal"
    android:focusable="true" >

    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical|fill_horizontal" >

        <EditText
            android:id="@+id/search_query"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="left|center"
            android:background="@drawable/bg_search_edit_text"
            android:imeOptions="actionSearch"
            android:inputType="text" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right|center_vertical"
            android:src="@drawable/ic_search_arrow" />

    </FrameLayout>

</LinearLayout>

A w MyActivity:

ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setIcon(R.drawable.ic_action_search);

LayoutInflater inflator = (LayoutInflater) this .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflator.inflate(R.layout.search, null);

actionBar.setCustomView(v);

Jak mogę ustawić niestandardowy układ, aby zajmował całą dostępną szerokość actionBar?

Prosimy o pomoc.

Szabla
źródło
Czy możesz ustawić tytuł z niestandardowym zestawem widoków?
Roy Lee

Odpowiedzi:

95

Jest na to podstęp. Wszystko, co musisz zrobić, to użyć RelativeLayoutzamiast LinearLayoutgłównego pojemnika. Ważne jest, aby android:layout_gravity="fill_horizontal"to przygotować. Że należy to zrobić.

Tomik
źródło
3
@Tomik Czy mógłbyś rzucić okiem na mój scenariusz? stackoverflow.com/questions/16516306/ ... Brakuje mi tytułu po ustawieniu widoku niestandardowego.
Roy Lee
36

Sam się z tym zmagałem i wypróbowałem odpowiedź Tomika. Jednak to nie sprawiło, że układ na początku miał pełną dostępną szerokość, tylko wtedy, gdy dodasz coś do widoku.

LayoutParams.FILL_PARENTPodczas dodawania widoku musisz ustawić :

//I'm using actionbarsherlock, but it's the same.
LayoutParams layout = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
getSupportActionBar().setCustomView(overlay, layout); 

W ten sposób całkowicie wypełnia dostępną przestrzeń. (Być może będziesz musiał użyć rozwiązania Tomika).

Peterdk
źródło
2
+1, właściwie to działało tylko dla mnie po dodaniu LayoutParams, thnx
Mahmoud Badri
1
jaka jest wartość nakładki?
androidevil
2
@androider to Twój niestandardowy widok. Albo zawyżone z XML, albo utworzone w kodzie.
Bilthon
9

Tak to działało dla mnie (z powyższych odpowiedzi pokazywał zarówno domyślny tytuł, jak i mój niestandardowy widok).

ActionBar.LayoutParams layout = new ActionBar.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
// actionBar.setCustomView(view); //last view item must set to android:layout_alignParentRight="true" if few views are there 
actionBar.setCustomView(view, layout); // layout param width=fill/match parent
actionBar.setDisplayShowCustomEnabled(true);//must other wise its not showing custom view.

Zauważyłem, że zarówno szerokość widoku , jak setCustomView(view)i setCustomView(view,params)szerokość widoku = dopasuj / wypełnij element nadrzędny. setDisplayShowCustomEnabled (boolean showCustom)

Bharatesh
źródło
Zmiana MATCH_PARENT na WRAP_CONTENT jako wartość drugiego parametru załatwiła sprawę. Korzystanie z LinearLayout ...
ka3ak
6

Odpowiedzi Tomika i Peterdka działają, gdy chcesz, aby Twój niestandardowy widok zajmował cały pasek akcji, ukrywając nawet tytuł natywny.

Ale jeśli chcesz, aby Twój niestandardowy widok był wyświetlany obok tytułu (i wypełniał całą pozostałą przestrzeń po wyświetleniu tytułu), to mogę polecić Ci doskonałą odpowiedź od użytkownika Android-Developer tutaj:

https://stackoverflow.com/a/16517395/614880

Jego kod na dole działał idealnie dla mnie.

Mike Repass
źródło
3

Na przykład możesz zdefiniować plik układu, który zawiera element EditText.

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

</EditText> 

możesz to zrobić

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


    }
BoldHD
źródło
zaoszczędziłem moje godziny n .. Dzięki
CrazyMind
1

Istnieje przykład w aplikacji uruchamiającej na Androida (tutaj utworzyłem bibliotekę), w klasie, która obsługuje wybieranie tapet („WallpaperPickerActivity”).

Przykład pokazuje, że aby to zadziałało, musisz ustawić niestandardowy motyw. Niestety, działało to dla mnie tylko przy użyciu normalnego frameworka, a nie tej z biblioteki wsparcia.

Oto motywy:

style.xml

 <style name="Theme.WallpaperPicker" parent="Theme.WallpaperCropper">
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:colorBackgroundCacheHint">@null</item>
    <item name="android:windowShowWallpaper">true</item>
  </style>

  <style name="Theme.WallpaperCropper" parent="@android:style/Theme.DeviceDefault">
    <item name="android:actionBarStyle">@style/WallpaperCropperActionBar</item>
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowActionBarOverlay">true</item>
  </style>

  <style name="WallpaperCropperActionBar" parent="@android:style/Widget.DeviceDefault.ActionBar">
    <item name="android:displayOptions">showCustom</item>
    <item name="android:background">#88000000</item>
  </style>

wartość-v19 / styles.xml

 <style name="Theme.WallpaperCropper" parent="@android:style/Theme.DeviceDefault">
    <item name="android:actionBarStyle">@style/WallpaperCropperActionBar</item>
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowActionBarOverlay">true</item>
    <item name="android:windowTranslucentNavigation">true</item>
  </style>

  <style name="Theme" parent="@android:style/Theme.DeviceDefault.Wallpaper.NoTitleBar">
    <item name="android:windowTranslucentStatus">true</item>
    <item name="android:windowTranslucentNavigation">true</item>
  </style>

EDYCJA: istnieje lepszy sposób na zrobienie tego, który działa również w bibliotece wsparcia. Po prostu dodaj tę linię kodu zamiast tego, co napisałem powyżej:

getSupportActionBar().setDisplayShowCustomEnabled(true);
programista Androida
źródło