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

97

我希望在操作栏中显示自定义搜索(我正在使用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的所有可用宽度?

请求帮助。


你能否使用自定义视图集设置标题? - Roy Lee
6个回答

100

有一个技巧可以解决这个问题。你只需要将主容器从LinearLayout改为RelativeLayout即可。重要的是要设置android:layout_gravity="fill_horizontal"。就这样。


3
@Tomik,你可以看一下我的情景吗?https://dev59.com/X2Qn5IYBdhLWcg3w36M1 当我设置自定义视图后,标题消失了。请帮忙检查一下。 - Roy Lee

37

我自己也遇到了这个问题,并尝试了Tomik的答案。 然而,这并没有使布局在启动时完全可用宽度,只有当您添加一些内容到视图中时才会。

您需要在添加视图时设置LayoutParams.FILL_PARENT

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

这样它就完全填满了可用空间。(您可能还需要使用Tomik的解决方案)。


2
+1,实际上,只有在添加了LayoutParams之后,它才对我起作用,谢谢。 - Mahmoud Badri
1
什么是叠加值? - androidevil
2
@androider 是你的自定义视图。可以从 XML 中膨胀或在代码中创建。 - Bilthon
你的想法是拥有自定义的工具栏布局和视图吗?因为这对我很有效,即使我认为后者会覆盖前者。 - Chucky

11

这是对我起作用的方式(从上面的答案中,它显示了默认标题和我的自定义视图)。

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.

我注意到的是,setCustomView(view)setCustomView(view,params) 两者都将视图的宽度设置为match/fill parent。 setDisplayShowCustomEnabled (boolean showCustom)


将MATCH_PARENT更改为WRAP_CONTENT作为第二个参数的值就解决了问题。使用LinearLayout... - ka3ak

6

当你想让自定义视图占据整个操作栏,甚至隐藏原生标题时,Tomik和Peterdk的答案是有效的。

但是,如果您希望您的自定义视图与标题并排存在(并在显示标题后填充所有剩余空间),那么我可以向您介绍用户Android-Developer在此处提供的出色答案:

https://dev59.com/X2Qn5IYBdhLWcg3w36M1#16517395

他的代码在底部对我完美地运行了。


3
例如,您可以定义一个包含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> 

你可以做

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


    }

2

在Android的启动器应用程序中有一个示例(我已经将其制作成库,在此处),在处理选择壁纸的类(“WallpaperPickerActivity”)内部。

示例显示您需要设置自定义主题才能使其工作。不幸的是,这只对我使用普通框架时有效,而不是支持库的框架。

这里是主题:

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>

编辑:有一种更好的方法可以实现,适用于支持库。只需添加以下代码行,而不是我上面写的代码:

getSupportActionBar().setDisplayShowCustomEnabled(true);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接