Как создать наложение справки, как в некоторых приложениях для Android и ICS?

93

Я хочу создать наложения справки, подобные тем, которые вы видите при первой загрузке ICS, или в таких приложениях, как ES File Explorer или Apex Launcher (их гораздо больше, но я не могу вспомнить их прямо сейчас). Это просто относительный макет, в котором один вид находится поверх другого? Мне не удалось найти образец кода для этого. Кто-нибудь знает, как это делается, или есть идеи?

ES проводник ES проводник

ssuperz28
источник

Ответы:

84

Предположим, вы обычно звоните setContentView(R.layout.main), но при первом запуске вы хотите получить этот оверлей.

Шаг №1: Создайте FrameLayoutкод на Java и передайте его в setContentView().

Шаг № 2: Используйте, LayoutInflaterчтобы надуть R.layout.mainв FrameLayout.

Шаг № 3: Используйте, LayoutInflaterчтобы надуть оверлей в FrameLayout.

Шаг №4: Когда пользователь нажимает кнопку (или что-то еще), чтобы закрыть оверлей, вызовите его, removeView()чтобы удалить оверлей из FrameLayout.

Поскольку оверлей является более поздним дочерним элементом FrameLayout, он будет плавать поверх содержимого R.layout.main.

CommonsWare
источник
6
@ ssuperz28: Да, ну, кроме нарисованных от руки стрелок и пузыря. Вы сами по себе. :-)
CommonsWare
Не знаю, удалось ли вам сделать то, что вы хотели, но есть еще одна альтернатива. stackoverflow.com/questions/8841240/… Если вы используете решение, данное CommonsWare, единственное, что мне приходит в голову, чтобы установить стрелки, - это определить FrameLayout инструкций с помощью resourceImage или backgroundImage уже с изображением со стрелками (и прозрачность).
Эдисон Сантос
1
Есть ли способ сделать это, но делать это относительно положения детей, которые находятся ниже от FrameLayout?
4gus71n 03
@CommonsWare - сэр, это будет работать независимо от того, какое это устройство?
Rat-a-tat-a-tat Ratatouille
2
@ user3364963: динамически корректировать положение вещей. Мой ответ был несколько упрощен. Я предполагаю, что они определяют положение выделяемых элементов и корректируют координаты «следов тренеров». С ViewGroupэтим может справиться обычай для слоя «тренерские отметки», и есть библиотеки (например, ShowcaseView), которые предлагают стандартные реализации этого шаблона.
CommonsWare
80

«Метка тренера» - это «Оверлей справки» в UX talk :-)

coach_mark.xml - это макет вашей марки тренера

coach_mark_master_view - это идентификатор самого верхнего просмотра (корневого) в файле coach_mark.xml.

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 (к этому отличному решению, предоставленному Одедом Брейнером), чтобы пользователь мог легко скопировать и вставить, чтобы быстро увидеть рабочий пример.

Здесь, например, здесь, в файле 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
Одед Брейнер
Тогда должна быть какая-то другая проблема, потому что я вижу это по-другому
ocramot
1
Я знаю, что этому как минимум несколько месяцев, но удалось ли когда-нибудь решить этот полноэкранный вопрос?
cbhedd
3
Для тех, кто не знает, как задать тему диалога, просто new Dialog(getContext(), R.style.WalkthroughTheme);
создайте
4

Вы можете сделать это довольно быстро. Вы добавляете, например, LinearLayout, где вы помещаете изображение с альфа-каналом, которое соответствует вашей справочной информации и тому, что вы хотите нарисовать как наложение. В XML-файле своей деятельности вы помещаете этот макет в RelativeLayout после макета вашей активности с видимостью Gone. Если вы хотите нарисовать справочную информацию, вам просто нужно сделать эту видимость видимой.

Надеюсь, мне понятно, если у вас есть какие-либо вопросы, я буду рад на них ответить.

FUBU
источник
Спасибо за ваш вклад. Вот как я это представлял. Я должен отдать должное приведенному ниже ответу, поскольку именно так я собираюсь его построить. Это кажется более управляемым, и мне не нужно менять схему основной деятельности.
ssuperz28
1

См. Мой другой ответ, как программно показать макет наложения поверх текущего действия. Макет действия layout.xml не должен ничего знать о обложке. Вы можете наложить полупрозрачный оверлей, закрыть только часть экрана, одно или несколько текстовых окон и кнопок на нем ... Как программно наложить кнопку?

  • создать шаблон res / layout / paused.xml RelativeLayout или использовать любой макет верхнего уровня
  • создать функцию для отображения наложения кожи
  • ключ - получить дескриптор layout.xml, использовать класс LayoutInflater для синтаксического анализа xml для просмотра объекта, добавить представление наложения в текущую структуру макета
  • В моем примере таймер уничтожает объект наложения, полностью удаляя его из структуры представления. Вероятно, это то, что вы хотите, чтобы избавиться от него бесследно.

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

отказ от ответственности: OPs «Спасибо за ваш вклад. Вот как я себе это представлял. Я должен отдать должное приведенному ниже ответу». Комментарий не означает мой ответ, а ответ CommonsWare. Stackoverflow изменил порядок публикаций.

Кто
источник