本人攥写的目的旨在学习View Pager的使用,并实现当下大多数app的广告条的使用!
闲言少叙,开撸:
首先从布局着手(本人写代码通常是从布局开始的,自认为布局有时比代码更重要!)
根据最终效果在这里我选择的是:RelativeLayout:RelativeLayout:android.support.v4.view.ViewPager:LinearLayout:TextView、LinearLayout
的结构;
具体步骤:第一部分:广告图片的显示:
1、在MainActivity中声明布局中的viewPager,并将其初始化;
2、添加图片int[] ids ;
3、设置适配器:这里用到的适配器为PagerAdapter(抽象类):是系统为ViewPager提供的适配器;
在使用时至少Override以下4个方法:
1、getCount():用于返回数据的总数;
2、instantiateItem(ViewGroup container, int position):用于实例化显示内容;container容器用来添加要显示的内容;position位置用来找到要添加的内容;
3、isViewFromObject(View view, Object object):这是个返回boolean值;用于判断当前页面和创建的页面是否是同一个页面,如果不重写该方法,则不会显示图片;
4、destroyItem(ViewGroup container, int position, Object object):把当前的页面销毁,个人理解:view pager默认创建2个页面最多3个(可以认为如同List view的适配器一样系统内部已经为我们做了优化了)如果不重写该方法,系统就会崩溃
以上是第一部分代码
第二部分:图片文本的显示:
1、在MainActivity中声明布局中的tv_title,并将其初始化;
2、添加文本String[] imageDescriptions ;
3、设置页面滑动监听;addOnPageChangeListener(new MyOnPageChangeListener());
使用OnPageChangeListener事件Override以下3个方法:
1、onPageScrolled(int position, float positionOffset, int positionOffsetPixels)当前页面滚动了时候回调
2、onPageSelected(int position)当选中某个页面的时候回调
3、onPageScrollStateChanged(int state)当页面的状态发生了变化的时候回调
这是第二部分代码
第三部分:图片变化指示点的随之变化:
1、在MainActivity中声明布局中的ll_point_group,并将其初始化;声明一个int变量prePosition在android中常使用这种方式进行当前和上一个状态变化交替
2、指示点的数量取决于图片的数量循环遍历即可,从本质上讲这个指示点是一个ImageView所以创建新的imageView给其添加背景让其显示
3、在这里指示点的imageView应用了(selector+shape)的方法制作,并对其进行了微调;
4、在循环的开始让position=0的位置一开始就显示出来,避免了打开app没有指示点选中的尴尬;
5、在onPageSelected(int position)方法中应用prePosition(前一个)和position(当前这个)状态的不同设置完成选中不同页面的时候指示点的交替;
第三部分代码
第四部分:左右无限循环
应用思想,给数组或集合一个很大的值让其定位在这个值的中间,只要这个值够大就能做到无限循环的目的,这个值为Integer.MAX_VALUE;大概21.7亿
在这还用到view pager的一个方法setCurrentItem(int item),指定view pager从哪一条开始;
循环部分代码
第五部分:图片的自动循环播放
1、应用handler发送消息,让viewPager获取当前的Item让后让其以1为单位自增,以达到实现自增的目的;
2、此时在页面处于空闲、拖拽和惯性等不同的状态的时候分别发送消息或移除消息以达到可能出现的一些bug;
最后一部分代码;
以下是源代码部分包括layout,mainActivity,适配器及其他可能用到的类都写在了main中,selecter和shape:
<?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">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="180dp">
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="wrap_content"
android:layout_height="180dp" />
<LinearLayout
android:padding="5dp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/viewPager"
android:background="#44000000"
android:orientation="vertical">
<TextView
android:id="@+id/tv_title"
android:textColor="#ffffff"
android:text="速度与激情8"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout
android:id="@+id/ll_point_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="horizontal"
android:padding="5dp" />
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
以上是布局部分
import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private ViewPager viewPager; //图片集合 private int[] ids = {R.drawable.a, R.drawable.b, R.drawable.c, R.drawable.d, R.drawable.e}; private TextView tv_title; // 图片标题集合 private final String[] imageDescriptions = { "首创一站式企业服务!", "拼搏进取!", "搞笑我们是认真的!", "精益求精!", "新手导航,装机必备!" }; private LinearLayout ll_point_group; private int prePosition; private Handler handler =new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); int itemposition =viewPager.getCurrentItem() +1; viewPager.setCurrentItem(itemposition); sendEmptyMessageDelayed(0,2000); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); viewPager = (ViewPager) findViewById(R.id.viewPager); tv_title = (TextView) findViewById(R.id.tv_title); ll_point_group = (LinearLayout) findViewById(R.id.ll_point_group); initView(); } private void initView() { //viewPager设置一个新创建的适配器 viewPager.setAdapter(new MyPageAdapter()); //监听页面的滑动变化(通过创建一个内部类提供方法来完成对页面滑动的监听事件)针对页面的滑动添加文本等 viewPager.addOnPageChangeListener(new MyOnPageChangeListener()); //先设置第一条的文本先,确保app一打开就显示出第一条文本 tv_title.setText(imageDescriptions[0]); //根据图片集合的元素的数量设置指示点 for (int i = 0; i < ids.length; i++) { //指示点在android中本质上是ImageView(创建一个ImageView) ImageView imageView = new ImageView(MainActivity.this); //在布局文件中已经设置了小指示点但还需要在代码中稍微调整一下,如果已经调好则可不需要这段(以下3行) LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(-2, ViewGroup.LayoutParams.WRAP_CONTENT); params.leftMargin = 10; imageView.setLayoutParams(params); //给小指示点设置背景(这里用selector+shape方法) imageView.setBackgroundResource(R.drawable.point_selector); //这段代码类似于设置第一条文本,让其一打开app便可选择第一个点 if (i == 0) { imageView.setSelected(true); } else { imageView.setSelected(false); } ll_point_group.addView(imageView); } int itemposition = Integer.MAX_VALUE / 2 - Integer.MAX_VALUE / 2 % ids.length; viewPager.setCurrentItem(itemposition); //一打开就让其发送消息 handler.sendEmptyMessageDelayed(0, 2000); } //ViewPage有属于自己的适配器,其用法和list View等的适配器有些相似 private class MyPageAdapter extends PagerAdapter { //返回图片的总的数量 @Override public int getCount() { return Integer.MAX_VALUE; } @Override public Object instantiateItem(ViewGroup container, int position) { //创建一个图片视图 ImageView imageView = new ImageView(MainActivity.this); //将图片集合作为背景资源添加到这个图片视图中 imageView.setBackgroundResource(ids[position % ids.length]); //将带有背景的图片视图添加到container中 container.addView(imageView); return imageView; } //判断当前页面和创建的页面是否是同一个页面,如果不从写该方法则不会显示图片 @Override public boolean isViewFromObject(View view, Object object) { // return true; return view == object; } //把当前的页面销毁的方法 @Override public void destroyItem(ViewGroup container, int position, Object object) { // super.destroyItem(container, position, object); container.removeView((View) object); } } private class MyOnPageChangeListener implements ViewPager.OnPageChangeListener { //当前页面滚动了的时候回调 @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } //当选中某个页面的时候回调 @Override public void onPageSelected(int position) { int realPosition = position % ids.length; //设置页面滑动时文本随之变化 tv_title.setText(imageDescriptions[realPosition]); //设置页面滑动时指示点也随着变化(当选中当前的页面的时候之前的画面就变成false不在显示颜色) ll_point_group.getChildAt(prePosition).setSelected(false); ll_point_group.getChildAt(realPosition).setSelected(true); prePosition = realPosition; } //当页面状态发生了变化的时候回调 @Override public void onPageScrollStateChanged(int state) { if(state == ViewPager.SCROLL_STATE_IDLE) { handler.removeCallbacksAndMessages(null); handler.sendEmptyMessageDelayed(0,2000); }else if(state==ViewPager.SCROLL_STATE_DRAGGING) { handler.removeCallbacksAndMessages(null); }else if(state==ViewPager.SCROLL_STATE_SETTLING) { } } } @Override protected void onDestroy() { super.onDestroy(); if(handler!=null) { handler.removeCallbacksAndMessages(null); } } }
以上是mainActivity 部分代码
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/point_normal" android:state_selected="false" /> <item android:drawable="@drawable/point_selected" android:state_selected="true" /> </selector>
selector部分代码上面
下面是shape部分两段代码:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#f00000" /> <corners android:radius="10dp" /> <size android:width="12dp" android:height="3dp" /> </shape>
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#44000000" /> <corners android:radius="10dp" /> <size android:width="12dp" android:height="3dp" /> </shape>