Android---引导界面的制作

一.概述

在我们下载了一个App第一次进入的时候,或者是已有App更新之后第一次进入时,一般都会有一个引导界面,这个界面用于展示本App的基本功能,或者是更新之后版本的重大改进;效果图如下:

这里就简单的记录以下这个功能的实现;

二.实现过程

1.布局页面分析

布局代码如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">

    <android.support.v4.view.ViewPager
        android:id="@+id/vp_guide"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </android.support.v4.view.ViewPager>

    <Button
        android:id="@+id/btn_start"
        android:textColor="@color/selector_txt_guide"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:background="@drawable/selector_btn_guide"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="60dp"
        android:visibility="invisible"
        android:text="开始体验"/>

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="30dp">

        <LinearLayout
            android:id="@+id/ll_container"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
        </LinearLayout>

        <ImageView
            android:id="@+id/iv_red_point"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/shape_point_red"/>

    </RelativeLayout>

</RelativeLayout>

注意:

 对于布局文件中Button的Visibility设置为false,不可见.在引导页的最后一页的时候,再将其设置为可见.

2.业务逻辑

难点:观察效果图注意到底部的小红点,当引导图滑动时,底部的小红点是跟随着滑动的.

2.1对小红点随页面移动而移动的分析如下:

ViewPager有一个监听事件: ViewPager.setOnPageChangeListener,

其中有一个重写的方法是这样的:

public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}

其中positionOffset参数是VIewPager中页面移动的百分比.

这样我们就可以得到一个思路:

小红点移动的距离(小红点的leftMargin值)=两小红点间距离*页面移动百分比(positionOffset)+当前位置的距离

2.2接下来分析两小红点之间的距离

从分析图片中可以看到,两小红点之间的距离(mPointDis)=第二个红点的left值-第一个红点的left值.

mPointDis = ll_container.getChildAt(1).getLeft() - ll_container.getChildAt(0).getLeft();

注意:

mPointDis 值必须要在View的位置确定了之后才可以得到(View的绘制有如下几个步骤:measures->layout(确定位置)->draw),所以我们要对小红点设置监听,当其位置确定了之后才拿mPointDis值.

//监听layout方法结束,位置确定好了之后,再计算值
        iv_red_point.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                //layout方法执行结束的回调

                //移除监听避免重复回调
                iv_red_point.getViewTreeObserver().removeOnGlobalLayoutListener(this);

                /*计算两个圆点的距离 第二个圆点的left值-第一个圆点的left值
                 * measures->layout(确定位置)->draw Acivity的onCreate方法结束后才会走这个流程
                 * */
                mPointDis = ll_container.getChildAt(1).getLeft() - ll_container.getChildAt(0).getLeft();
                Log.d("------>" + "计算两个圆点的距离", mPointDis + "");
            }
        });

2.3监听VIewPager的滑动,小红点随之而动

小红点的移动也就是在底部线性布局中的marginLeft值的改变.

由上诉分析得来的公式:

小红点移动的距离(小红点的leftMargin值)=两小红点间距离*页面移动百分比(positionOffset)+当前位置的距离

可以得到如下代码:

int leftMargin = (int) (mPointDis * positionOffset) + position * mPointDis;

然后将leftMargin的值从新设置给小红点的参数即可:

RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)
                        iv_red_point.getLayoutParams(); //拿到小红点的布局参数
                layoutParams.leftMargin = leftMargin; //修改小红点的布局参数
                iv_red_point.setLayoutParams(layoutParams); //重新设置小红点的布局参数

2.4业务逻辑完整代码

package com.example.lenovo.ruizhiapp;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import com.example.lenovo.utils.PrefUtils;

import java.util.ArrayList;

/**
 * 新手引导界面
 * Created by lenovo on 2016/7/7.
 */
public class GuideActivity extends Activity {

    private ViewPager vp_guide;
    //引导页图片ID数组
    private int[] mImageIds = new int[]{R.drawable.guide_1,
            R.drawable.guide_2,
            R.drawable.guide_3};
    //imageView的集合
    private ArrayList<ImageView> mImageViewList;
    private LinearLayout ll_container;
    private ImageView iv_red_point;
    private int mPointDis;
    private Button btn_start;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_guid);

        initViews();//初始化界面控件
        initData();//先初始化数据,然后再设置数据
        vp_guide.setAdapter(new GuideAdapter());//设置数据

    }

    private void initViews() {
        vp_guide = (ViewPager) findViewById(R.id.vp_guide);
        ll_container = (LinearLayout) findViewById(R.id.ll_container);
        iv_red_point = (ImageView) findViewById(R.id.iv_red_point);
        btn_start = (Button) findViewById(R.id.btn_start);

        //对ViewPager页面滑动的监听
        vp_guide.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

            @Override //页面滑动过程中的回调方法
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                Log.d("------>" + "当前位置:", position + "");
                Log.d("------>" + "偏移百分比:", positionOffset + "");

                //更新小红点的距离=移动百分比*两个原点间的间距+当前位置
                int leftMargin = (int) (mPointDis * positionOffset) + position * mPointDis;
                RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)
                        iv_red_point.getLayoutParams(); //拿到小红点的布局参数
                layoutParams.leftMargin = leftMargin; //修改小红点的布局参数
                iv_red_point.setLayoutParams(layoutParams); //重新设置小红点的布局参数

            }

            @Override //某个页面被选中
            public void onPageSelected(int position) {
                //最后一个页面才显示"开始体验的按钮"
                if (position==mImageViewList.size()-1){ //灵活代码
                    //只在引导页面的最后一页显示按钮
                    btn_start.setVisibility(View.VISIBLE);
                }else{
                    //其余引导页面不显示按钮
                    btn_start.setVisibility(View.INVISIBLE);
                }

            }

            @Override //页面状态发生变化 (滑-->不滑)
            public void onPageScrollStateChanged(int state) {
            }
        });

        //监听layout方法结束,位置确定好了之后,再计算值
        iv_red_point.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                //layout方法执行结束的回调

                //移除监听避免重复回调
                iv_red_point.getViewTreeObserver().removeOnGlobalLayoutListener(this);

                /*计算两个圆点的距离 第二个圆点的left值-第一个圆点的left值
                 * measures->layout(确定位置)->draw Acivity的onCreate方法结束后才会走这个流程
                 * */
                mPointDis = ll_container.getChildAt(1).getLeft() - ll_container.getChildAt(0).getLeft();
                Log.d("------>" + "计算两个圆点的距离", mPointDis + "");
            }
        });

        btn_start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(getApplicationContext(),MainActivity.class));
                //表示已经不是第一次进入,跟新SP
                PrefUtils.setBoolean(getApplicationContext(),ConstantValues.IS_FIRST_ENTER,false);
                //结束引导界面
                finish();

            }
        });

    }

    //初始化数据
    private void initData() {
        mImageViewList = new ArrayList<ImageView>();
        for (int i = 0; i < mImageIds.length; i++) {
            ImageView imageView = new ImageView(this);
            imageView.setBackgroundResource(mImageIds[i]);//通过设置背景,可以让宽高填充布局
            mImageViewList.add(imageView);

            //初始化底部小圆点
            ImageView point = new ImageView(this);
            point.setImageResource(R.drawable.shape_point_gray);//设置图片<shape>

            //初始化布局参数,宽高包裹内容,父控件是谁就申明谁的布局参数
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);

            if (i > 0) {
                //从第二个点开始设置原点之间的间隔
                layoutParams.leftMargin = 10;
            }
            point.setLayoutParams(layoutParams);//设置布局参数

            ll_container.addView(point);//给容器添加原点

        }
    }

    class GuideAdapter extends PagerAdapter {

        @Override //返回Item的个数
        public int getCount() {
            return mImageViewList.size();
        }

        @Override //固定写法
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        @Override //初始化Item布局
        public Object instantiateItem(ViewGroup container, int position) {
            ImageView imageView = mImageViewList.get(position);
            container.addView(imageView);
            return imageView;

        }

        @Override //销毁Item
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }
    }
}
时间: 2024-10-10 03:01:42

Android---引导界面的制作的相关文章

十八、Android引导界面

一.所需素材 很有必要整理一下,里面附带友盟的社会化分享组件,我就不去掉了. 二.代码 import com.umeng.update.UmengUpdateAgent; import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.os.Handler; import an

android 欢迎界面的制作

再打开手机app的时候,最先映入我们眼帘的是一个覆盖手机全屏的欢迎界面,在这个界面显示出来的时候整个手机屏幕只会显示这一个界面,上面的标题栏,以及手机最顶端的状态栏都会消失,只有欢迎页面结束跳转到其他页面时,标题栏和状态栏才回又显示出来. 现在我们就来制作一下欢迎界面. 欢迎界面的设置 首先,我们需要先创建一个Activity来承载这样一个.首先找到res文件夹下的Layout文件夹,创建一个Activity用于承载欢迎界面,也可以直接利用已经创建好的MainActivity,在使用其他的Act

Android 引导界面的实现过程

现在越来越多程序都有引导页面了.网上资料不全.现在自己实现下. 顺序是: OneAcitivity  –>MainActivity -> TwoActivity 然后第2次进去就是:OneActivity -> TwoActivity 代码里都有注释的了,这里就不多说了. OneActivity的代码如下: 1.png (18.29 KB, 下载次数: 0) 下载附件 android 7 分钟前 上传 MainActivity的代码如下: 最后是TWOActivity:这个Activit

使用UIPageControl UIScrollView制作APP引导界面

1. 新建两个视图控制器类(继承自UIViewController), 在AppDelegate.m中指定根视图控制器 #import "AppDelegate.h" #import "RootViewController.h" #import "LeadViewController.h" @interface AppDelegate () @end @implementation AppDelegate - (void)dealloc { se

android——利用SharedPreference做引导界面

很久以前就接触过sharedPreference这个android中的存储介质.但是一直没有实际使用过,今天在看之前做的“民用机型大全”的app时,突然想到可以使用sharedPreference类来改进这个app中的一个缺陷. 此前,我先介绍sharedPreference的使用.Android数据总共有四种存储的方式 一.SharePreference 二.SQLite 三.File 四.ContentProvider SharedPreference类是一个轻量级的存储类,特别适合保存软件

Android UI开发第四十三篇——使用Property Animation实现墨迹天气3.0引导界面及动画实现

前面写过<墨迹天气3.0引导界面及动画实现>,里面完美实现了动画效果,那一篇文章使用的View Animation,这一篇文章使用的Property Animation实现.Property Animation是Android3.0以后新增的动画库. 这篇文章的源码以及效果在github. 实现墨迹天气向上滑动的viewpager使用的开源库ViewPager-Android.ViewPager-Android开源库设置app:orientation定义滑动方向. 墨迹天气引导界面共有4个视图

android实现应用程序只有在第一次启动时显示引导界面

概述 SharedPreferences的使用非常简单,能够轻松的存放数据和读取数据.SharedPreferences只能保存简单类型的数据,例如,String.int等.一般会将复杂类型的数据转换成Base64编码,然后将转换后的数据以字符串的形式保存在 XML文件中,再用SharedPreferences保存. 使用SharedPreferences保存key-value对的步骤如下: (1)使用Activity类的getSharedPreferences方法获得SharedPrefere

android 功能引导界面实现

一.界面实现: 借鉴了别人的实例,然后记录下引导界面的实现,总体来说实现不算困难,前提是要有个美工帮你做这些引导图片(找了张图片凑合用吧): 主界面: public class MainActivity extends PromptActivity { //activity的生命周期 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layo

【Android UI设计与开发】3.引导界面(三)实现应用程序只启动一次引导界面

大部分的引导界面基本上都是千篇一律的,只要熟练掌握了一个,基本上也就没什么好说的了,要想实现应用程序只启动一次引导界面这样的效果,只要使用SharedPreferences类,就会让程序变的非常简单,下面来详细介绍一下这个类的使用方法 1.SharedPreferences的详细介绍和用法 其实在 20.游戏开发基础(游戏数据存储)中已经有过介绍了,为了文章的完整还是再介绍一遍. 做软件开发应该都知道,很多软件会有配置文件,里面存放这程序运行当中的各个属性值,由于其配置信息并不多,如果采用数据库

Android实现用户引导界面

在众多应用中,几乎每一款应用都有自己的Splash用户引导界面,该界面在用户首次启动展示,之后不会显示,主要向用户展示新功能. 分析 主要使用ViewPager+Indicator实现 主要是实现一个圆形指示器,这个圆形指示器继承LinearLayout,需要有一些属性可以自定义,比如指示器的颜色,大小,边距等 这个指示器也可以自动滚动,比如应用在幻灯片展示的地方 指示器是圆形的,需要我们自己绘制 这个圆形指示器实现了ViewPager.OnPageChangeListener接口 实现 定义自