【问题标题】:ActionBar - custom view with centered ImageView, Action Items on sidesActionBar - 具有居中 ImageView 的自定义视图,两侧的操作项
【发布时间】:2013-04-08 06:06:20
【问题描述】:

我需要在“主页”活动的操作栏中将自定义徽标(使用 ImageView)居中。我在这个项目中使用 ABS。这与 S.O. 上发布的另一个问题非常相似。 (ActionBar logo centered and Action items on sides),但我不确定 ImageView 或搜索菜单是否有所不同,因为我没有得到我正在寻找的结果(居中的图像),或者我只是弄错了.基本上,我在左侧设置了一个图标,在中心插入自定义视图,并在右侧(OptionsMenu)有一个搜索图标。图像确实出现在图标的右侧,但它仍然居中。任何关于如何在操作栏中居中 ImageView 的指针将不胜感激。

Home.java:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home);

    LayoutInflater inflater = (LayoutInflater) getSupportActionBar().getThemedContext()
            .getSystemService(LAYOUT_INFLATER_SERVICE);

    final View customActionBarView = inflater.inflate(
            R.layout.actionbar_custom_view_home, null);

    /* Show the custom action bar view and hide the normal Home icon and title */
    final ActionBar actionBar = getSupportActionBar();
    actionBar.setHomeButtonEnabled(true);
    actionBar.setDisplayHomeAsUpEnabled(false);
    actionBar.setDisplayShowTitleEnabled(false);
    actionBar.setIcon(R.drawable.ic_ab_som);
    actionBar.setCustomView(customActionBarView);
    actionBar.setDisplayShowCustomEnabled(true);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = new MenuInflater(this);
    inflater.inflate(R.menu.search, menu);
    return true;
}

res/layout/actionbar_custom_view_home.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center">

<ImageView
    android:id="@+id/actionBarLogo"
    android:contentDescription="@string/application_name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:clickable="false"
    android:duplicateParentState="false"
    android:focusable="false"
    android:longClickable="false"
    android:padding="@dimen/padding_small"
    android:src="@drawable/logo_horizontal" />

</LinearLayout>

res/menu/search.xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item 
        android:id="@id/search_item"
        android:icon="?attr/action_search"
        android:title="@string/search_label"
        android:showAsAction="ifRoom|collapseActionView">
    </item>
</menu>

【问题讨论】:

标签: android android-actionbar actionbarsherlock


【解决方案1】:

如果您想在 ActionBar 的中心显示图像视图,请使用:

只需将下面代码中的getActionBar(); 替换为getSupportActionBar();

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final ActionBar actionBar = getActionBar();
        actionBar.setCustomView(R.layout.actionbar_custom_view_home);
        actionBar.setDisplayShowTitleEnabled(false);
        actionBar.setDisplayShowCustomEnabled(true);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

你的 actionbar_custom_view_home.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/actionBarLogo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:clickable="false"
        android:focusable="false"
        android:longClickable="false"
        android:src="@drawable/ic_launcher" />

</LinearLayout>

隐藏操作栏图标

final ActionBar actionBar = getActionBar();
actionBar.setCustomView(R.layout.actionbar_custom_view_home);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setDisplayUseLogoEnabled(false);
actionBar.setDisplayShowHomeEnabled(false);

注意: 11 API 使用 getActionBar()


已编辑:工具栏

2016 年 2 月 3 日
<android.support.v7.widget.Toolbar
   style="@style/ToolBarStyle"
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:background="?attr/colorPrimary"
   android:minHeight="@dimen/abc_action_bar_default_height_material">

    <ImageView
        android:layout_width="wrap_content"
        android:contentDescription="@string/logo"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:src="@drawable/ic_launcher"/>

 </android.support.v7.widget.Toolbar>

【讨论】:

  • 设置.setDisplayHomeAsUpEnabled(true);后这不起作用
  • 顺序很重要actionBar.setDisplayShowCustomEnabled(true);应该在actionBar.setCustomView之后调用以保持正确的布局参数
  • 我在actionBar.setCustomView(R.layout.actionbar_custom_view_home); 上有一个NullPointerException。是的,我用自己的名字替换了 R.layout.actionbar_custom_view_home
  • 您已将活动扩展到 ActionBarActivity(如果您使用支持 v7)或 sharrlockactivity(如果您使用 sharelock lib)
  • 这不是在 ActionBar 中居中
【解决方案2】:

解释:

粉红色的容器,是您将添加视图的真实空间。

诀窍是做一些数学运算,将视图(无论如何)居中。

在我的例子中,视图是一个 TextView。这是我的完整方法:

public void addTextToActionBar( String textToSet )
{
    mActionbar.setDisplayShowCustomEnabled( true );

    // Inflate the custom view
    LayoutInflater inflater = LayoutInflater.from( this );
    View header = inflater.inflate( R.layout.actionbar_header, null );

    //Here do whatever you need to do with the view (set text if it's a textview or whatever)
    TextView tv = (TextView) header.findViewById( R.id.program_title );
    tv.setText( textToSet );

    // Magic happens to center it.
    int actionBarWidth = DeviceHelper.getDeviceWidth( this ); //Google for this method. Kinda easy.

    tv.measure( 0, 0 );
    int tvSize = tv.getMeasuredWidth();

    try
    {
        int leftSpace = 0;

        View homeButton = findViewById( android.R.id.home );
        final ViewGroup holder = (ViewGroup) homeButton.getParent();

        View firstChild =  holder.getChildAt( 0 );
        View secondChild =  holder.getChildAt( 1 );

        leftSpace = firstChild.getWidth()+secondChild.getWidth();
    }
    catch ( Exception ignored )
    {}

    mActionbar.setCustomView( header );

    if ( null != header )
    {
        ActionBar.LayoutParams params = (ActionBar.LayoutParams) header.getLayoutParams();

        if ( null != params )
        {
            int leftMargin =  ( actionBarWidth / 2 - ( leftSpace ) ) - ( tvSize / 2 ) ;

            params.leftMargin = 0 >= leftMargin ? 0 : leftMargin;
        }
    }
}

布局:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal|center_vertical|center"
    android:orientation="horizontal" >

<TextView
    android:id="@+id/program_title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@android:color/white"
    android:contentDescription="@string/content_description_program_title"
    android:ellipsize="end"
    android:maxLines="1"
    android:textSize="22sp"/>

</RelativeLayout>

享受吧。

【讨论】:

  • 你能添加你的actionbar_header的代码吗?我在 ActionBar.LayoutParams 行上有一个投射异常。谢谢!
  • 您好,我已经编辑了代码,现在您应该提供一个视图并且应该添加它。我还添加了布局。
  • xml 布局是你的 actionbar_layout 还是你的 viewToAdd?
  • 哎呀,我写错了。这个想法是,这两者是相同的观点。
  • @Jakub,我真的建议您切换到工具栏,这是一个“原始”视图,而不是破解工具栏。以前它曾经救过我的命,直到我切换到工具栏:antonioleiva.com/material-design-everywhere
【解决方案3】:

我遇到了这个问题,这是我的解决方案:

ActionBar.LayoutParams layoutParams = new ActionBar.LayoutParams(
        ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.MATCH_PARENT);
layoutParams.gravity = Gravity.CENTER_HORIZONTAL|Gravity.CENTER_HORIZONTAL;
actionBar.setCustomView(yourCustomView,layoutParams);

【讨论】:

  • 这行得通,谢谢
  • 可能你最好使用layoutParams.gravity = Gravity.CENTER
【解决方案4】:

代码中的 ImageView 相对于 LinearLayout 居中,而不是相对于 Action Bar。您可以在布局中添加左边距(android:layout_marginLeft)来调整图像位置。

其他方法不是向操作栏添加图标和操作项,而是使用内部包含图标和按钮的自定义布局。但在这种情况下,您需要自己处理操作项。

【讨论】:

    【解决方案5】:

    派对迟到了,但万一它对其他人有帮助 - 使用图层列表并将其设置为背景。否则,徽标将基于剩余空间居中,而不是 Reinherd 提到的整个工具栏。

    您可以使用具有静态背景颜色的图层列表,以及将重力设置为中心的图像,如下所示。希望对您有所帮助!

    toolbar.axml

    <android.support.v7.widget.Toolbar
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@drawable/toolbar_background"
        android:theme="@style/ThemeOverlay.AppCompat.Dark"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:layout_scrollFlags="scroll|enterAlways"
        app:layout_collapseMode="pin">
    </android.support.v7.widget.Toolbar>
    

    toolbar_background.xml

    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
      <item>
        <shape android:shape="rectangle">
          <solid android:color="@color/colorPrimary" />
        </shape>
      </item>
      <item>
        <bitmap android:src="@drawable/logo" android:gravity="center" />
      </item>
    </layer-list>
    

    【讨论】:

      【解决方案6】:

      我遇到了同样的问题,我建议以下解决方案:

      1. 在您的 res/layout/actionbar_custom_view_home.xml 中将布局的宽度更改为 wrap_content:

        android:layout_width="wrap_content"
        
      2. 像这样获取操作栏的宽度:

        Display display = getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        //width of action bar is the same as width of whole screen
        final int actionBarWidth = size.x;
        
      3. 将 layoutListener 添加到您的 customActionBarView:

        customActionBarView.addOnLayoutChangeListener(
          new OnLayoutChangeListener() {
        
            @Override
            public void onGlobalLayout() {
              float x = customActionBarView.getX();
              int logoImageWidth = imageLogo.getWidth();
              int logoPosition = actionBarWidth / 2 - logoImageWidth / 2;
              if (x != logoPosition) {
                customActionBarView.setX(logoPosition);
                customActionBarView.requestLayout();
              } else {
                customActionBarView.removeOnLayoutChangeListener(this);
              }
            }
          }
        );
        

      【讨论】:

        【解决方案7】:

        我发现唯一有用的是放(根据需要放右或左,或两者兼而有之):

        android:layout_marginLeft|Right="?attr/actionBarSize"
        

        我在这里找到的: http://sourcey.com/android-custom-centered-actionbar-with-material-design/

        【讨论】:

          【解决方案8】:

          对我来说,“layoutParams.leftMargin”具有魔力。我可以将图标从左向右推。

              androidx.appcompat.app.ActionBar actionBar = getSupportActionBar();
              actionBar.setDisplayOptions(actionBar.getDisplayOptions()
                      | ActionBar.DISPLAY_SHOW_CUSTOM);
              actionBar.setDisplayOptions(actionBar.getDisplayOptions());
              ImageView imageView = new ImageView(actionBar.getThemedContext());
              imageView.setImageResource(R.drawable.content_copy);
          
              ActionBar.LayoutParams layoutParams = new ActionBar.LayoutParams(
                      ActionBar.LayoutParams.WRAP_CONTENT,
                      ActionBar.LayoutParams.WRAP_CONTENT
                      );
              layoutParams.leftMargin = 50;
              imageView.setLayoutParams(layoutParams);
          
              actionBar.setCustomView(imageView);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-12-27
            • 2012-09-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-06-16
            • 1970-01-01
            相关资源
            最近更新 更多