`
he91_com
  • 浏览: 376363 次
文章分类
社区版块
存档分类
最新评论

android 给自己的app编写 用户引导(UserGuider)

 
阅读更多

有些第三方应用(如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

~~完~~


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics