Bir Android uygulaması için şeffaf bir demo ekranı nasıl oluşturursunuz?


105

Yalnızca bir kullanıcı uygulamamı ilk kez yüklediğinde başlatılan yarı şeffaf bir demo ekranı oluşturmaya çalışıyorum. İşte Pulse News uygulamasından bir örnek:

Galaxy Nexus

Galaxy Nexus'ta Pulse News'den örnek ekran görüntüsü

Nexus One

görüntü açıklamasını buraya girin

'Atlamak için dokun' özelliği yerine, kullanıcının bu tür şeffaf demo sayfalarından birkaçını kaydırabilmesini istiyorum.

İlk denemem için ViewPagerIndicator kitaplığından bir örneği değiştirdim . Görüntü sayfalayıcısının her bir parçasının içinde ImageViews'ta yarı saydam PNG'ler kullandım. Daha sonra bunu 'ana etkinliğimin' onCreate yönteminde bir 'demo etkinliği' olarak başlattım.

Problem: 'Ana aktivite' arka planda görülemiyordu - bunun yerine sadece siyahtı. Buradaki çözümleri denedim ama bu sorunu çözmedi.

Böyle bir şey yaratmak için daha iyi bir yaklaşım var mı yoksa doğru yolda mıyım?

Bunun nasıl uygulandığına bağlı başka bir ilgili sorum da vardı. Metin ve okları arka planda belirli UI bileşenlerini gösterecek şekilde yerleştirmeye çalışıyorum. Metin ve oklar içeren bir PNG kullanarak, farklı cihazlarda doğru şekilde ölçeklenmeyebilir. Yani, oklar arka planda mutlaka doğru UI bileşenini göstermeyebilir. Bu sorunu da çözmenin bir yolu var mı?

Teşekkürler!

İşte ilk deneme için kodum:

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);
    }
}

Kodunuza bakmadan bir şey önermek zordur. Aktivite kodunu girebilirsen yardımcı olabilir.
Sayyam

11
bu iyi bir soru.
con_9

Yanıtlar:


79

Demo bilgilerinizi farklı bir aktiviteye koyun ve ona aşağıdaki temayı verin.

<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>

Eğer ActionBarSherlock değişikliği kullanıyorsanız parentiçin @style/Theme.Sherlock.

Bu size şeffaf bir aktivite verecektir, böylece altındaki faaliyeti görebileceksiniz.

Şimdi de saydam bir arka plan istediğinizi tahmin ediyorum.

Xml düzeninde (şeffaf etkinliğinizin) şunu ekleyin:

android:background="#aa000000" 

Son 6 hane rengi tanımlar: 000000 siyahtır.

İlk 2, opaklığı tanımlar: 00% 100 şeffaftır, ff% 100 opaktır. Bu yüzden ikisinin arasında bir şey seçin.


1
Cevap için teşekkürler! Pek çok deneme yanılmadan sonra yaptığım şey buydu . Pulse demo ekranının, farklı ekran boyutlarında bile üst üste bindirilmiş içeriği doğru yerlerde nasıl 'yeniden konumlandırabildiğini' hala merak ediyorum - güncellenmiş ekran görüntülerine bakın. Herhangi bir fikir?
Gautam

2
İlk etkinliğinizde ( findViewById) işaret etmek istediğiniz görünümü bulun . Ardından, bu yöntemi kullanarak kök düzenine göre konumunu alın . Amaçtaki bindirme etkinliğine pozisyon gönderin. Doğru hizalamayı yapın.
Benito Bertoli

2
Veya View.getLocationOnScreen(int[] location)veya kullanın View.getLocationInWindow(int[] location). Hangisinin daha iyi olduğundan emin değilim.
Benito Bertoli

@Gautam: "Herhangi bir fikrin var mı?" - Pulse için bu, bir resmi sol üst köşeye, başka bir resmi ortalayarak ve üçüncü bir resmi sağ alt köşeye yerleştirme meselesidir. A'ya dayalı bir düzine XML satırı RelativeLayoutyeterli olacaktır.
CommonsWare

1
Bu benim için çalıştı, ancak faaliyetlerimi genişleterek etkinliklerimde sorunlar yaşadım. Bu yüzden AppCompatActivity'yi kullanmak için stili şu şekilde tanımladım: <style name = "Transparent" parent = "Theme.AppCompat"> <item name = "android: windowContentOverlay"> @ null </item> <item name = "android : windowIsTranslucent "> doğru </item> <item name =" android: windowBackground "> @ android: color / transparent </item> <item name =" android: windowNoTitle "> doğru </item> <item name =" android : backgroundDimEnabled "> yanlış </item> </style>
Jose Q

65

ShowcaseView'a baktınız mı? https://github.com/Espiandev/ShowcaseView .

Bunu kullanarak:

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);

1
Teşekkürler, tam olarak aradığım buydu.
Snicolas

Harika! İOS için benzer bir şey biliyor musunuz?
KVISH

Henüz kullanımdan kaldırıldı ... Geliştirici, temel API tasarımının yeterince iyi olmadığı anlamına geliyordu (bu kısmen doğruydu).
Laurent Meyer

Bunu denedim ve resimleri değiştirecek bir etiket olmadığını buldum.
Anshul Tyagi

11

Pulse, dört ImageView ve dört TextView ile bir RelativeLayout kullanıyor. Ekran görüntüsündeki metin, kendi özel yazı tipine sahip tüm TextView'lardır.

Manifest'inize aşağıdakileri Faaliyetinize ekleyin:

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

Dış RelativeLayout'unuza şunu ekleyin:

android: background = "# aa000000"

Styles.xml dosyanıza:

<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>    

Özel yazı tipinin nasıl programlanacağına bir örnek şurada bulabilirsiniz:

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

Hierarchy Viewer'daki düzen şuna benzer (kırmızı kutu RelativeLayout kapsayıcısıdır):

görüntü açıklamasını buraya girin


6
setContentView(R.layout.sample_main);
showOverLay();

private void showOverLay(){

    final Dialog dialog = new Dialog(context, android.R.style.Theme_Translucent_NoTitleBar);

    dialog.setContentView(R.layout.transparent);

    RelativeLayout layout = (RelativeLayout) dialog.findViewById(R.id.transparent);

    layout.setOnClickListener(new View.OnClickListener() {

        @Override

        public void onClick(View arg0) {

            dialog.dismiss();

        }

    });

    dialog.show();

}

tam olarak aradığım şey basit ve anlaşılır ve etkinlikleri kontrol etmeden veya yığınlamadan kolayca yöntem çağrısı. teşekkürler
Abhishek Garg

5

Bunun için ana düzeninizin altında yardım düzeni oluşturmanız gerekir, örn: (yapı)

<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>

2

Ana düzeninizi bir içine sarın RelativeLayout, ardından buna ikinci bir düzen ekleyin, örneğin:

<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>

Bindirme düzeninin XML dosyasındaki ana düzenin altına düştüğüne inanıyorum (bellek hizmet veriyorsa). Daha sonra ViewFlipperbu ikinci düzen içinde kendi düzeninizi oluşturabilirsiniz .


1
Cevabınız için teşekkürler! Bunu denedim ve işe yarıyor gibi görünüyor. Ancak, bir sorun var - kaplama düzenindeki içerik, etkinliğimdeki ActionBar veya ActionBar sekmelerini kapsamıyor.
Gautam

Sen ekledi RelativeLayoutiçin demo_activity.xmldosyanın? Ve DemoActivityana (ilk) Activitymi?
Eric

Pekala, 'DemoActivity' aynı şeyi yapacak şeffaf bir etkinlik yaratma girişimimdi. 'MainActivity', arka planda altında olmasını istediğim etkinliktir. Bu yüzden 'MainActivity' için düzeni, yani 'main_activity.xml', bahsettiğiniz gibi 'RelativeLayout' ile sardım ve ayrıca şeffaf 'LinearLayout' ekledim. Sorun, "main_activity.xml" deki tüm içeriğin "ActionBar" ın ve onun gezinme sekmelerinden herhangi birinin altında gösterilmesidir.
Gautam

1

Yeni bir Etkinlik oluşturun (Öğretici deyin).

Aktivitenizin düzen xml dosyasına (activity_tutorial) gidin. Ana düzen altında "android: background = # 000" ve "android: alpha =" 0.5 "ekleyin

<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>

Şimdi, uygulama bildirim dosyasına gidin ve eğitim etkinliğinizin altına android: theme = "@ android: style / Theme.Translucent.NoTitleBar" özelliğini ekleyin>

<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>

İşte bu, şimdi bu aktiviteyi diğer aktivitelerin üzerinde çalıştırın ve istediğiniz sonuçları elde edebilirsiniz. İstediğiniz eğitim ekranını elde etmek için özelleştirin, metin, görüntü görünümü ve diğer şeyler ekleyin. Bir görüntüleyicinin bu teknikle çalışmasını sağlayabileceğinizden oldukça eminim.


0

Onlar yaptıkları gibi, Android başlatıcı kodunu da kontrol edebilirsiniz. Orada uygulamayı bilmiyorum.

Ben olsaydım yapardım (basit bir kaplama olsaydı), böylece uygulamanız için düzeninizi bozmazsınız, sadece kaplama düzeninizi oluşturun ve bunu doğrudan etkinliklerinizle ekleyerek uygulama düzeninizin üzerine ekleyin WindowManager. Bir ekleme gibi basit olarak olabilir ImageViewiçin WindowManager, üzerine dokunuşlar dinlemek ImageViewveya kaldırmak için bir zaman aşımı var ImageViewhesabınızla ilgili Window.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.