如何在 ActionBar 中显示自定义视图?

我希望在操作栏中显示自定义搜索(我正在使用 ActionBarSherlock)。

我明白了:

enter image description here

但是我想使自定义布局(编辑文本字段)占据整个可用宽度。

我已经按照建议的 给你实现了自定义布局。

这是我的自定义布局 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>

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

我如何使自定义布局占据所有可用的宽度的 actionBar

救命啊。

107831 次浏览

There is a trick for this. All you have to do is to use RelativeLayout instead of LinearLayout as the main container. It's important to have android:layout_gravity="fill_horizontal" set for it. That should do it.

I struggled with this myself, and tried Tomik's answer. However, this didn't made the layout to full available width on start, only when you add something to the view.

You'll need to set the LayoutParams.FILL_PARENT when adding the view:

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

This way it completely fills the available space. (You may need to use Tomik's solution too).

The answers from Tomik and Peterdk work when you want your custom view to occupy the entire action bar, even hiding the native title.

But if you want your custom view to live side-by-side with the title (and fill all remaining space after the title is displayed), then may I refer you to the excellent answer from user Android-Developer here:

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

His code at bottom worked perfectly for me.

For example, you can define a layout file which contains a EditText element.

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

you can do

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




}

This is how it worked for me (from above answers it was showing both default title and my custom view also).

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.

What I noticed is that both setCustomView(view) and setCustomView(view,params) the view width=match/fill parent. setDisplayShowCustomEnabled (boolean showCustom)

There is an example in the launcher app of Android (that I've made a library out of it, here), inside the class that handles wallpapers-picking ("WallpaperPickerActivity") .

The example shows that you need to set a customized theme for this to work. Sadly, this worked for me only using the normal framework, and not the one of the support library.

Here're the themes:

styles.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>

value-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>

EDIT: there is a better way to do it, which works on the support library too. Just add this line of code instead of what I've written above:

getSupportActionBar().setDisplayShowCustomEnabled(true);