Как создать прозрачный демонстрационный экран для приложения Android?

Я пытаюсь создать полупрозрачный демонстрационный экран, который запускается только тогда, когда пользователь впервые устанавливает мое приложение. Вот пример из приложения Pulse News:

Galaxy Nexus

Пример снимка экрана из Pulse News на Galaxy Nexus

Nexus One

введите описание изображения здесь

Вместо функции «коснитесь, чтобы закрыть», я хочу, чтобы пользователь мог пролистывать пару таких прозрачных демонстрационных страниц.

Для своей первой попытки я изменил образец из библиотеки ViewPagerIndicator. Я использовал полупрозрачные PNG в ImageViews внутри каждого фрагмента пейджера просмотра. Затем я запустил это как «демонстрационное действие» в методе onCreate моего «основного действия».

Проблема: «Основное действие» не было видно на заднем плане - оно было просто черным. Я попробовал решения здесь, но это не устранило проблему. .

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

У меня также был еще один связанный с этим вопрос, который зависит от того, как это реализовано. Я пытаюсь наложить текст и стрелки так, чтобы они указывали на определенные компоненты пользовательского интерфейса в фоновом режиме. При использовании PNG с текстом и стрелками он, скорее всего, не будет правильно масштабироваться на разных устройствах. То есть стрелки не обязательно указывают на правильный компонент пользовательского интерфейса в фоновом режиме. Есть ли способ решить и эту проблему?

Спасибо!

Вот мой код для первой попытки:

DemoActivity.java

public class DemoActivity extends FragmentActivity {
    DemoFragmentAdapter mAdapter;
    ViewPager mPager;
    PageIndicator mIndicator;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.demo_activity);

        mAdapter = new DemoFragmentAdapter(getSupportFragmentManager());

        mPager = (ViewPager)findViewById(R.id.pager);
        mPager.setAdapter(mAdapter);
        //mPager.setAlpha(0);

        UnderlinePageIndicator indicator = (UnderlinePageIndicator)findViewById(R.id.indicator);
        indicator.setViewPager(mPager);
        indicator.setFades(false);
        mIndicator = indicator;
    }

}

DemoFragmentAdapter.java

class DemoFragmentAdapter extends FragmentPagerAdapter {
    protected static final int[] CONTENT = new int[] { R.drawable.demo1, R.drawable.demo2, R.drawable.demo3, R.drawable.demo4};

    private int mCount = CONTENT.length;

    public DemoFragmentAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        return DemoFragment.newInstance(CONTENT[position % CONTENT.length]);
    }

    @Override
    public int getCount() {
        return mCount;
    }

    public void setCount(int count) {
        if (count > 0 && count <= 10) {
            mCount = count;
            notifyDataSetChanged();
        }
    } }

DemoFragment.java

public final class DemoFragment extends Fragment {
    private static final String KEY_CONTENT = "TestFragment:Content";

    public static DemoFragment newInstance(int content) {
        DemoFragment fragment = new DemoFragment();
        fragment.mContent = content;
        return fragment;
    }

    private int mContent;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if ((savedInstanceState != null) && savedInstanceState.containsKey(KEY_CONTENT)) {
            mContent = savedInstanceState.getInt(KEY_CONTENT);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        ImageView image = new ImageView(getActivity());
        image.setBackgroundResource(mContent);

        LinearLayout layout = new LinearLayout(getActivity());
        layout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
        layout.setGravity(Gravity.CENTER);
        layout.addView(image);

        return layout;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt(KEY_CONTENT, mContent);
    }
}

person Gautam    schedule 17.08.2012    source источник
comment
Не глядя на свой код, сложно что-либо предложить. Если бы вы могли указать свой код активности, это могло бы помочь.   -  person Sayyam    schedule 18.08.2012
comment
Это хороший вопрос.   -  person con_9    schedule 30.08.2012


Ответы (8)


Поместите свою демонстрационную информацию в другое задание и задайте ему следующую тему.

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

Если вы используете ActionBarSherlock, измените parent на @style/Theme.Sherlock.

Это даст вам прозрачное действие, поэтому вы сможете увидеть действие под ним.

Думаю, вам тоже нужен полупрозрачный фон.

В макете xml (вашей прозрачной активности) добавьте:

android:background="#aa000000" 

Последние 6 цифр определяют цвет: 000000 - черный.

Первые 2 определяют непрозрачность: 00 - 100% прозрачность, ff - 100% непрозрачность. Так что выбирайте что-то среднее.

person Benito Bertoli    schedule 30.08.2012
comment
Спасибо за ответ! Это в значительной степени то, чем я закончил после множества методом проб и ошибок. Мне все еще любопытно, как демонстрационный экран Pulse может «перемещать» наложенный контент в нужных местах, даже на экранах разных размеров - см. Обновленные снимки экрана. Любые идеи? - person Gautam; 31.08.2012
comment
В своем первом действии найдите представление, на которое вы хотите указать (findViewById). Затем получите его положение относительно корневого макета, используя этот метод. Отправить позицию для наложения активности в намерении. Сделайте правильное выравнивание. - person Benito Bertoli; 31.08.2012
comment
Или используйте View.getLocationOnScreen(int[] location) или View.getLocationInWindow(int[] location). Я не уверен, какой из них лучше. - person Benito Bertoli; 31.08.2012
comment
@Gautam: Есть идеи? - для Pulse это вопрос размещения одного изображения в верхнем левом углу, другого изображения по центру и третьего изображения в нижнем правом углу. Достаточно примерно дюжины строк XML на основе RelativeLayout. - person CommonsWare; 01.09.2012
comment
Я попробовал тему с обоими родителями с простым действием и SherlockActivity, но они оба отображаются с черным фоном, непрозрачным, и я не вижу активности позади. Любой совет ? И у них обоих был контент с установленным фоном. Я вижу их виджеты, но фон активности просто черный и непрозрачный. - person Snicolas; 01.09.2012
comment
@Snicolas Добавьте тему в свой файл стилей, см. Мой ответ ниже - person powder366; 31.10.2013
comment
‹Style name = Theme.Transparent parent = android: Theme› ‹item name = android: windowIsTranslucent› true ‹/item› ‹имя элемента = android: windowBackground› @android: color / transparent ‹/item› ‹имя элемента = android: windowContentOverlay ›@null ‹/item›‹ имя элемента = android: windowNoTitle ›true ‹/item›‹ имя элемента = android: windowIsFloating ›false ‹/item›‹ имя элемента = android: backgroundDimEnabled ›false ‹/item›‹ / style › - person powder366; 01.11.2013
comment
это лучшее решение, чтобы не добавлять библиотеки и не усложнять вашу текущую деятельность слишком сильно. +1. - person rupps; 01.04.2014
comment
Это сработало для меня, но у меня были проблемы с расширением Activity. Итак, чтобы использовать AppCompatActivity, я определил стиль следующим образом: ‹style name = Transparent parent = Theme.AppCompat› ‹item name = android: windowContentOverlay› @null ‹/item› ‹имя элемента = android: windowIsTranslucent› true ‹/ item ›‹ Имя элемента = android: windowBackground ›@android: color / transparent ‹/item›‹ имя элемента = android: windowNoTitle ›true ‹/item›‹ имя элемента = android: backgroundDimEnabled ›false ‹/item› ‹/style› - person Jose Q; 01.02.2019

Вы смотрели ShowcaseView? https://github.com/Espiandev/ShowcaseView.

Используя это:

View showcasedView = findViewById(R.id.view_to_showcase);
ViewTarget target = new ViewTarget(showcasedView);
ShowcaseView.insertShowcaseView(target, this, R.string.showcase_title, R.string.showcase_details);
person Nik    schedule 04.09.2012
comment
Спасибо, это именно то, что я искал. - person Snicolas; 04.09.2012
comment
Потрясающий! Вы знаете что-нибудь подобное для iOS? - person KVISH; 19.02.2014
comment
Еще не рекомендуется ... Разработчик имел в виду, что дизайн базового API был недостаточно хорош (что частично было правдой). - person Laurent Meyer; 05.09.2015
comment
Я попробовал это и обнаружил, что нет тега для изменения изображений. - person Anshul Tyagi; 29.03.2016

Pulse использует RelativeLayout с четырьмя ImageView и четырьмя TextView. Текст на снимке экрана - это все TextView со своим собственным шрифтом.

В своем манифесте добавьте к своей деятельности следующее:

android: theme = "@ style / Theme.Transparent">

Во внешний RelativeLayout добавьте:

android: background = "# aa000000"

В ваш файл styles.xml:

<style name="Theme.Transparent" parent="android:Theme">
    <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:windowIsFloating">false</item>
    <item name="android:backgroundDimEnabled">false</item>
</style>    

Пример программирования собственного шрифта можно найти по адресу:

https://github.com/commonsguy/cw-android/tree/master/Fonts/FontSampler/

Макет из средства просмотра иерархии выглядит следующим образом (красный прямоугольник - это контейнер RelativeLayout):

введите описание изображения здесь

person powder366    schedule 11.11.2012

Для этого вам нужно создать макет справки внизу основного макета, например: (структура)

<Parent layout>

<Layout 1>(Linear,Relative,....)
  Main layout
  your view...
</Layout 1>

<Layout help>
  set #70000000 as background of this layout 
  #70(transparent range can change) 000000(black)
  and height and width as fillparent
</Layout help>

</Parent layout>
person Surendar D    schedule 31.07.2015

Оберните свой основной макет в RelativeLayout, затем добавьте к нему второй макет, например:

<RelativeLayout
    .... >

    <LinearLayout
        .... >

        <!-- Contents of your main layout -->

    </LinearLayout>

    <LinearLayout
        ....
        android:background="#44000000" > <!-- This is alpha 68/255, black -->

        <!-- Contents of your overlay layout -->

    </LinearLayout>

</RelativeLayout>

Я считаю, что макет наложения располагается ниже основного макета в XML-файле (если не изменяет память). Затем вы можете создать свой собственный макет, ViewFlipper, что угодно во втором макете.

person Eric    schedule 17.08.2012
comment
Спасибо за ваш ответ! Я пробовал это, и, похоже, это сработало. Однако есть одна проблема - содержимое в макете наложения не закрывает ActionBar или вкладки ActionBar, которые у меня есть в моем действии. - person Gautam; 18.08.2012
comment
Вы добавили RelativeLayout в demo_activity.xml файл? И DemoActivity ваш главный (первый) Activity? - person Eric; 18.08.2012
comment
Что ж, «DemoActivity» была моей попыткой создать прозрачное действие, которое делало бы то же самое. «MainActivity» - это активность, которую я хочу выполнять в фоновом режиме. Итак, я обернул макет для MainActivity, то есть main_activity.xml, с помощью RelativeLayout, как вы упомянули, а также вставил прозрачный LinearLayout. Проблема в том, что все содержимое main_activity.xml отображается под панелью ActionBar и любой из ее вкладок навигации. - person Gautam; 18.08.2012

Создайте новое действие (скажем, Учебное пособие).

Перейдите в XML-файл макета вашей деятельности (activity_tutorial). Под родительским макетом добавьте android: background = # 000 и android: alpha = "0.5".

<RelativeLayout 
    
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
                
                
    tools:context=".Tutorial_Activity" 
    android:background="#000"
    android:alpha="0.5">
  ..................................................
  ....................................................
  .............................................
  ...............................................
  
  </RelativeLayout>

Теперь перейдите в файл манифеста приложения и в разделе учебного курса добавьте атрибут android: theme = "@ android: style / Theme.Translucent.NoTitleBar">

<application>
 .........................................
..........................................
....................................
..........................................

<activity
            android:name="com.aird.airdictionary.Tutorial_Activity"
            android:label="@string/title_activity_tutorial"
            
          android:theme="@android:style/Theme.Translucent.NoTitleBar">
  
        </activity>
    </application>

</manifest>

Вот и все, теперь запустите это действие поверх любого другого, и вы можете получить желаемые результаты. Настройте, добавьте текст, просмотры изображений и другие вещи, чтобы получить желаемый экран учебника. Совершенно уверен, что вы можете заставить работать просмотрщик с помощью этой техники.

person Ankush Wadhwa    schedule 28.12.2014

Вы можете просто проверить код запуска Android, как они это делают. Не знаю там реализации.

Если бы это был я, я бы (если бы просто наложение), чтобы вы не ошиблись с макетом для своего приложения, просто создайте макет наложения и прикрепите его к макету вашего приложения, добавив его непосредственно в свои действия WindowManager. Это может быть так же просто, как добавить ImageView к WindowManager, прислушаться к прикосновениям к ImageView или иметь тайм-аут, чтобы удалить ImageView из вашего Window.

person Jug6ernaut    schedule 17.08.2012

person    schedule
comment
именно то, что я ищу, простой и понятный и легкий вызов метода без управления или складывания действий. Благодарность - person Abhishek Garg; 04.12.2018