Подтвердить что ты не робот

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

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

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

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

Edit: Вот образ того, что я думал: enter image description here

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

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

4b9b3361

Ответ 1

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

Общие шаги:

  • Создать представление оболочки
  • Отсоедините дочерние элементы экрана, поместите обертку и прикрепите дочерние элементы
  • Нажать содержимое детям
  • Управление оболочкой поможет вам точно контролировать панель действий и содержимое под ним все вместе.
  • Теперь, используя обертку, вы можете добавить "братья" в панель действий/главную область. Этот брат - это то, что вы описали в своем образе.

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

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

РЕДАКТИРОВАТЬ: Обратитесь к @CristopherOyarzúnAltamirano Ответ для дальнейшей поддержки в новых версиях Android

Удачи!

Ответ 2

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

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

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

Ответ 3

Существует гораздо более простой способ добиться этого. 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);

Ответ 4

Я нашел это обходное решение на основе ответа @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);}

Ответ 5

Попробуйте использовать ActionBar.setCustomView(). Это единственный способ изменить внешний вид этой области экрана. Вы не можете вставить "Вид" в область "выше" ActionBar, потому что эта область в основном контролируется системой. С другой стороны, вы можете предоставить свой собственный макет для него.

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

Ответ 6

https://github.com/michaelye/EasyDialogDemo

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

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

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

Ответ 7

Я нашел гораздо более простой способ сделать это. Я просто применил 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.

Ответ 8

Используйте 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);}

Что если:)

Ответ 9

(Ссылка: 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);
}
}