下面我们来看一页一页滑动的介绍页面如何实现。
首先在WkyLib工程中定义应用介绍基类WkyAppTourActivity,在本类中,我们用ViewPager来实现介绍页面一页一页滑动的功能。该Activity的布局文件如下所示:
<?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"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/linearLayout01"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<android.support.v4.view.ViewPager
android:id="@+id/tourPages"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="20dp"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/stepBar"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:gravity="center"
android:orientation="horizontal" >
</LinearLayout>
</RelativeLayout>
</FrameLayout>
我们首先在WkyAppTourActivity类中定义需要用到的属性,我们将介绍页面的ID保存在images中,而对应的ImageView保存在imageViews中,然后用一个ViewGroup来进行管理,而最后一页进入应用也是一介单独的ImageView。
protected WkyApplication application = null;
protected ViewPager tourPages;
protected List<ImageView> imageViews;
// 包裹小圆点的LinearLayout
protected ViewGroup stepBar;
protected ImageView enterAppImgv;
protected int[] images = null;
因为每个应用所用的介绍图片都不相同,所以在WkyAppTourActivity类中定义了抽象方法prepareImages方法,该方法是将介绍页面的ID保存到images中:/**
* 实例化的应用程序通过定义本函数,将引导页面存入images里面
*/
abstract protected void prepareImages();
这个方法在每个具体应用的AppTourActivity中必须实现。下面是WkyAppTourActivity类的onCreate函数:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_app_intro);
getViewObjects();
setupActionListeners();
prepareImages();
setupTourImages();
}
/**
* 获取页面所有View,并赋给相应的属性,与IOS中IBOutlets类似
*/
private void getViewObjects() {
imageViews = new ArrayList<ImageView>();
stepBar = (ViewGroup) findViewById(R.id.stepBar);
tourPages = (ViewPager) findViewById(R.id.tourPages);
}
/**
* 设定界面中操作的消息响应函数,与IOS中IBAction类似
*/
private void setupActionListeners() {
tourPages.setOnPageChangeListener(new TourPageChangeListener());
}
/**
* 设置介绍页面,介绍页面下面表示进度的圆点
*/
private void setupTourImages() {
for (int i = 0; i < images.length; i++) {
ImageView imageView = new ImageView(this);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(14, 0, 14, 0);
imageView.setLayoutParams(lp);
// imageView.setPadding(20, 0, 20, 0);
imageViews.add(imageView);
if (i == 0) {
// 默认选中第一张图片
imageViews.get(i).setBackgroundResource(R.drawable.page_indicator_focused);
} else {
imageViews.get(i).setBackgroundResource(R.drawable.page_indicator);
}
stepBar.addView(imageViews.get(i));
}
tourPages.setAdapter(new TourPageAdapter());
}
onCreate方法的代码并不复杂,首先设置布局,然后获取页面中需要进行操作的View,然后是设置页面事件响应函数,最后是生成与介绍页面相同数量的空ImageView对象,并将其加入ViewGroup中进行管理。顺便提一句,上述代码全部加在onCreate方法中也是可以的,但是,如果想要让代码可维护性增强,小函数更有优势,而且同一个函数中,语句最是同一层级的,这些编码规范虽然看似没什么用,但是当回头维护代码时,你就会体会到这样写的重要性了。
下面是实现介绍图片一页一页滑动的ViewPager类及其实现:
// 指引页面数据适配器
class TourPageAdapter extends PagerAdapter {
@Override
public int getCount() {
return images.length;
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
@Override
public int getItemPosition(Object object) {
return super.getItemPosition(object);
}
@Override
public void destroyItem(ViewGroup container, int arg1, Object object) {
container.removeView((View) object);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
View view = createView(position);
container.addView(view, 0);
return view;
}
@SuppressWarnings("deprecation")
private View createView(int position) {
LayoutInflater mLayoutInflater = getLayoutInflater();
View view = mLayoutInflater.inflate(R.layout.app_tour_view_pager, null);
ImageView appTourImgv = (ImageView) view.findViewById(R.id.appTourImgv);
enterAppImgv = (ImageView) view.findViewById(R.id.enterAppImgv);
appTourImgv.setImageResource(images[position]);
WkyLayoutAdapter.setRectangleView(appTourImgv, 0.6141f);
if (position == images.length - 1) {
WkyLayoutAdapter.setRectangleView(enterAppImgv, 0.1179f, 1.2835f);
WkyLayoutAdapter.setViewMargin(enterAppImgv, 0.2017f);
enterAppImgv.setVisibility(View.VISIBLE);
enterAppImgv.setOnClickListener(mOnClickListener);
}
return view;
}
/**
* 进入应用ImageView的点击响应函数,由于是第一次运行,进入注册登录页面
* 1. 将firstRun置为false,下次应用启动将不再显示介绍页面
* 2. 进入注册登录页面
*/
private View.OnClickListener mOnClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
finishAppTour();
}
};
@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
}
@Override
public Parcelable saveState() {
return null;
}
@Override
public void startUpdate(View arg0) {
}
@Override
public void finishUpdate(View arg0) {
}
}
上面代码都比较简单,只是重点说一下onCreateView,页面中有一个介绍图片appTourImgv和一个进入应用的图片按钮enterAppImgv,当要显示某个介绍图片时,从images中找到ID,然后赋给appTourImgv来显示,如果是最后一张图片,将enterAppImgv置为可见,用户点击后调用finishAppTour方法。/**
* 进入注册登录页面
*/
abstract protected void goRegisterLoginActivity();
/**
* 由于是第一次运行,进入注册登录页面
* 1. 将firstRun置为false,下次应用启动将不再显示介绍页面
* 2. 进入注册登录页面
*/
protected void finishAppTour() {
application.setFirstRunToFalse();
goRegisterLoginActivity();
}
由于每个具体应用的注册登录页面可能不同,因此定义了抽象方法goRegisterLoginActivity方法,具体应用中必须实现这个方法。下面是处理ViewPager页面滑动的事件响应函数:
class TourPageChangeListener implements OnPageChangeListener {
@Override
public void onPageScrollStateChanged(int arg0) {
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageSelected(int arg0) {
if (arg0 == imageViews.size()) {
finishAppTour();
} else {
for (int i = 0; i < imageViews.size(); i++) {
imageViews.get(arg0).setBackgroundResource(
R.drawable.page_indicator_focused);
if (arg0 != i) {
imageViews.get(i).setBackgroundResource(
R.drawable.page_indicator);
}
}
}
}
}
这里的处理逻辑比较简单,如果是在最后一页还向后翻页,就直接进入注册登录页面,如果不是的话,更新下页代表进度的小圆点,表示当前已经浏览到第几张。还有界面调整工具类和常量存储的工具类,这里由于篇幅问题就不再贴上代码了,我们找一个下载地址,提供完整工程的下载,这样大家就可以看到完整的代码了。
下面是具体工程WkgJys,我们定义WkyAppTourActivity类的子类JysAppTourActivity类:
public class JysAppTourActivity extends WkyAppTourActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
application = (JysApplication)getApplication();
}
/**
* 启动注册登录页面,并关闭本页
* 【闫涛 2015.09.11】初始版本
*/
@Override
protected void goRegisterLoginActivity() {
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
}
/**
* 定义介绍页面,将ID保存到images数组中
* 【闫涛 2015.09.11】初始版本
*/
@Override
protected void prepareImages() {
images = new int [5];
images[0] = R.drawable.app_tour_01;
images[1] = R.drawable.app_tour_02;
images[2] = R.drawable.app_tour_03;
images[3] = R.drawable.app_tour_04;
images[4] = R.drawable.app_tour_05;
}
}
好了,大家运行程序,如果一切顺利的话,就可以看到多数应用具有的介绍页面了。
华丽的分隔线
******************************************************************************************************************************************************************************
希望大家多支持,有大家的支持,我才能走得更远,谢谢!
银行账号:622202 0200 1078 56128 闫涛
我的支付宝:yt7589@hotmail.com