从之前入门Android,一步一步的走到现在,过程真的难于言表,只有经历过的人才知道吧,理解初学Android时痛苦,所以现在在Android上略窥门径的时候,回过头来写一些小Demo,希望能够帮助到需要的人,后面有空会经常写一些实例Demo。
废话不多说,这次讲解APP的引导页启动页,我使用在代码中加入详细的注释的方式进行讲解,对于以下不经常出现的API我都进行了注解,接下来直接开始吧。
先上效果图(PS:动态图没来得及做,时间好晚了,可以直接下载我的项目运行,附GitHub链接):
java包如图:
WelcomeActivity.java
package com.example.power.welcomepage;
import android.app.Activity;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import com.example.power.welcomepage.Activity.MainActivity;
import com.example.power.welcomepage.Activity.WelcomeGuideActivity;
import com.example.power.welcomepage.Util.SharedPreferencesUtil;
public class WelcomeActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/*首先启动该Activity,并判断是否是第一次启动,注意,需要添加默认值,
* 如果是第一次启动,则先进入功能引导页*/
boolean isFirstOpen = SharedPreferencesUtil.getBoolean(this, SharedPreferencesUtil.FIRST_OPEN, true);
if(isFirstOpen){
Intent intent = new Intent(this, WelcomeGuideActivity.class);
startActivity(intent);
/*注意,需要使用finish将该activity进行销毁,否则,在按下手机返回键时,会返回至启动页*/
finish();
return;
}
/*如果不是第一次启动app,则启动页*/
setContentView(R.layout.activity_welcome);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
/*2秒后进入主页*/
enterHomeActivity();
}
},2000);
}
private void enterHomeActivity(){
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
}
}
WelcomeGuideActivity.java
package com.example.power.welcomepage.Activity;
import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import com.example.power.welcomepage.Adapter.GuideViewPagerAdapter;
import com.example.power.welcomepage.R;
import com.example.power.welcomepage.Util.SharedPreferencesUtil;
import com.example.power.welcomepage.WelcomeActivity;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Power on 2018/11/2.
*/
public class WelcomeGuideActivity extends Activity implements View.OnClickListener {
private ViewPager viewPager;
private GuideViewPagerAdapter adapter;
private List<View> views;
private Button startBtn;
/*引导页图片资源*/
private static final int[] pics = { R.layout.guid_view1,
R.layout.guid_view2, R.layout.guid_view3, R.layout.guid_view4 };
/*底部小点图片*/
private ImageView[] dots;
/*用于记录当前选中位置*/
private int currentIndex;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_guide);
views = new ArrayList<View>();
/*初始化引导页视图列表,需要对资源进行处理*/
for(int i = 0; i < pics.length; i++){
View view = LayoutInflater.from(this).inflate(pics[i], null);
if(i == pics.length - 1){
startBtn = (Button)view.findViewById(R.id.btn_login);
/*这里使用setTag方法进行标注。在View中的setTag(Onbect)表示给View
添加一个格外的数据,以后可以用getTag()将这个数据取出来。可以用在
多个Button添加一个监听器,每个Button都设置不同的setTag。这个监听
器就通过getTag来分辨是哪个Button 被按下。*/
startBtn.setTag("enter");
startBtn.setOnClickListener(this);
}
views.add(view);
}
viewPager = (ViewPager)findViewById(R.id.vp_guide);
/*初始化adapter*/
adapter = new GuideViewPagerAdapter(views);
viewPager.setAdapter(adapter);
/*需要设置页面改变的监听器,这样我们能把我页面改变时的具体操作细节,所以
需要创建PageChangeListener,实现OnPageChangeListener接口*/
viewPager.addOnPageChangeListener(new PageChangeListener());
initDots();
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onPause() {
super.onPause();
/*如果切换到后台,就设置下次不进入功能引导页*/
SharedPreferencesUtil.setBoolean(WelcomeGuideActivity.this, SharedPreferencesUtil.FIRST_OPEN, false);
finish();
}
@Override
protected void onStop() {
super.onStop();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
private void initDots(){
LinearLayout linearLayout = (LinearLayout)findViewById(R.id.ll);
dots = new ImageView[pics.length];
/*循环取得小点图片*/
for(int i = 0; i < pics.length; i++){
/*得到一个LinearLayout下面的每一个子元素*/
dots[i] = (ImageView)linearLayout.getChildAt(i);
dots[i].setEnabled(false);//设置成灰色
dots[i].setOnClickListener(this);
dots[i].setTag(i);//设置位置tag,方便取出与当前位置对应,原理同上
}
currentIndex = 0;
dots[currentIndex].setEnabled(true); // 设置为白色,即选中状态
}
/**
* 设置当前view
*
* @param position
*/
private void setCurrentView(int position){
if(position < 0 || position > pics.length){
return;
}
viewPager.setCurrentItem(position);
}
/**
* 设置当前指示点
*
* @param position
*/
private void setCurDot(int position) {
if (position < 0 || position > pics.length || currentIndex == position) {
return;
}
dots[position].setEnabled(true);
dots[currentIndex].setEnabled(false);
currentIndex = position;
}
@Override
public void onClick(View v) {
if(v.getTag().equals("enter")){
enterMainActivity();
return;
}
int position = (Integer) v.getTag();
setCurrentView(position);
setCurDot(position);
}
private void enterMainActivity(){
Intent intent = new Intent(WelcomeGuideActivity.this, WelcomeActivity.class);
startActivity(intent);
SharedPreferencesUtil.setBoolean(WelcomeGuideActivity.this, SharedPreferencesUtil.FIRST_OPEN, false);
finish();
}
private class PageChangeListener implements ViewPager.OnPageChangeListener{
/*当滑动状态改变时调用*/
@Override
public void onPageScrollStateChanged(int state) {
/*arg0 ==1的时辰默示正在滑动,arg0==2的时辰默示滑动完毕了,arg0==0的时辰默示什么都没做。*/
}
/*当前页面被滑动时调用*/
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// arg0 :当前页面,及你点击滑动的页面
// arg1:当前页面偏移的百分比
// arg2:当前页面偏移的像素位置
}
/*当新的页面被选中时调用*/
@Override
public void onPageSelected(int position) {
setCurDot(position);
}
}
}
SharedPreferencesUtil.java
package com.example.power.welcomepage.Util;
import android.content.Context;
import android.content.SharedPreferences;
/**
* Created by Power on 2018/11/2.
*/
/*我们使用SharedPreferences的数据储存方式进行存取,所以我们创建这个工具类进行封装操作,较为方便可行。
* 在这里我以我们要使用到的getBoolean和setBoolean进行举例讲解,其余类型原理一致*/
public class SharedPreferencesUtil {
private static final String FILE_NAME = "welcomePage";
public static final String FIRST_OPEN = "first_open";
public static Boolean getBoolean(Context context, String strKey,
Boolean strDefault){
/*使用Context.MODE_PRIVATE模式创建shared preference文件,意味着只用本应用程序
* 能够使用,还包括MODE_WORLD_READABLE或者MODE_WORLD_WRITEABLE 模式的,这两种
* 模式下,其他任何app均可通过文件名访问该文件。*/
SharedPreferences sharedPreferences = context.getSharedPreferences(
FILE_NAME, Context.MODE_PRIVATE
);
/*在文件中获取一个Boolean类型值,strDefault是默认值,可以省略,其意义是查找的
key不存在时函数的返回值。*/
Boolean result = sharedPreferences.getBoolean(strKey, strDefault);
return result;
}
public static Boolean getBoolean(Context context, String strKey) {
SharedPreferences setPreferences = context.getSharedPreferences(
FILE_NAME, Context.MODE_PRIVATE);
Boolean result = setPreferences.getBoolean(strKey, false);
return result;
}
public static void setBoolean(Context context, String strKey,
Boolean strData){
SharedPreferences sharedPreferences = context.getSharedPreferences(
FILE_NAME, Context.MODE_PRIVATE
);
/*往shared preference文件中写入值时,我们需要用到SharedPreferences.Editor*/
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean(strKey, strData);
editor.commit();
}
public static String getString(Context context, String strKey) {
SharedPreferences setPreferences = context.getSharedPreferences(
FILE_NAME, Context.MODE_PRIVATE);
String result = setPreferences.getString(strKey, "");
return result;
}
public static String getString(Context context, String strKey,
String strDefault) {
SharedPreferences setPreferences = context.getSharedPreferences(
FILE_NAME, Context.MODE_PRIVATE);
String result = setPreferences.getString(strKey, strDefault);
return result;
}
public static void setString(Context context, String strKey, String strData) {
SharedPreferences activityPreferences = context.getSharedPreferences(
FILE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = activityPreferences.edit();
editor.putString(strKey, strData);
editor.commit();
}
public static int getInt(Context context, String strKey) {
SharedPreferences setPreferences = context.getSharedPreferences(
FILE_NAME, Context.MODE_PRIVATE);
int result = setPreferences.getInt(strKey, -1);
return result;
}
public static int getInt(Context context, String strKey, int strDefault) {
SharedPreferences setPreferences = context.getSharedPreferences(
FILE_NAME, Context.MODE_PRIVATE);
int result = setPreferences.getInt(strKey, strDefault);
return result;
}
public static void setInt(Context context, String strKey, int strData) {
SharedPreferences activityPreferences = context.getSharedPreferences(
FILE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = activityPreferences.edit();
editor.putInt(strKey, strData);
editor.commit();
}
public static long getLong(Context context, String strKey) {
SharedPreferences setPreferences = context.getSharedPreferences(
FILE_NAME, Context.MODE_PRIVATE);
long result = setPreferences.getLong(strKey, -1);
return result;
}
public static long getLong(Context context, String strKey, long strDefault) {
SharedPreferences setPreferences = context.getSharedPreferences(
FILE_NAME, Context.MODE_PRIVATE);
long result = setPreferences.getLong(strKey, strDefault);
return result;
}
public static void setLong(Context context, String strKey, long strData) {
SharedPreferences activityPreferences = context.getSharedPreferences(
FILE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = activityPreferences.edit();
editor.putLong(strKey, strData);
editor.commit();
}
}
GuideViewPagerAdapter.java
package com.example.power.welcomepage.Adapter;
import android.support.annotation.NonNull;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;
import java.util.List;
/**
* Created by Power on 2018/11/2.
*/
/*我们需要使用适配器来帮助我们更方便的使用ViewPager*/
public class GuideViewPagerAdapter extends PagerAdapter {
private List<View> views;
public GuideViewPagerAdapter(List<View> views){
super();
this.views = views;
}
@Override
public int getCount() {
if(views != null){
return views.size();
}
return 0;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
((ViewPager)container).removeView(views.get(position));
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == ((View)object);
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
((ViewPager)container).addView(views.get(position), 0);
return views.get(position);
}
}
XML资源文件
guid_view1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@mipmap/welcomimg3"/>
<!--我们在使用imageview时一些图片的尺寸大小比例不一样,为了让所有图片都
能填充整个imageview,就可以使用这个属性,它可以让图片保持原有比例充满imageview,
并将超出屏幕的部分裁剪掉。-->
</LinearLayout>
guid_view2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@mipmap/welcomimg5"/>
</LinearLayout>
guid_view3.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@mipmap/welcomimg6"/>
</LinearLayout>
guid_view4.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--第四个View布局(也就是放置按钮的那个布局)要使用FrameLayout
因为需要使用Button在ImageView上方,普通的线性布局做不到,所以需
要使用帧布局(FrameLayout),即后定义的布局在上方,一层一层叠加-->
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@mipmap/welcomimg11"/>
<!--正规来讲,应该尽量把宽度高度等值放在values的资源文件中,
这里为了方便,直接写在了布局文件中-->
<Button
android:id="@+id/btn_login"
android:layout_width="160dp"
android:layout_height="42dp"
android:layout_gravity="bottom|center_horizontal"
android:layout_marginBottom="100dp"
android:background="@drawable/button_shape"
android:text="立刻体验"
android:textColor="#ce102c"
android:textSize="18sp"
android:visibility="visible"/>
</FrameLayout>
activity_guide.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="@+id/vp_guide"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
<LinearLayout
android:id="@+id/ll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="24.0dip"
android:orientation="horizontal" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:clickable="true"
android:padding="10.0dip"
android:src="@drawable/dot_selector" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:clickable="true"
android:padding="10.0dip"
android:src="@drawable/dot_selector" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:clickable="true"
android:padding="10.0dip"
android:src="@drawable/dot_selector" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:clickable="true"
android:padding="10.0dip"
android:src="@drawable/dot_selector" />
</LinearLayout>
</RelativeLayout>
以上就是较为核心的代码,想要了解整个项目的小伙伴,可以下载源码查看哦,里面进行了详细的注解。