Android 在操作栏顶部显示视图

Android 在操作栏顶部显示视图,android,view,android-actionbar,z-index,Android,View,Android Actionbar,Z Index,有没有办法在操作栏顶部渲染视图?我想创建一个小提示框,将用户指向操作栏中的项目。我知道带有设置视图的Toast将在操作栏上方呈现。有人知道如何在视图中执行此操作吗 我尝试将FrameLayout与layout\u gravity=“top”一起使用,并将视图放大,然后将其添加到运行活动的布局中 我提前感谢你 编辑: 以下是我当时的想法: 编辑: 也许需要更多的细节。我正在寻找一种方法,或者找出是否有可能将视图添加到活动的视图层次结构中,以便最后呈现它 与CSS类似,我希望此特定视图(图像中的蓝

有没有办法在操作栏顶部渲染视图?我想创建一个小提示框,将用户指向操作栏中的项目。我知道带有设置视图的
Toast
将在操作栏上方呈现。有人知道如何在视图中执行此操作吗

我尝试将
FrameLayout
layout\u gravity=“top”
一起使用,并将视图放大,然后将其添加到运行活动的布局中

我提前感谢你

编辑: 以下是我当时的想法:

编辑: 也许需要更多的细节。我正在寻找一种方法,或者找出是否有可能将视图添加到活动的视图层次结构中,以便最后呈现它


与CSS类似,我希望此特定视图(图像中的蓝色浮动框)具有更高的z索引顺序,以便在“活动”中的操作栏区域顶部进行渲染。视图与操作栏没有任何关联,它只是在上面绘制。

使用menu.xml文件中的
android:actionLayout

<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_id"
      android:title="@string/menu_string_to_show"
      android:icon="@drawable/ic_menu_icon_name"
      android:showAsAction="always"
      android:actionLayout="@layout/action_button_foo" /></menu>

如果:)

尝试使用ActionBar.setCustomView()。这是改变屏幕上该区域外观的唯一方法。您不能将视图粘贴到操作栏“上方”的区域,因为该区域基本上由系统控制。另一方面,您可以为它提供自己的布局

如果你更详细地解释你想做什么,受访者可能会有更好的设计想法

(参考:)
操作栏中的自定义视图 您还可以将自定义视图添加到
操作栏
。为此,您使用
ActionView
类的
setCustomView
方法。您还必须通过传入
ActionBar.display\u SHOW\u custom
标志,通过
setDisplayOptions()
方法启用自定义视图的显示

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

经过一段时间的努力,以下是解决方案(经过测试-效果良好):

一般步骤如下:

  • 创建包装器视图
  • 分离屏幕视图子项,放置包装器,然后附加子项
  • 给孩子们充气
  • 控制包装器将帮助您精确地控制操作栏及其下面的内容
  • 现在,使用包装器,您可以将“兄弟”添加到actionbar/main区域。那兄弟正是你形象中描述的
  • 让我们看一些代码

    首先,创建一个方法来帮助创建包装器视图。包装器将放置在整个屏幕和应用程序内容之间。作为一个用户,您可以在以后完全控制它的内容

    private ViewGroup setContentViewWithWrapper(int resContent) {
            ViewGroup decorView = (ViewGroup) this.getWindow().getDecorView();
            ViewGroup decorChild = (ViewGroup) decorView.getChildAt(0);
    
            // Removing decorChild, we'll add it back soon
            decorView.removeAllViews();
    
            ViewGroup wrapperView = new FrameLayout(this);
    
            // You should set some ID, if you'll want to reference this wrapper in that manner later
            //
            // The ID, such as "R.id.ACTIVITY_LAYOUT_WRAPPER" can be set at a resource file, such as:
            //  <resources xmlns:android="http://schemas.android.com/apk/res/android">
            //      <item type="id" name="ACTIVITY_LAYOUT_WRAPPER"/>
            //  </resources>
            //
            wrapperView.setId(R.id.ACTIVITY_LAYOUT_WRAPPER);
    
            // Now we are rebuilding the DecorView, but this time we 
            // have our wrapper view to stand between the real content and the decor
            decorView.addView(wrapperView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
            wrapperView.addView(decorChild, decorChild.getLayoutParams());
            LayoutInflater.from(this).inflate(getActivityLayout(), 
                        (ViewGroup)((LinearLayout)wrapperView.getChildAt(0)).getChildAt(1), true);
    
            return wrapperView;
        }
    
    就这样

    注释

    • 我曾经理解什么是正确的层次结构。(没有猜到那些
      0
      1
      索引)
    • 如果您在活动中使用某种菜单抽屉,您可能需要对其进行稍微不同的配置,因为抽屉已经在为您创建包装
    • 通过看电影,我学到了很多东西
    编辑:请参阅@CristopherOyarzúnAltamirano答案,以获得对较新Android版本的进一步支持


    祝你好运

    我根据@Sean answer找到了这个解决方法:

            //This is for Jelly, ICS, Honeycomb
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2){
                LayoutInflater.from(this).inflate(resContent, (ViewGroup)((LinearLayout)wrapperView.getChildAt(0)).getChildAt(1), true);}
            //This is for KitKat and Jelly 4.3
            else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
                LayoutInflater.from(this).inflate(resContent, (ViewGroup) (((ViewGroup) wrapperView.getChildAt(0)).getChildAt(0)), true);}
            //This is for Ginger
            else{
                LayoutInflater.from(this).inflate(resContent, (ViewGroup) ((LinearLayout)((FrameLayout) wrapperView.getChildAt(0)).getChildAt(0)).getChildAt(1), true);}
    
    //这是给果冻、ICS和蜂巢的
    if(Build.VERSION.SDK\u INT>=Build.VERSION\u code.Honeycom&&Build.VERSION.SDK\u INT=Build.VERSION\u code.JELLY\u BEAN\u MR2){
    LayoutInflater.from(this).充气(resContent,(ViewGroup)((ViewGroup)wrapperView.getChildAt(0)).getChildAt(0)),true);}
    //这是给金吉尔的
    否则{
    LayoutInflater.from(this).充气(resContent,(ViewGroup)((LinearLayout)((FrameLayout)wrapperView.getChildAt(0)).getChildAt(0)).getChildAt(1),true);}
    
    有一种更简单的方法来实现这一点。ActionBar将其布局保存在ActionBarContainer类中,该类仅继承自FrameLayout。因此,为了在ActionBar上显示某些内容,您需要获取对ActionBarContainer的引用,并将您自己的自定义视图添加到其中。这是密码

        int abContainerViewID = getResources().getIdentifier("action_bar_container", "id", "android");     
        FrameLayout actionBarContainer = (FrameLayout)findViewById(abContainerViewID);      
        LayoutInflater myinflater = getLayoutInflater();        
        View customView = myinflater.inflate(R.layout.yourCustomeViewLayout, null);
        actionBarContainer.addView(customView);
    

    我试图实现其他目标,但我需要类似的解决方案。我需要画一个覆盖整个屏幕的不透明层,甚至是动作栏——有点像一个对话框。我是这样做的:

    ViewGroup vg = (ViewGroup)(getWindow().getDecorView().getRootView());
    vg.addView(myNewView, params);
    
    这可用于在屏幕上的任何位置绘制任何内容

    更新:你真的不应该再使用ActionBar了,如果你像Android推荐的那样使用工具栏,你一开始就不会有这个问题。工具栏将像常规视图一样放在活动xml中,您可以对其执行任何操作。它完全向后兼容。

    请参阅上面的演示,它可能会对您有所帮助

    dialog.setLocation(new location[])//point in screen
    

    您可以自己设置位置[]。

    我找到了一种更简单的方法。 我刚刚将android:translationZ=“10dp”应用到需要覆盖操作栏的视图中

    我选择了10dp,但它实际上可以是任何你想要的,只要它优于actionbar的高度

    
    
    另外,不要担心Android studio的以下警告:


    “translationZ不能与API一起使用这里的解释太长了:


    将主布局文件包装到顶层视图组中(例如,将坐标或布局包装到框架布局中),然后在新的顶层布局中插入或声明视图。视图将显示在操作栏上方。

    感谢您的快速回复!但我相信这是在为操作栏创建菜单项?我只想画一个vi
            //This is for Jelly, ICS, Honeycomb
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2){
                LayoutInflater.from(this).inflate(resContent, (ViewGroup)((LinearLayout)wrapperView.getChildAt(0)).getChildAt(1), true);}
            //This is for KitKat and Jelly 4.3
            else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
                LayoutInflater.from(this).inflate(resContent, (ViewGroup) (((ViewGroup) wrapperView.getChildAt(0)).getChildAt(0)), true);}
            //This is for Ginger
            else{
                LayoutInflater.from(this).inflate(resContent, (ViewGroup) ((LinearLayout)((FrameLayout) wrapperView.getChildAt(0)).getChildAt(0)).getChildAt(1), true);}
    
        int abContainerViewID = getResources().getIdentifier("action_bar_container", "id", "android");     
        FrameLayout actionBarContainer = (FrameLayout)findViewById(abContainerViewID);      
        LayoutInflater myinflater = getLayoutInflater();        
        View customView = myinflater.inflate(R.layout.yourCustomeViewLayout, null);
        actionBarContainer.addView(customView);
    
    ViewGroup vg = (ViewGroup)(getWindow().getDecorView().getRootView());
    vg.addView(myNewView, params);
    
    dialog.setLocation(new location[])//point in screen
    
    <ImageView
          android:layout_width="100dp"
          android:layout_height="100dp"
          android:translationZ="10dp"
          android:src="@drawable/potatoe" />