คุณสร้างหน้าจอสาธิตแบบโปร่งใสสำหรับแอป 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.