คุณสร้างหน้าจอสาธิตแบบโปร่งใสสำหรับแอป Android ได้อย่างไร


105

ฉันกำลังพยายามสร้างหน้าจอสาธิตแบบกึ่งโปร่งใสที่จะเปิดขึ้นเมื่อผู้ใช้ติดตั้งแอปพลิเคชันของฉันครั้งแรกเท่านั้น นี่คือตัวอย่างจากแอป Pulse News:

Galaxy Nexus

ตัวอย่างภาพหน้าจอจาก Pulse News บน Galaxy Nexus

Nexus One

ป้อนคำอธิบายภาพที่นี่

แทนที่จะใช้คุณสมบัติ 'แตะเพื่อปิด' ฉันต้องการให้ผู้ใช้สามารถปัดผ่านหน้าสาธิตโปร่งใสสองสามหน้าดังกล่าวได้

สำหรับความพยายามครั้งแรกของฉันฉันแก้ไขตัวอย่างจากViewPagerIndicatorไลบรารีฉันใช้ PNG กึ่งโปร่งใสใน ImageViews ภายในส่วนของเพจเจอร์แต่ละมุมมอง จากนั้นฉันก็เปิดตัวสิ่งนี้เป็น 'กิจกรรมสาธิต' ในเมธอด onCreate ของ 'กิจกรรมหลัก' ของฉัน

ปัญหา: ไม่สามารถมองเห็น 'กิจกรรมหลัก' ในพื้นหลัง แต่เป็นเพียงสีดำ ฉันลองแก้ปัญหาที่นี่แล้ว แต่ไม่สามารถแก้ไขปัญหาได้

มีแนวทางที่ดีกว่าในการสร้างสิ่งนี้หรือฉันมาถูกทางแล้ว?

ฉันยังมีคำถามอื่นที่เกี่ยวข้องซึ่งขึ้นอยู่กับวิธีการใช้งาน ฉันพยายามวางซ้อนข้อความและลูกศรเพื่อให้ชี้ไปที่ส่วนประกอบ UI เฉพาะในพื้นหลัง การใช้ PNG ที่มีข้อความและลูกศรมีแนวโน้มว่าจะปรับขนาดได้ไม่เหมาะสมในอุปกรณ์ต่างๆ กล่าวคือลูกศรอาจไม่จำเป็นต้องชี้ไปที่ส่วนประกอบ UI ที่ถูกต้องในพื้นหลัง มีวิธีจัดการกับปัญหานี้ด้วยหรือไม่?

ขอบคุณ!

นี่คือรหัสของฉันสำหรับความพยายามครั้งแรก:

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

โดยไม่ต้องดูรหัสของคุณก็ยากที่จะแนะนำอะไร หากคุณใส่รหัสกิจกรรมได้ก็อาจช่วยได้
— Sayyam

11
นั่นเป็นคำถามที่ดี
— con_9

คำตอบ:


79

ใส่ข้อมูลสาธิตของคุณในกิจกรรมอื่นและกำหนดธีมต่อไปนี้

<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% ดังนั้นเลือกบางสิ่งระหว่าง


1
ขอบคุณสำหรับคำตอบ! นี่เป็นสิ่งที่ฉันทำหลังจากลองผิดลองถูกมาหลายครั้ง ฉันยังคงสงสัยว่าหน้าจอสาธิต Pulse สามารถ 'เปลี่ยนตำแหน่ง' เนื้อหาที่ซ้อนทับในตำแหน่งที่เหมาะสมได้อย่างไรแม้ในขนาดหน้าจอที่แตกต่างกัน - ดูภาพหน้าจอที่อัปเดต ความคิดใด ๆ ?
— Gautam

2
ในกิจกรรมแรกของคุณให้ค้นหามุมมองที่คุณต้องการชี้ไปที่ ( findViewById) จากนั้นรับตำแหน่งที่สัมพันธ์กับเค้าโครงรูทโดยใช้วิธีนี้ ส่งตำแหน่งซ้อนทับกิจกรรมในเจตนา จัดตำแหน่งที่เหมาะสม
— Benito Bertoli

2
หรือใช้View.getLocationOnScreen(int[] location)หรือView.getLocationInWindow(int[] location). ฉันไม่แน่ใจว่าอันไหนดีกว่ากัน
— Benito Bertoli

@Gautam: "มีความคิดอย่างไร" - สำหรับ Pulse นี่เป็นเรื่องของการวางภาพหนึ่งภาพที่มุมบนซ้ายอีกภาพหนึ่งอยู่ตรงกลางและภาพที่สามที่มุมล่างขวา XML ประมาณหนึ่งโหลหรือมากกว่านั้นตาม a RelativeLayoutก็เพียงพอแล้ว
— CommonsWare

1
สิ่งนี้ใช้ได้ผลสำหรับฉัน แต่ฉันมีปัญหาในการทำกิจกรรมเพื่อขยายกิจกรรม ดังนั้นในการใช้ AppCompatActivity ฉันได้กำหนดรูปแบบดังนี้ <style name = "Transparent" parent = "Theme.AppCompat"> <item name = "android: windowContentOverlay"> @ null </item> <item name = "android : windowIsTranslucent "> จริง </item> <item name =" android: windowBackground "> @ android: color / transparent </item> <item name =" android: windowNoTitle "> จริง </item> <item name =" android : backgroundDimEnabled "> เท็จ </item> </style>
— Jose Q

65

คุณดู 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);

1
ขอบคุณนั่นคือสิ่งที่ฉันกำลังมองหา
— Snicolas

สุดยอด! คุณรู้จักอะไรที่คล้ายกันสำหรับ iOS หรือไม่?
— KVISH

เลิกใช้แล้ว ... นักพัฒนาหมายความว่าการออกแบบ API พื้นฐานไม่ดีพอ (ซึ่งเป็นความจริงบางส่วน)
— Laurent Meyer

ฉันลองสิ่งนี้และพบว่าไม่มีแท็กสำหรับเปลี่ยนภาพ
— Anshul Tyagi

11

Pulse ใช้ RelativeLayout กับ ImageView สี่ตัวและ TextView สี่ตัว ข้อความในภาพหน้าจอเป็น TextView ทั้งหมดที่มีแบบอักษรที่กำหนดเอง

ในไฟล์ Manifest ของคุณให้เพิ่มสิ่งต่อไปนี้ในกิจกรรมของคุณ:

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/

เค้าโครงจาก Hierarchy Viewer มีลักษณะดังนี้ (กล่องสีแดงคือคอนเทนเนอร์ RelativeLayout):

ป้อนคำอธิบายภาพที่นี่


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

}

สิ่งที่ฉันกำลังมองหาที่เรียบง่ายและตรงไปตรงมาและวิธีการโทรอย่างง่ายดายโดยไม่ต้องควบคุมหรือซ้อนกิจกรรม ขอบคุณ
— Abhishek Garg

5

สำหรับสิ่งนี้คุณต้องสร้างเค้าโครงความช่วยเหลือที่ด้านล่างของเค้าโครงหลักเช่น: (โครงสร้าง)

<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

รวมเลย์เอาต์หลักของคุณเป็น a 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ตามที่คุณต้องการภายในเลย์เอาต์ที่สองนี้


1
ขอบคุณสำหรับการตอบกลับ! ฉันลองแล้วดูเหมือนจะได้ผล อย่างไรก็ตามมีปัญหาหนึ่ง - เนื้อหาในเลย์เอาต์ภาพซ้อนทับไม่ครอบคลุมบนแท็บ ActionBar หรือ ActionBar ที่ฉันมีในกิจกรรมของฉัน
— Gautam

คุณเพิ่มRelativeLayoutไปยังdemo_activity.xmlไฟล์? และเป็นDemoActivityหลัก (แรก) ของActivityคุณหรือไม่?
— Eric

'DemoActivity' เป็นความพยายามของฉันที่จะสร้างกิจกรรมที่โปร่งใสซึ่งจะทำในสิ่งเดียวกัน 'MainActivity' คือกิจกรรมที่ฉันต้องการอยู่เบื้องหลัง ดังนั้นฉันจึงรวมเค้าโครงสำหรับ 'MainActivity' คือ 'main_activity.xml' ด้วย 'RelativeLayout' เหมือนที่คุณพูดถึงและยังแทรก 'LinearLayout' แบบโปร่งใส ปัญหาคือเนื้อหาทั้งหมดใน 'main_activity.xml' แสดงอยู่ใต้ 'ActionBar' และแท็บการนำทางใด ๆ
— Gautam

1

สร้างกิจกรรมใหม่ (พูดบทช่วยสอน)

ไปที่ไฟล์ 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>

ตอนนี้เรียกใช้กิจกรรมนี้กับกิจกรรมอื่น ๆ และคุณจะได้รับผลลัพธ์ที่ต้องการ ปรับแต่งเพิ่มข้อความมุมมองภาพและสิ่งอื่น ๆ เพื่อให้ได้หน้าจอการสอนที่คุณต้องการ ค่อนข้างแน่ใจว่าคุณสามารถทำให้ viewpager ทำงานด้วยเทคนิคนี้ได้


0

คุณสามารถตรวจสอบรหัสตัวเรียกใช้งาน Android ได้เช่นเดียวกับที่ทำ ฉันไม่ทราบว่ามีการใช้งาน

ถ้ามันเป็นฉันฉันจะ (ถ้าเป็นเพียงแค่การซ้อนทับง่าย) เพื่อให้คุณ dont สกรูที่มีรูปแบบของคุณสำหรับการประยุกต์ใช้ของคุณเพียงแค่สร้างรูปแบบการซ้อนทับของคุณและแนบมันมากกว่ารูปแบบการประยุกต์ใช้ ur WindowManagerโดยเพิ่มโดยตรงกับกิจกรรมของคุณ อาจทำได้ง่ายเพียงแค่เพิ่มImageViewในWindowManagerฟังก์ชั่นการแตะImageViewหรือกำหนดเวลาที่จะลบออกImageViewจากWindowไฟล์.

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.