【问题标题】:How to get ActionBar view?如何获取 ActionBar 视图?
【发布时间】:2013-11-30 04:02:51
【问题描述】:

我正在使用Showcase 库来解释我的应用程序功能 用户。在某些时候,我需要将整个ActionBar 调暗以呈现 用户的另一个功能。

为此,我正在使用 View 类的 setAlpha(float num)。因此,为此我需要获取我的ActionBar 的实际视图实例@

顺便说一句,我正在使用 support-7-appcompat 库,它为旧系统提供 ActionBar 支持。

更新

与此同时,我发现了这个选项,如果您配置自定义视图并将其添加到您 ActionBar 使用:

getSupportActionBar().setCustomView(v);

然后要获得ActionBar 中的View,您可以这样做:

(View) activity.getSupportActionBar().getCustomView().getParent().getParent()

有没有更简单或更容易的方法来做到这一点?

【问题讨论】:

    标签: android view android-actionbar android-actionbar-compat showcaseview


    【解决方案1】:

    是的。您实际上可以使用此函数获取视图:

    public View getActionBarView() {
        Window window = getWindow();
        View v = window.getDecorView();
        int resId = getResources().getIdentifier("action_bar_container", "id", "android");
        return v.findViewById(resId);
    }
    

    其工作方式几乎是 actionbar 容器使用 id android.R.id.action_bar_container,但这个 id 不是公开的。因此,我们使用 getIdentifier() 来检索这个 id,然后剩下的就很简单了。

    【讨论】:

    • 如果我使用 actionbarsherlock 会怎样?
    • @ThuyTrinh 我认为是abs__action_bar_containerfor actionbarsherlock
    • @ThuyTrinh 你可以查看我的扩展答案
    • 不适用于带有 ActionBar Compat 的 Android 2.3,但适用于 getPackageName() 而不是“android”。
    • support-library-v7-r21.0.3 上使用ActionBarActivityTheme.Appcompatv.findViewById(resId) 返回nullresId 是有效的。任何建议。
    【解决方案2】:

    我觉得这个方案比较完善,既能处理普通的Activity,也能处理ActionBarActivity。

    它还处理使用工具栏设置操作栏的情况,但您需要在您创建的活动中实现它:

    public static View getActionBarView(final Activity activity) {
        if (activity instanceof IToolbarHolder)
            return ((IToolbarHolder) activity).getToolbar();
        final String packageName = activity instanceof ActionBarActivity ? activity.getPackageName() : "android";
        final int resId = activity.getResources().getIdentifier("action_bar_container", "id", packageName);
        final View view = activity.findViewById(resId);
        return view;
    }
    
    public interface IToolbarHolder {
        public android.support.v7.widget.Toolbar getToolbar();
    }
    

    【讨论】:

    • 不用final View v = window.getDecorView();,可以用activity.findViewById代替。
    • @MoshErsan 似乎是正确的。也许我是从其他地方得到的。
    【解决方案3】:

    对于 support.v7,getActionBarView(ById) 不起作用。

    这会返回 actionBar 工具栏:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        ViewGroup actionBar = getActionBar(getWindow().getDecorView());
        TextView actionBarTitle = (TextView) actionBar.getChildAt(0);
    }
    
    public ViewGroup getActionBar(View view) {
        try {
            if (view instanceof ViewGroup) {
                ViewGroup viewGroup = (ViewGroup) view;
    
                if (viewGroup instanceof android.support.v7.widget.Toolbar) {
                    return viewGroup;
                }
    
                for (int i = 0; i < viewGroup.getChildCount(); i++) {
                    ViewGroup actionBar = getActionBar(viewGroup.getChildAt(i));
    
                    if (actionBar != null) {
                        return actionBar;
                    }
                }
            }
        } catch (Exception e) {
        }
    
        return null;
    }
    

    【讨论】:

    • 欢迎来到 Stack Overflow!虽然这段代码可能会回答这个问题,但最好包含一些上下文,解释它的如何工作以及何时使用它。从长远来看,纯代码的答案没有用处。
    • 实现Toolbar实例的好方案。
    【解决方案4】:

    我对 @idunnololz 的代码做了一些修正以支持 ActionBarSherlock

    private View getActionBarView() {
    
        int actionViewResId = 0;
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
            actionViewResId = getResources().getIdentifier(
                    "abs__action_bar_container", "id", getPackageName());
        } else {
            actionViewResId = Resources.getSystem().getIdentifier(
                    "action_bar_container", "id", "android");
        }
        if (actionViewResId > 0) {
            return this.findViewById(actionViewResId);
        }
    
        return null;
    }
    

    【讨论】:

    • 如果我使用 action_bar_container,它会返回 null,尽管我使用的是来自 appcompat-v7 (r21.0.3) 的 ActionBarActivity。我检查并发现actionViewResId 返回正值。
    • 我认为不再需要此代码,因为您已经可以从工具栏视图访问操作栏视图。
    • 我实际上需要在 ActionBar Title TextView 添加一条最大线,但 this.findViewById(actionViewResId) 返回 null。我什至使用getWindow().getDecorView() 而不是thisaction_bar_title 都没有运气,尽管在这两种情况下actionViewResId 都会返回一个值。你能建议我如何得到它。 编辑对不起,我没有使用ToolBar
    • 让我检查一下谷歌代码,也许他们现在正在为操作栏视图使用不同的标识符。
    • 我认为最好的解决方案是使用 Toolbar 并自定义它的标题,因为 actionbar 新布局没有 id。
    【解决方案5】:

    当使用本机 ActionBar、您自己的 appcompat 的 Toolbar 或 Lollipop 上的本机 Toolbar 时,这将获得 Toolbar/ActionBar

    public static ViewGroup findActionBar(Activity activity) {
        int id = activity.getResources().getIdentifier("action_bar", "id", "android");
        ViewGroup actionBar = null;
        if (id != 0) {
            actionBar = (ViewGroup) activity.findViewById(id);
        }
        if (actionBar == null) {
            actionBar = findToolbar((ViewGroup) activity.findViewById(android.R.id.content)
                    .getRootView());
        }
        return actionBar;
    }
    
    private static ViewGroup findToolbar(ViewGroup viewGroup) {
        ViewGroup toolbar = null;
        for (int i = 0, len = viewGroup.getChildCount(); i < len; i++) {
            View view = viewGroup.getChildAt(i);
            if (view.getClass().getName().equals("android.support.v7.widget.Toolbar")
                    || view.getClass().getName().equals("android.widget.Toolbar")) {
                toolbar = (ViewGroup) view;
            } else if (view instanceof ViewGroup) {
                toolbar = findToolbar((ViewGroup) view);
            }
            if (toolbar != null) {
                break;
            }
        }
        return toolbar;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-08
      • 2012-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-04
      • 1970-01-01
      • 2016-02-28
      相关资源
      最近更新 更多