引导页???这是多少人写过的啊,还写,猪吗?
相信很多小伙伴就已经火大了。
其实呢,主要是我进入职场的头一个月基本上就全泡在了引导页上,遇见过各种奇葩心塞的bug
所以在此,想写一系列关于此类的博文
基本路线是:先从ViewPager静态引导页讲起,然后是ViewPager静态页的翻页动画,ViewPager简单动画引导页,SurfaceView复杂型动画引导页
废话不多说,一步步来。先来看看guide_layout.xml文件,这个是引导页的显示页
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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/guide_view_group"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</android.support.v4.view.ViewPager>
</LinearLayout>里面就是一个ViewPager,如果没有v4的包,需要自己动态添加以下,这里就不介绍怎么添加v4包了
然后看看引导页的子页,就是滑动的每一页的布局文件,guide_item_view.xml,个人比较懒所以会对这个布局进行复用,形成4个子页。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >
<TextView android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="48sp"
android:text="0"/>
</LinearLayout>
然后来看看Java代码,其实基础型的引导页结构还是很简单的
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
public class GuidanceActivity extends Activity{
private ViewPager mViewPager ;
private PagerAdapter mPagerAdapter ;
private List<View> mListViews ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.guide_layout) ;
mListViews = new ArrayList<View>() ;
LayoutInflater inflater = getLayoutInflater() ;
View view1 = inflater.inflate(R.layout.guide_item_view, null) ;
view1.setBackgroundColor(getResources().getColor(android.R.color.holo_blue_dark)) ;
((TextView) view1.findViewById(R.id.tv)).setText("0") ;
View view2 = inflater.inflate(R.layout.guide_item_view, null) ;
view2.setBackgroundColor(getResources().getColor(android.R.color.holo_red_dark)) ;
((TextView) view2.findViewById(R.id.tv)).setText("1") ;
View view3 = inflater.inflate(R.layout.guide_item_view, null) ;
view3.setBackgroundColor(getResources().getColor(android.R.color.holo_orange_dark)) ;
((TextView) view3.findViewById(R.id.tv)).setText("2") ;
View view4 = inflater.inflate(R.layout.guide_item_view, null) ;
view4.setBackgroundColor(getResources().getColor(android.R.color.holo_green_dark)) ;
((TextView) view4.findViewById(R.id.tv)).setText("3") ;
mListViews.add(view1) ;
mListViews.add(view2) ;
mListViews.add(view3) ;
mListViews.add(view4) ;
mViewPager = (ViewPager) findViewById(R.id.guide_view_group);
mPagerAdapter = new PagerAdapter(mListViews) ;
mViewPager.setAdapter(mPagerAdapter) ;
}
private class PagerAdapter extends android.support.v4.view.PagerAdapter {
private List<View> mViews ;
public PagerAdapter(List<View> views) {
super() ;
mViews = views ;
}
@Override
public int getCount() {
return mViews.size();
}
@Override
public boolean isViewFromObject(View v, Object obj) {
return v == obj;
}
@Override
public void destroyItem(View view, int position, Object object) {
((ViewPager) view).removeView(mViews.get(position));
}
@Override
public Object instantiateItem(View view, int position) {
((ViewPager) view).addView(mViews.get(position), 0);
return mViews.get(position);
}
}
}
最后来分析分析,
mListViews装你想要显示的几个子页,我这里写了4个页面
private List<View> mListViews ;
获取inflater对象来初始化四个View,inflater可以有很多种方式获取,在Activity中可以直接getLayoutInflater(),如果只是在某个View中想获取此对象,可以使用Context<这是上下文,也是一个很重要很重要的家伙>,以后再专门讲讲
LayoutInflater inflater = getLayoutInflater() ;
View view1 = inflater.inflate(R.layout.guide_item_view, null) ;
view1.setBackgroundColor(getResources().getColor(android.R.color.holo_blue_dark)) ;
((TextView) view1.findViewById(R.id.tv)).setText("0") ;
View view2 = inflater.inflate(R.layout.guide_item_view, null) ;
view2.setBackgroundColor(getResources().getColor(android.R.color.holo_red_dark)) ;
((TextView) view2.findViewById(R.id.tv)).setText("1") ;
View view3 = inflater.inflate(R.layout.guide_item_view, null) ;
view3.setBackgroundColor(getResources().getColor(android.R.color.holo_orange_dark)) ;
((TextView) view3.findViewById(R.id.tv)).setText("2") ;
View view4 = inflater.inflate(R.layout.guide_item_view, null) ;
view4.setBackgroundColor(getResources().getColor(android.R.color.holo_green_dark)) ;
((TextView) view4.findViewById(R.id.tv)).setText("3") ;之后就来讲讲PagerAdapter,在类中自己新建一个Adapter类继承v4包中的PagerAdapter
public PagerAdapter(List<View> views) {
super() ;
mViews = views ;
}上面的代码是指在adapter初始化的时候,将之前定义的四个view的容器mListViews传进来
然后,在Adapter里面分别对每一个view操作即可
@Override
public int getCount() {
return mViews.size();
}获取有多少个子页。
@Override
public boolean isViewFromObject(View v, Object obj) {
return v == obj;
}这个方法呢,说白了就是为了看public Object instantiateItem(View view, int position)这个方法返回的object是否和view有关,额,如果想深入了解的话,最好直接看看源码
@Override
public Object instantiateItem(View view, int position) {
((ViewPager) view).addView(mViews.get(position), 0);
return mViews.get(position);
}动态加入每一个子页view,看这个函数返回的对象是Object就知道,这个函数不一定就是返回view,也可以是其他的
还有一个函数,虽然在demo中可加,可不加。但是也是让人头疼的,也是让人喜欢的函数
@Override
public void destroyItem(View view, int position, Object object) {
((ViewPager) view).removeView(mViews.get(position));
}
先说它的作用,在吐槽吐槽。
其实在ViewPager中对引导页是只加载当前页的下一页和上一页的,其他的页都会直接调用此函数摧毁掉,也可以看做是做释放内存的操作。
像这种摧毁性的和释放性的函数,是很让人不喜欢的,因为一旦它出现了,势必就要深刻理会它们的重要性,理由只有一个,因为它们直接和你的代码中的bug数联系上了其实在demo中对他的需求还不是很明显,因为一个demo就是引导页,所以对内存的分配可以土豪点,但是当引导页仅仅是作为程序中很小很小的一部分时,那我就要重新审视它们了。
讲一个案例:我在写动态引导页的时候,由于背景xxh的比较大,所以直接加到内存中,然后再有许多页面中的动画,程序立马outofmemory,内存溢出了,这个是很头疼的一件事,特别是在动画页中还有AnimationDrawable动画的时候,需要特别的小心,所以就要终点使用destroyItem函数了,上面的例子在此函数里面只是做摧毁item页面的操作,其实在实际中,要做的还有很多资源内存回收的操作,因为这些资源你不去主动释放,哪怕是在你的引导页不报outofmemeory,一旦进入程序,加载一些其他的资源很大可能就Crash掉了。这些在之后的博文中一一列出。
今天就到这里了,把代码放上来:代码下载,都是不要钱的哟,小伙伴们捧个场就行了!
本文探讨了在Android开发中如何实现ViewPager静态引导页,并详细讲述了ViewPager的工作原理,包括页面加载策略和内存管理。作者通过实例分享了如何处理可能导致内存溢出的问题,特别是涉及大图和动画时。此外,文章还预告了后续将讨论更复杂的ViewPager动画引导页和SurfaceView动画引导页。

被折叠的 条评论
为什么被折叠?



