在操作栏上方显示视图视图、栏上、操作

2023-09-12 01:41:28 作者:甜甜的吻

有没有办法呈现在操作栏上方的看法?我想创建一个小的提示框,将指向用户的项目在操作栏。我知道,一个吐司一组视图将上面的动作条中呈现。有谁知道如何以期做到这一点?

Is there a way to render a view on top of the action bar? I want to create a small tip box that will point the user to an item in the action bar. I know that a Toast with a set view will be rendered above the action bar. Does anyone know how to do this with a view?

我用的FrameLayout layout_gravity =顶和充气一个视图,然后将其添加到已尝试运行活动的布局。

I have attempted using FrameLayout with layout_gravity="top" and inflating a view and then adding it to the running activity's layout.

在事先我AP preciate你。

I appreciate you in advance.

修改: 下面是我在想什么图像:

Edit: Here is an image of what I was thinking:

修改: 也许一些细节是必要的。我在寻找一种方式,或者找出如果它甚至可以将视图添加到使得其最后呈现活动的视图层次。

Edit: Perhaps some more detail is needed. I am looking for a way, or to find out if it is even possible to add a view to the view hierarchy of the activity so that it is rendered last.

类似的CSS,我想更高z索引顺序对这个特定视图(图像中的蓝色浮动框),使得其将在在活动操作栏区域的顶部被渲染。该视图中没有与操作栏相关联的方式,那简直是绘制在它的上面。

Similar to CSS, I want a higher z-index order for this particular view ( the blue floating box in the image), such that it would be rendered on top of the Action Bar region in the activity. The view is in no way associated with Action Bar, it is simply drawn on top of it.

推荐答案

与它自己挣扎了一段时间后,这里的解决方案(测试了它 - 工作好):

After struggling with it myself quite some time, here's the solution (tested it - working good):

的一般步骤是:

创建一个包装视图 拆下屏幕视图的孩子,将包装,并附上孩子 充气的内容给孩子 控制,使其包装会帮助你精确控制操作栏和它下面的所有内容一起。 现在,使用的包装,你可以添加兄弟的动作条/主要区域。这兄弟正是你在你的形象描述了。

让我们来看看一些code。

Let's see some code.

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

First, create a method to help create a wrapper view. the wrapper will be placed between the entire screen and the content of your app. being a ViewGroup you can later on fully control it's content.

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,使用我们已经创建的方法。

Now, interfere with the regular Activity creation, and instead of using setContentView, use the method we've created.

    @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 索引) 如果您使用的是某种在你的活动菜单抽屉,您可能需要对其进行配置有点不同,因为抽屉已经创建的包装为你 在我通过看这个伟大的图书馆 学到了很多 I've used Android's hierarchy-viewer to understand what's the right hierarchy. (didn't guess those 0 and 1 indexes) If you are using some kind of a menu drawer in your activity, you might have to configure it a little bit different since drawers are already creating that wrapper for you I've learned a lot by looking at this great library

编辑:请参阅@CristopherOyarzúnAltamirano答案较新的Andr​​oid版本还支持

Refer to @CristopherOyarzúnAltamirano Answer for further support on newer Android versions

祝你好运!