Отображение в верхней части панели действий

Есть ли способ сделать вид сверху панели действий? Я хочу создать небольшой наконечник, который указывает пользователю на элемент в панели действий. Я знаю, что над панелью действий будет отображаться Toast с заданным представлением. Кто-нибудь знает, как это сделать с точки зрения?

Я попытался использовать FrameLayout с layout_gravity="top" и раздуть представление, а затем добавить его в макет текущей работы.

Я ценю вас заранее.

Редактировать : Вот образ того, что я думал: Введите описание изображения здесь

Изменить : Возможно, требуется более подробная информация. Я ищу способ или выяснить, возможно ли даже добавить представление в иерархию представления активности, чтобы она была последней.

Подобно CSS, я хочу получить более высокий порядок z-index для этого конкретного вида (синий плавающий ящик на изображении), так что он будет отображаться поверх области Action Bar в действии. Представление никоим образом не связано с панелью действий, оно просто нарисовано поверх него.

Solutions Collecting From Web of "Отображение в верхней части панели действий"

После того, как я боролся с этим сам довольно долго, вот решение (проверено – работает хорошо):

Общие шаги:

  1. Создание представления обертки
  2. Отсоедините экран просмотра детей, поместите обертку и присоедините детей
  3. Надуйте контент детям
  4. Управление оболочкой поможет вам точно контролировать панель действий и содержимое под ним все вместе.
  5. Теперь, используя обертку, вы можете добавить «братья» в панель действий / главную область. Этот брат – это то, что вы описали в своем образе.

Посмотрим на код.

Во-первых, создайте метод, который поможет создать представление оболочки. Оболочка будет размещена между всем экраном и содержимым вашего приложения. Будучи 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; } 

Теперь помешайте регулярному созданию активности , а вместо использования setContentView используйте метод, который мы создали.

  @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 для понимания правильной иерархии. (Не угадали эти 0 и 1 индексы)
  • Если вы используете какой-либо ящик меню в своей деятельности, вам может потребоваться настроить его немного иначе, поскольку ящики уже создают эту оболочку для вас
  • Я многому научился, посмотрев на эту великую библиотеку

EDIT: обратитесь к @ CristopherOyarzúnAltamirano Ответ для дальнейшей поддержки в новых версиях Android

Удачи!

Я пытался добиться чего-то еще, но мне было нужно решение, подобное этому. Мне нужно было нарисовать непрозрачный слой, покрывающий весь экран, даже панель действий – вроде как диалог. Я сделал так:

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

Это можно использовать для рисования чего угодно на экране.

Существует гораздо более простой способ достичь этого. ActionBar сохраняет свой макет в классе ActionBarContainer, который просто наследуется от FrameLayout. Поэтому, чтобы отобразить что-то над 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, потому что эта область в основном контролируется системой. С другой стороны, вы можете предоставить свой собственный макет.

Если вы более подробно объясните, что вы пытаетесь сделать, у респондентов могут быть несколько лучших дизайнерских идей.

https://github.com/michaelye/EasyDialogDemo

См. Демонстрацию выше, это может помочь вам

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

Вы можете установить местоположение [] самостоятельно.

Я нашел гораздо более простой способ сделать это. Я просто применил android: translationZ = "10dp" к представлению, которое мне нужно покрыть панель действий.

Я выбрал 10dp, но на самом деле это может быть все, что вы хотите, если оно превосходит высоту панели действий

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

Кроме того, не беспокойтесь о следующем предупреждении студии Android:

«TranslationZ нельзя использовать с API <21».

Он будет проигнорирован, но вам все равно, потому что панель инструментов не должна покрывать ваше представление API-интерфейсом ниже 21.

Используйте файл android:actionLayout в файле menu.xml.

 <?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> 

Затем создайте свой макет 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 . Для этого вы используете метод setCustomView для класса ActionView . Вы также должны включить отображение пользовательских представлений с помощью setDisplayOptions() , передав флаг ActionBar.DISPLAY_SHOW_CUSTOM .

Например, вы можете определить файл макета, который содержит элемент 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); } }