先看實際效果,這個是用了一個APP裏面的圖片,不是本身的圖。android
第一步:建立引導頁的 Activity,先在引導頁上的xml定義一個ViewPager和用於下面放置圓點導航的ViewImage。app
<android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerInParent="true" android:background="#00000000"> </android.support.v4.view.ViewPager> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:layout_alignParentBottom="true" android:layout_marginBottom="68dp" > <ImageView android:layout_width="12dp" android:layout_height="12dp" android:id="@+id/iv1" android:src="@drawable/abc_btn_radio_check"/> <ImageView android:layout_width="12dp" android:layout_height="12dp" android:id="@+id/iv2" android:src="@drawable/abc_btn_radio_nocheck"/> <ImageView android:layout_width="12dp" android:layout_height="12dp" android:id="@+id/iv3" android:src="@drawable/abc_btn_radio_nocheck"/> <ImageView android:layout_width="12dp" android:layout_height="12dp" android:id="@+id/iv4" android:src="@drawable/abc_btn_radio_nocheck"/> </LinearLayout>
第二步:建立一個繼承自 PagerAdapter 的類。其中的內容也是分3個部分:
第1部分:構造函數
第2部分:加載、銷燬View的方法
第3部分:自動生成的兩個有返回值的方法ide
public class ViewPagerAdapter extends PagerAdapter { // 建立兩個變量,做爲參數傳入構造方法 private List<View> mViews; private Context mContext; public ViewPagerAdapter (List<View> views, Context context) { this.mViews = views; this.mContext = context; } // 根據 position 索引來銷燬View @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(mViews.get(position)); } // 加載 View @Override public Object instantiateItem(ViewGroup container, int position) { container.addView(mViews.get(position)); return mViews.get(position); } // 返回 View 集合的數量 @Override public int getCount() { return mViews.size(); } // 判斷當前 View 是否咱們須要的對象 @Override public boolean isViewFromObject(View view, Object object) { return (view == object); } }
第三步:回到剛纔引導頁的Activity,添加以下代碼。函數
public class GuideActivity extends Activity implements ViewPager.OnPageChangeListener { private ViewPager mViewPager; private ViewPagerAdapter mViewPagerAdapter; private List<View> mViews; private ImageView[] mImageViews; private int[] mInts = new int[] {R.id.iv1, R.id.iv2, R.id.iv3, R.id.iv4}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 去除引導頁的標題欄 requestWindowFeature(Window.FEATURE_NO_TITLE); // 設置頂部狀態欄爲透明狀態 getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); setContentView(R.layout.activity_guide); // 加載View視圖 initViews(); // 加載底部圓點導航 initPoint(); } // 加載 View 視力 private void initViews() { //第1步,建立一個View的集合,並動態加載n個View,添加進集合 LayoutInflater inflater = LayoutInflater.from(this); mViews = new ArrayList<View>(); mViews.add(inflater.inflate(R.layout.layout_guide_0, null)); mViews.add(inflater.inflate(R.layout.layout_guide_1, null)); mViews.add(inflater.inflate(R.layout.layout_guide_2, null)); mViews.add(inflater.inflate(R.layout.layout_guide_3, null)); ////第2步,爲ViewAdapter裝載這個集合 mViewPagerAdapter = new ViewPagerAdapter(mViews, this); //第3步,給ViewPager設置ViewAdapter mViewPager = (ViewPager) findViewById(R.id.viewPager); mViewPager.setAdapter(mViewPagerAdapter); // 找到 Button,注意這個 Button 不是當前佈局裏的,這個按鈕是在集合中最後一頁的進入首頁那個按鈕 // 因此得用 view 集合找到最後一頁再 findViewById,否則會因找不到,致使空指針異常。 Button btnEntryMain = (Button) mViews.get(3).findViewById(R.id.btnEntryMain); btnEntryMain.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(GuideActivity.this, MainActivity.class); startActivity(intent); finish(); } }); mViewPager.setOnPageChangeListener(this); } // 加載底部圓點導航 private void initPoint() { mImageViews = new ImageView[mViews.size()]; for (int i = 0; i < mViews.size(); i++) { mImageViews[i] = (ImageView) findViewById(mInts[i]); } } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } // 當Page被選中時解發的事,變換圓點導航 @Override public void onPageSelected(int position) { for (int i = 0; i < mImageViews.length; i++) { if (position == i){ mImageViews[i].setImageResource(R.drawable.abc_btn_radio_check); } else { mImageViews[i].setImageResource(R.drawable.abc_btn_radio_nocheck); } } } @Override public void onPageScrollStateChanged(int state) { } }
第四步:這裏開始建立要顯示View的xml,這裏用到了4個xml,都是同樣的代碼,惟獨最後一個多添加了一個用於進入主Activity的Button,故只貼出最後一個xml的代碼。佈局
<android.support.percent.PercentRelativeLayout xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:id="@+id/ivFont" app:layout_widthPercent="60%" app:layout_heightPercent="30%" android:layout_centerInParent="true" android:layout_alignParentTop="true" android:layout_marginTop="70dp" android:src="@drawable/guide_p4_word"/> <ImageView android:id="@+id/ivImage" android:layout_below="@id/ivFont" app:layout_widthPercent="100%" app:layout_heightPercent="30%" android:src="@drawable/guide_p4_img"/> <Button android:id="@+id/btnEntryMain" app:layout_widthPercent="80%" android:layout_height="wrap_content" android:text="進入主程序" android:layout_alignParentBottom="true" android:layout_marginBottom="15dp" android:layout_centerHorizontal="true" android:textSize="20sp" android:background="#cac2c8" android:textColor="@color/colorPrimary"/> </android.support.percent.PercentRelativeLayout>
這裏用的佈局是百分比佈局,適配性仍是不行,若是在特別大的屏幕,會有一點點的小誤差,待後期作整個Demo的時候再好好改改。ui
第五步,這裏再建立一個Activity,用於進程序顯示的第一個畫面,能夠放張圖片或者廣告之類的。this
public class WelcomeActivity extends Activity { private static final int WAIT_TIME = 2000; private static final int ACT_HOME = 1000; private static final int ACT_GUIDE = 1001; private boolean mIsFirst = false; // 延時操做啓動相關的 Activity,由於是在主線程,因此用 Handler private Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { switch(msg.what){ case ACT_HOME: goHome(); break; case ACT_GUIDE: goGuide(); break; default: break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 去掉頭部標題 requestWindowFeature(Window.FEATURE_NO_TITLE); // 設置頭部狀態欄透明(同色) getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); setContentView(R.layout.activity_wecome); init(); } // 根據 SharedPreferences 的 first 發送給 Handler 啓動哪一個 Activity private void init() { SharedPreferences sp = getPreferences(MODE_PRIVATE); //先去取isFirst的值,若是沒有,代表是第一次取,第一次取確定是true,因此這裏給個默認值爲 true mIsFirst = sp.getBoolean("first", true); if (!mIsFirst){ // 有延時 mHandler.sendEmptyMessageDelayed(ACT_HOME, WAIT_TIME); } else { // 直接啓動 mHandler.sendEmptyMessage(ACT_GUIDE); // 寫入數據 SharedPreferences.Editor editor = sp.edit(); editor.putBoolean("first", false); editor.commit(); } } // 啓動主 Activity private void goHome() { Intent intent = new Intent(WelcomeActivity.this, MainActivity.class); startActivity(intent); finish(); } // 啓動引導頁 Activity private void goGuide() { Intent intent = new Intent(WelcomeActivity.this, GuideActivity.class); startActivity(intent); finish(); } }
若是想簡化一點,能夠沒必要建立這個 Activity ,有另外一種解決方法:
在style.xml 文件中新建一個style 主題spa
<style name="Theme.Start" parent="android:Theme"> <item name="android:windowBackground">@drawable/ic_launcher</item> <item name="android:windowNoTitle">true</item> </style>
android:windowBackgrounds屬性中添加本身的過場圖片就好
在AndroidManifest.xml文件, 程序中第一個顯示的界面添加這個主題線程
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".ActLogo" android:theme="@style/Theme.Start" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
固然了,用這種方法的話,WelcomeActivity裏的業務邏輯代碼就得放進MainActivity裏,看本身怎麼去作,業務邏輯仍是同樣的。指針
另外作好後仍是遇到了一個問題,就是在啓動程序的時候會有1秒左右的空白,這個很好解決,在AndroidManifest.xml定義要啓動的 Activity 里加上一個主題便可。
android:theme="@android:style/Theme.Translucent"