显示视图上的行动栏

有没有办法在操作栏顶部显示视图? 我想创build一个小的提示框,将用户指向操作栏中的项目。 我知道,具有设置视图的Toast将被呈现在操作栏上方。 有谁知道如何做到这一点的观点?

我已经尝试使用layout_gravity="top" FrameLayout和膨胀一个视图,然后将其添加到正在运行的活动的布局。

我提前感激你。

编辑 :这是我在想什么的形象: 在这里输入图像说明

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

与CSS类似,我想为此特定视图(图像中的蓝色浮动框)提供更高的Z-index顺序,以便它将呈现在活动的操作栏区域之上。 这个视图与Action Bar没有任何关系,它只是简单的绘制在上面。

经过相当长时间的努力之后,这里是解决scheme(testing它 – 工作良好):

一般步骤是:

  1. 创build一个包装视图
  2. 分离屏幕查看儿童,放置包装,并附上孩子
  3. 将内容膨胀给孩子们
  4. 控制包装将帮助您精确控制操作栏和下面的所有内容。
  5. 现在,使用包装器,你可以添加“兄弟”到操作栏/主区域。 那个哥哥就是你形象中所描述的。

让我们看看一些代码。

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

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

现在,干扰常规的Activity创build,而不是使用setContentView ,使用我们创build的方法。

  @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // DON'T CALL `setContentView`, // we are replacing that line with this code: ViewGroup wrapperView = setContentViewWithWrapper(R.layout.activity_layout); // Now, because the wrapper view contains the entire screen (including the notification bar // which is above the ActionBar) I think you'll find it useful to know the exact Y where the // action bar is located. // You can use something like that: ViewGroup actionBar = (ViewGroup)((LinearLayout)wrapperView.getChildAt(0)).getChildAt(0); int topOffset = actionBar.getTop(); // Now, if you'll want to add a view: // 1. Create new view // 2. Set padding top - use "topOffset" // 3. Add the view to "wrapperView" // 4. The view should be set at front. if not - try calling to "bringToFront()" } 

就是这样。

笔记

  • 我使用Android的层次结构查看器来了解什么是正确的层次结构。 (没有猜测那些01索引)
  • 如果您在活动中使用某种菜单抽屉,则可能必须对其进行configuration,因为抽屉已经为您创build了包装
  • 通过看这个伟大的图书馆,我学到了很多东西

编辑:参考@CristopherOyarzúnAltamirano答案更新的Android版本的进一步支持

祝你好运!

我试图实现其他的东西,但我需要类似这样的解决scheme。 我需要绘制一个覆盖整个屏幕的不透明层,甚至是操作栏 – 就像一个对话框。 我这样做了:

 ViewGroup vg = (ViewGroup)(getWindow().getDecorView().getRootView()); vg.addView(myNewView, params); 

这可以用来在屏幕上的任何地方绘制任何东西。

有一个更简单的方法来实现这一点。 ActionBar将其布局保存在仅从FrameLayoutinheritance的ActionBarContainer类中。 所以为了在ActionBar上显示一些东西,你需要获取对ActionBarContainer的引用,并添加你自己的自定义View。 这是代码

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

我发现这个解决方法基于@Sean的答案:

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

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

如果你更详细地解释你想要做什么,受访者可能会有一些更好的devise思路。

https://github.com/michaelye/EasyDialogDemo

看到上面的演示,它可能会帮助你

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

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

我发现了一个更简单的方法来做到这一点。 我只是应用android:translationZ =“10dp”的视图,我需要覆盖的操作栏。

我select了10dp,但实际上它可以是任何你想要的,只要它比操作栏的高程更好

 <ImageView android:layout_width="100dp" android:layout_height="100dp" android:translationZ="10dp" android:src="@drawable/potatoe" /> 

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

“translationZ不能与API <21”一起使用。

它将被忽略,但是你并不关心,因为工具栏不应该用API低于21来覆盖你的视图。

在你的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> 

然后创build你的action_button_foo.xml布局:

 <?xml version="1.0" encoding="utf-8"?><TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="@string/menu_string_to_show" android:drawableLeft="@drawable/ic_menu_icon_name" android:background="@drawable/bg_btn_action_bar" android:clickable="true" /> 

要处理点击,请执行以下操作:

 @Overridepublic boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.my_menu, menu); final MenuItem item = menu.findItem(R.id.menu_id); item.getActionView().setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { onOptionsItemSelected(item); } }); return super.onCreateOptionsMenu(menu);} 

那就是如果:)

(参考: http : //www.vogella.com/articles/AndroidActionBar/article.html )
ActionBar自定义视图
您也可以添加一个自定义的视图到ActionBar 。 为此,您可以使用ActionView类的setCustomView方法。 您还必须通过传递ActionBar.DISPLAY_SHOW_CUSTOM标志来通过setDisplayOptions()方法启用自定义视图的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 。 示例代码允许将侦听器附加到自定义视图。

 package com.vogella.android.actionbar.customviews; import android.app.ActionBar; import android.app.Activity; import android.os.Bundle; import android.view.KeyEvent; import android.widget.EditText; import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; import android.widget.Toast; 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); } }