我如何创建一个帮助叠加层,就像您在一些Android应用程序和ICS中看到的那样?


93

我想创建帮助叠加层,例如您首次加载ICS时看到的叠加层,或在ES File Explorer或Apex Launcher等应用程序中看到的叠加层(还有更多,但我现在想不起来)。这只是一个相对视图,一个视图位于另一个视图之上吗?我还没有找到执行此操作的任何示例代码。有谁知道这是怎么做的或有什么想法?

ES文件浏览器 ES文件浏览器

Answers:


84

假设您通常会调用setContentView(R.layout.main),但是在第一次运行时,您希望具有此覆盖。

步骤#1:创建一个FrameLayoutJava代码并将其传递给setContentView()

第2步:使用LayoutInflater膨胀R.layout.mainFrameLayout

步骤#3:用于LayoutInflater将叠加层充气到中FrameLayout

步骤#4:当用户点击按钮(或其他按钮)以关闭叠加层时,请致电removeView()从中删除叠加层FrameLayout

由于叠加层是的后继子层FrameLayout,因此它将浮动在内容的顶部R.layout.main


6
@ ssuperz28:是的,除了手绘箭头和气泡。这些都是您自己的。:-)
CommonsWare

我不知道您是否能按自己的意愿去做,但这是另一种选择。 stackoverflow.com/questions/8841240/… 如果您使用CommonsWare给出的解决方案,为了设置箭头,发生在我身上的唯一一件事情就是定义带有ResourceImage或backgroundImage的指令的FrameLayout和已经带有箭头的图像(和透明度)。
Edison Santos

1
有没有办法做到这一点,但要相对于FrameLayout下方的儿童位置进行呢?
4gus71n 2013年

@CommonsWare-先生,无论使用哪种设备,它都可以工作?
Rat-a-t-a-tat Ratatouille 2014年

2
@ user3364963:动态调整事物的位置。我的回答有些简化。我假设它们确定了要突出显示的元素的位置,并调整了“教练标记”的坐标。ViewGroup“教练标记”层的自定义可以处理该问题,并且有一些库(例如ShowcaseView)提供了该模式的固定实现。
CommonsWare,2014年

80

在UX对话中,“教练标记”是“帮助叠加” :-)

coach_mark.xml是您的教练标记布局

coach_mark_master_viewcoach_mark.xml中最顶层视图(根)的ID

public void onCoachMark(){

    final Dialog dialog = new Dialog(this);
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
    dialog.setContentView(R.layout.coach_mark);
    dialog.setCanceledOnTouchOutside(true);
    //for dismissing anywhere you touch
    View masterView = dialog.findViewById(R.id.coach_mark_master_view);
    masterView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            dialog.dismiss();
        }
    });
    dialog.show();
}

添加coach_mark.xml的样本(到由Oded Breiner提供的出色解决方案中),因此ppl易于复制和粘贴以快速查看工作示例。

这里的coach_mark.xml样本,将-> drawable / coach_marks更改为您的图像:

coach_mark.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:id="@+id/coach_mark_master_view">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
         <ImageView
             android:id="@+id/coach_marks_image"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:layout_centerInParent="true"
             android:layout_gravity="center_horizontal"
             android:src="@drawable/coach_marks" />
    </RelativeLayout>
</LinearLayout>

并且可以选择使用此主题来删除填充:

<style name="WalkthroughTheme" parent="Theme.AppCompat">
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:backgroundDimEnabled">false</item>
</style>

您好,如何拉伸此对话框以匹配屏幕?在文档中,A dialog is a small window that prompts [...]. A dialog does not fill the screen and is normally used for modal events [...].。如果使用此代码,则会在屏幕的一小部分中压缩我的主视图。如果我设置了android:layout_width="640dp" android:layout_height="480dp"(即我正在测试的屏幕的实际值),则它可以正常工作。(当然,这不是可行的解决方案)
ocramot

@ocramot:由于match_parent和Window.FEATURE_NO_TITLE
Oded Breiner

然后肯定还有其他问题,因为我以不同的方式看待它
ocramot

1
我知道这至少有几个月的历史了,但是这个全屏问题有没有解决?
cbhedd

3
对于那些不知道如何设置对话框主题的用户,只需实例化该对话框,如下所示:new Dialog(getContext(), R.style.WalkthroughTheme);
w3bshark 2015年

4

您可以很快完成。例如,您添加了LinearLayout,在其中放置了带有Alpha的图片,该图片与您的帮助信息以及要像覆盖层一样绘制的内容相对应。在您的活动xml中,将此活动放置在具有Gone可见性的活动布局之后,将该布局放入RelativeLayout中。当您想绘制帮助信息时,您只需要将此可见性设置为visible。

希望我很清楚,如果您有任何问题,请回答。


感谢您的输入。这就是我想象的过程。我必须归功于下面的答案,因为那是我要构建它的方式。似乎更易于管理,我不必更改我的主要活动布局。
ssuperz28'2013-4-18

1

请参阅我的另一个答案,如何以编程方式在当前活动的顶部显示覆盖布局。活动的layout.xml不需要了解有关覆盖皮肤的任何信息。您可以将覆盖层设置为半透明,仅覆盖部分屏幕,一个或多个textview以及其上的按钮... 如何以编程方式覆盖按钮?

  • 创建res / layout / paused.xml RelativeLayout模板或使用顶层任何布局
  • 创建一个功能来显示覆盖皮肤
  • 关键是获取layout.xml的句柄,使用LayoutInflater类解析xml以查看对象,将叠加视图添加到当前布局结构
  • 我的示例使用计时器通过从视图结构中完全删除覆盖对象来销毁覆盖对象。这可能也是您想要完全摆脱它的原因。

我的目标是主要活动不了解任何叠加层皮肤,叠加层来去去去,许多不同的叠加层,仍然能够使用overlay1.xml文本文件作为模板,并且应该以编程方式更新内容。我做了CommonsWare告诉我们的几乎所有事情,我的帖子显示了开始的实际程序代码。

免责声明:OPs:“谢谢您的输入。这是我想象的完成方式。我必须赞扬下面的答案”评论不是我的答案,而是CommonsWare的答案。Stackoverflow更改了后顺序。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.