有些第三方应用(如QQ,微信等),安装后第一次使用都有个用户引导,提示用户怎么用及版本升级后新功能介绍。用 Hierarchy Viewer 工具看用户引导 是用哪些layout组成的。常见的QQ,微信 用的 Gallery,百度输入法用的是 FrameLayout。

下面就以 Gallery 实现用户引导为例。

先来图吧,有图有真相!

这个熟悉吧,仿微信当前最新版的欢迎页。安装后第一次启动这个用户引导,本例用读写SharedPrefences判断是否第一次进(代码片段):

boolean firstLogin = PreferenceManager.getDefaultSharedPreferences(this).getBoolean(FLAG_FIRST_LOGIN, true);    if (firstLogin) {        startActivity(new Intent("com.xyz.guider.GuiderActivity"));    }


完成用户引导后把键值 first 写 false:

SharedPreferences sp = PreferenceManager        .getDefaultSharedPreferences(mContext);    Editor edit = sp.edit();    edit.putBoolean(FLAG_FIRST_LOGIN, false);    edit.commit();


下面来贴关键代码。

用户引导布局:

<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/main_layout"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:background="@drawable/background_holo_dark" >    <com.xyz.guider.XyzGallery        android:id="@+id/what_news_gallery"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:clickable="true"        android:focusable="true"        android:spacing="0.0dip"        android:unselectedAlpha="1.2" />    <LinearLayout        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:layout_gravity="center"        android:background="@null" >        <com.xyz.guider.PageControlView            android:id="@+id/what_news_page_control"            android:layout_width="fill_parent"            android:layout_height="fill_parent"            android:layout_marginBottom="17.5dip"            android:background="@null"            android:gravity="bottom|center" />    </LinearLayout>    <RelativeLayout        xmlns:android="http://schemas.android.com/apk/res/android"        android:id="@+id/mm_door"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:background="@drawable/background_holo_dark"        android:orientation="horizontal"        android:visibility="gone" >        <ImageView            android:id="@+id/mm_left"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_centerInParent="true"            android:adjustViewBounds="true"            android:scaleType="fitEnd"            android:src="@drawable/whatsnew_08_01" />        <ImageView            android:id="@+id/mm_right"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_centerInParent="true"            android:adjustViewBounds="true"            android:scaleType="fitEnd"            android:src="@drawable/whatsnew_08_02" />    </RelativeLayout></FrameLayout>



首先继承个Gallery的类如XyzGallery:

package com.xyz.guider;import android.content.Context;import android.util.AttributeSet;import android.view.KeyEvent;import android.view.MotionEvent;import android.widget.Gallery;public class XyzGallery extends Gallery {    public XyzGallery(Context context) {        super(context);        // TODO Auto-generated constructor stub        setStaticTransformationsEnabled(true);    }    public XyzGallery(Context context, AttributeSet attrs) {        super(context, attrs);        // TODO Auto-generated constructor stub        setStaticTransformationsEnabled(true);    }    public XyzGallery(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        // TODO Auto-generated constructor stub        setStaticTransformationsEnabled(true);    }    @Override    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,            float velocityY) {        // TODO Auto-generated method stub        if (velocityX > 0) {            onKeyDown(KeyEvent.KEYCODE_DPAD_LEFT, null);        } else {            onKeyDown(KeyEvent.KEYCODE_DPAD_RIGHT, null);        }        return true;    }}


有了Gallery,还要个Gallery的适配器,作为GuiderActivity的内部类,GuiderActivity主要作用是呈现并控制 用户引导 界面:

package com.xyz.guider;import android.app.Activity;import android.content.Context;import android.content.Intent;import android.content.SharedPreferences;import android.content.SharedPreferences.Editor;import android.os.Bundle;import android.preference.PreferenceManager;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.view.View.OnClickListener;import android.view.WindowManager;import android.view.animation.Animation;import android.view.animation.Animation.AnimationListener;import android.view.animation.AnimationUtils;import android.widget.AdapterView;import android.widget.AdapterView.OnItemSelectedListener;import android.widget.BaseAdapter;import android.widget.Button;import android.widget.ImageView;public class GuiderActivity extends Activity implements OnItemSelectedListener {    private View mViewDoor = null;    private ImageView mImageLeft = null;    private ImageView mImageRight = null;    private XyzGallery mGallery = null;    private GalleryAdapter mAdapter = null;    private PageControlView mIndicateView = null;    private static final String FLAG_FIRST_LOGIN = "first";    @Override    protected void onCreate(Bundle savedInstanceState) {        // TODO Auto-generated method stub        super.onCreate(savedInstanceState);        setContentView(R.layout.whats_news);        mGallery = (XyzGallery) findViewById(R.id.what_news_gallery);        mAdapter = new GalleryAdapter(this);        mGallery.setFadingEdgeLength(0);        mGallery.setSpacing(-1);        mGallery.setAdapter(mAdapter);        mGallery.setOnItemSelectedListener(this);        mIndicateView = (PageControlView) findViewById(R.id.what_news_page_control);        mIndicateView.setIndication(mGallery.getCount(), 0);        mViewDoor = findViewById(R.id.mm_door);        mImageLeft = (ImageView) findViewById(R.id.mm_left);        mImageRight = (ImageView) findViewById(R.id.mm_right);    }    private class GalleryAdapter extends BaseAdapter implements            OnClickListener, AnimationListener {        private Context mContext;        private LayoutInflater mInfater = null;        private int[] mLayouts = new int[] {                R.layout.whats_news_gallery_fornew_one,                R.layout.whats_news_gallery_fornew_two,                R.layout.whats_news_gallery_fornew_three,                R.layout.whats_news_gallery_fornew_four };        public GalleryAdapter(Context ctx) {            mContext = ctx;            mInfater = (LayoutInflater) mContext                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);        }        @Override        public int getCount() {            // TODO Auto-generated method stub            return mLayouts.length;        }        @Override        public Object getItem(int position) {            // TODO Auto-generated method stub            return Integer.valueOf(position);        }        @Override        public long getItemId(int position) {            // TODO Auto-generated method stub            return position;        }        @Override        public View getView(int position, View convertView, ViewGroup parent) {            // TODO Auto-generated method stub            if (convertView == null) {                convertView = mInfater.inflate(mLayouts[position], null);                if (position == 3) {                    Button btn = (Button) convertView                            .findViewById(R.id.whats_new_start_btn);                    btn.setOnClickListener(this);                }            }            return convertView;        }        @Override        public void onClick(View v) {            // TODO Auto-generated method stub            mViewDoor.setVisibility(View.VISIBLE);            mImageLeft.startAnimation(setAnimation(R.anim.slide_left));            mImageRight.startAnimation(setAnimation(R.anim.slide_right));        }        private Animation setAnimation(int resId) {            Animation anim = AnimationUtils.loadAnimation(mContext, resId);            anim.setAnimationListener(this);            return anim;        }        @Override        public void onAnimationStart(Animation animation) {            // TODO Auto-generated method stub        }        @Override        public void onAnimationEnd(Animation animation) {            // TODO Auto-generated method stub            mImageLeft.setVisibility(View.GONE);            mImageRight.setVisibility(View.GONE);            SharedPreferences sp = PreferenceManager                    .getDefaultSharedPreferences(mContext);            Editor edit = sp.edit();            edit.putBoolean(FLAG_FIRST_LOGIN, false);            edit.commit();            GuiderActivity.this.finish();        }        @Override        public void onAnimationRepeat(Animation animation) {            // TODO Auto-generated method stub        }    }    @Override    public void onItemSelected(AdapterView<?> parent, View view, int position,            long id) {        // TODO Auto-generated method stub        if (mIndicateView != null) {            mIndicateView.setIndication(parent.getCount(), position);        }    }    @Override    public void onNothingSelected(AdapterView<?> parent) {        // TODO Auto-generated method stub    }}


还有个就是 用户引导 的指示器,共有几页,当前是那一页,实现起来很简单:

package com.xyz.guider;import android.content.Context;import android.util.AttributeSet;import android.widget.ImageView;import android.widget.LinearLayout;public class PageControlView extends LinearLayout {    private Context mContext;    public PageControlView(Context ctx) {        super(ctx);        // TODO Auto-generated constructor stub        mContext = ctx;    }    public PageControlView(Context ctx, AttributeSet attrs) {        super(ctx, attrs);        // TODO Auto-generated constructor stub        mContext = ctx;    }    public void setIndication(int cnt, int index) {        if (index < 0 || index > cnt)             index = 0;        removeAllViews();        for (int i = 0; i < cnt; i++) {            ImageView iv = new ImageView(mContext);            iv.setImageResource(index == i ? R.drawable.page_indicator_focused                    : R.drawable.page_indicator_unfocused);            if (i != 0 || i != cnt - 1) {                iv.setPadding(4, 0, 4, 0);            }            addView(iv);        }    }}


剩下的就是些xml文件,就不贴啦。

免分下载原码路径:http://download.csdn.net/detail/zhouyuanjing/4866714

~~完~~


更多相关文章

  1. 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
  2. Android(安卓)游戏开发之服务器端
  3. libevent 多线程IO
  4. 71、Android上对Cookie的读写操作
  5. Android流媒体开发之路三:基于NDK开发Android平台RTSP播放器
  6. 代码实例 -- 在程序里检查虚拟键盘状态, 并开启关闭
  7. 在Android(安卓)P中默认使用TLS保护用户
  8. “Android第一书”作者郭霖:用心做事,结果自然水到渠成
  9. 安卓4.1(android 4.1) 新功能分析 新特性介绍

随机推荐

  1. ubuntu使用uwsgi+nginx部署django
  2. python学习笔记:python 2与python 3的一些
  3. 【python学习.油价和美元汇率查询】
  4. python---写一个迭代器
  5. 第七章、Python字符编码
  6. python中x,y交换值的问题
  7. Django rest framework 使用自定义认证方
  8. Python学习/复习神器-->各种方法/技巧在哪
  9. Python:Sympy定义与包含变量的边界的积分
  10. 25行Python来反求触地位移模拟滚动