Android应用第一次进入显示的欢迎,引导页面实例

来源:互联网 发布:正义不会缺席知乎 编辑:程序博客网 时间:2024/05/18 04:53

大家一定见过各种各类的app软件吧,多数app都会有一个第一次运行进入app时显示的欢迎介绍页面,下面就是我的实现方式

import www.fenpai.show.R;import android.app.Dialog;import android.content.Context;import android.os.Bundle;import android.support.v4.view.PagerAdapter;import android.support.v4.view.ViewPager;import android.support.v4.view.ViewPager.OnPageChangeListener;import android.view.KeyEvent;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.view.Window;import android.view.WindowManager;import android.view.ViewGroup.LayoutParams;/** * 第一次进入App时显示的欢迎引导页面 *  * @author 周舜 *  */public class WelcomeDialog extends Dialog {/** * 显示内容的容器 */private ViewPager mInnerViewPager = null;private Context mContext = null;/** * 内容数组 */private View[] mViews;/** * 用户行为监听接口 */private WelcomeDialogImpl mWelcomeDialogImpl;public WelcomeDialog(Context context) {this(context, R.style.FullScreenDialog);}public WelcomeDialog(Context context, int theme) {// 这里我选择强制的使用了自己定义的Dialog样式,控制风格// 如果用户不是用的R.style.FullScreenDialog,则强制替换super(context,theme != R.style.FullScreenDialog ? R.style.FullScreenDialog: theme);this.mContext = context;}/** * 设置用户操作行为接口,用户按下返回键时将回调,用户滑动到左后一个页面时将回调 *  * @param welcomeDialogImpl *            {@link WelcomeDialogImpl} */public void setWelcomeDialogImpl(WelcomeDialogImpl welcomeDialogImpl) {if (null == welcomeDialogImpl)throw new NullPointerException("ERROR:WelcomeDialogImpl为空");this.mWelcomeDialogImpl = welcomeDialogImpl;}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Window window = getWindow();// 设置大小为全屏-1=WindowManager.LayoutParams.MATCH_PARENTWindowManager.LayoutParams params = window.getAttributes();params.height = -1;params.width = -1;window.setAttributes(params);// 设置Dialog 弹出时显示的动画样式window.setWindowAnimations(R.style.WelcomeDialogAnim);// 设置点击返回键无效setCancelable(false);}@Overridepublic void setContentView(View view) {this.setContentView(view, null);}@Overridepublic void setContentView(int layoutResID) {// 根据传入的资源id,获得view;View view = LayoutInflater.from(mContext).inflate(layoutResID, null);this.setContentView(view, null);}/** * 可以使用自己定义的ViewPager,如果调用了此函数且ViewPager的内容没有在本组件中维护,那么不需要调用 * {@link #setImgsResource(int[])},{@link #setViews(View[])} *  * @param view *            必须是ViewPager的子类 */@Overridepublic void setContentView(View view, LayoutParams params) {// 如果传入进来的View不为ViewPager,则抛出异常if (!(view instanceof ViewPager)) {view = null;throw new ClassFormatError("ERROR:View不是ViewPager的实现类");}mInnerViewPager = (ViewPager) view;super.setContentView(mInnerViewPager,null == params ? new ViewGroup.LayoutParams(-1, -1) : params);}/** * 重写了该函数,强制让点击返回键无效 */@Overridepublic void setCancelable(boolean flag) {super.setCancelable(flag ? !flag : flag);}/** * 设置需要显示的图片资源(内容view本组件会生成且本组件会维护好这些数据,不需要再调用{@link #setViews(View[] views)} * 来设置显示内容了 *  * @param res *            资源数组 */public void setImgsResource(int[] res) {// 如果非空则表示调用了setViewsif (null != mViews)return;if (null == mInnerViewPager)setContentView(mInnerViewPager = new ViewPager(mContext), null);// 这里我给实例化了一个比参数长度+1的数组,这是为了多一个页面,因为用户滑倒最后一页在滑动的时候应该关闭本组件this.mViews = new View[res.length + 1];for (int i = 0; i < res.length; i++) {View v = new View(mContext);v.setBackgroundResource(res[i]);this.mViews[i] = v;}// 这里多添加一个空的View,作为最后一个页面,这样用户可以看玩所有实际内容页面,滑动到这个空页面时会// 调用mWelcomeDialogImpl.onLastPage();this.mViews[res.length] = new View(mContext);// 设置内容适配器this.mInnerViewPager.setAdapter(new InnerPagerAdapter(mViews));// 设置页面更变监听this.mInnerViewPager.setOnPageChangeListener(new InnerOnPageChangeListener());}/** * 设置需要显示的页面 显示的内容需要自己维护 不需要再调用{@link #setImgsResource(int[] res)} *  * @param views *            页面数组 */public void setViews(View[] views) {// 如果非空则表示调用了setImgsResourceif (null != mViews)return;if (null == mInnerViewPager)setContentView(mInnerViewPager = new ViewPager(mContext), null);// 这里我给实例化了一个比参数长度+1的数组,这是为了多一个页面,因为用户滑倒最后一页在滑动的时候应该关闭本组件this.mViews = new View[views.length + 1];// 这里多添加一个空的View,作为最后一个页面,这样用户可以看玩所有实际内容页面,滑动到这个空页面时会// 调用mWelcomeDialogImpl.onLastPage();this.mViews[views.length] = new View(mContext);// 设置内容适配器mInnerViewPager.setAdapter(new InnerPagerAdapter(views));// 设置页面更变监听mInnerViewPager.setOnPageChangeListener(new InnerOnPageChangeListener());}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {if (null == mWelcomeDialogImpl)throw new NullPointerException("ERROR:WelcomeDialogImpl为空请设置");// 如果用户按下了返回键,回调接口通知实现方mWelcomeDialogImpl.onBack();return false;}return super.onKeyDown(keyCode, event);}class InnerPagerAdapter extends PagerAdapter {private View[] views;public InnerPagerAdapter(View[] views) {this.views = views;}@Overridepublic int getItemPosition(Object object) {return super.getItemPosition(object);}@Overridepublic void destroyItem(View arg0, int arg1, Object arg2) {}@Overridepublic Object instantiateItem(View arg0, int arg1) {// 不重复添加已经添加过的Viewif (((ViewPager) arg0).getChildCount() - 1 < arg1) {((ViewPager) arg0).addView(views[arg1]);}return views[arg1];}@Overridepublic boolean isViewFromObject(View arg0, Object arg1) {return arg0 == arg1;}@Overridepublic int getCount() {return views.length;}}/** * 滑动页面监听 *  * @author 周舜 *  */class InnerOnPageChangeListener implements OnPageChangeListener {@Overridepublic void onPageSelected(int arg0) {// 如果滑动到最后一页,回调接口通知实现方if (arg0 == (mViews.length - 1)) {if (null == mWelcomeDialogImpl)throw new NullPointerException("ERROR:WelcomeDialogImpl为空请设置");mWelcomeDialogImpl.onLastPage();}}@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {}@Overridepublic void onPageScrollStateChanged(int arg0) {}}/** * 用户操作行为接口 *  * @author 周舜 *  */public interface WelcomeDialogImpl {/** * 用户点击返回键时被调用 */void onBack();/** * 滑动到最后一页时被调用 */void onLastPage();}}


实现原理比较简单,就是一个全屏无边框的Dialog,中添加了一个ViewPager作为显示内容的容器设置内容的方法有2种,一种是setImgsResource(int[] res),这种方式数据之类的东西都是由本组件来维护。另外一种是setViews(View[] views),这种方式需要自己来维护内容.WelcomeDialogImpl接口来监听用户的操作onBack()表示用户点击了返回键,onLastPage()表示滑动到了最后一页,可以在这个函数里面关闭本个组件.


下面是用到的Style样式

    <style name="FullScreenDialog" parent="@android:Theme.Dialog">        <item name="android:windowFrame">@null</item>        <item name="android:windowNoTitle">true</item>        <item name="android:windowBackground">@android:color/transparent</item>        <item name="android:windowIsTranslucent">false</item>        <item name="android:windowIsFloating">true</item>        <item name="android:windowContentOverlay">@null</item>        <item name="android:backgroundDimEnabled">true</item>    </style>    <!--动画-->    <style name="WelcomeDialogAnim">        <item name="android:windowEnterAnimation">@anim/welcome_dialog_in</item>        <item name="android:windowExitAnimation">@anim/welcome_dialog_out</item>    </style>


调用实例

/** * 显示欢迎引导页面,如果第一次进入则会显示,之后不会显示 */private void showWelcomeDialog() {SharedPreferences preferences = getSharedPreferences("phone",Context.MODE_PRIVATE);if (preferences.getBoolean("first_login", true)) {mEditor = preferences.edit();// 设置已经不是第一次进入软件mEditor.putBoolean("first_login", false);mWelcomeDialog = new WelcomeDialog(this);mWelcomeDialog.setWelcomeDialogImpl(this);mWelcomeDialog.setImgsResource(new int[] { R.drawable.welcome_1,R.drawable.welcome_2, R.drawable.welcome_3 });mWelcomeDialog.show();}}@Overridepublic void onLastPage() {// 关闭欢迎引导窗体if (null != mWelcomeDialog)mWelcomeDialog.cancel();mWelcomeDialog = null;// 提交设置,设置之后不会再弹出欢迎引导窗体mEditor.commit();}@Overridepublic void onBack() {// 销毁单前activitysuper.onBackPressed();}


Activity实现了WelcomeDialogImpl接口来监听用户的操作,在滑动到最后一个页面的时候可以保存Editor中设置的值,下次登录就不会显示这个欢迎介绍页面了,onBack函数中调用了父类的onBackPressed();这是我实现了另外一个类,那个类里面处理了操作,这里就不贴代码了,大家只需要在onBack里面调用finish()退出act,或者关闭本组件.这个看大家的需求了.怎么样,很简单吧,赶紧试试吧.

本文章属于原创,转载请注明出处.



0 1