首页 > 系统 > Android > 正文

Android ViewPager实现Banner循环播放

2019-12-12 05:18:40
字体:
来源:转载
供稿:网友

问题的起源
在项目里,有时候需要实现一个图片轮播的效果,用来展示Banner。同时,图片能循环播放,下面还有一排小圆点来指示当前轮播到哪一页了。

如下图:


分析
・ 图片的个数是会变化的,同时小圆点的个数也会跟着图片个数变化
・ 每一个page的布局是一样的。变化的就是小圆点的个数,所以需要用代码来动态生成小圆点

编码
布局
首先完成 MainActivity 的布局 activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" > <!-- ViewPager --> <android.support.v4.view.ViewPager  android:id="@+id/viewpager"  android:layout_width="fill_parent"  android:layout_height="180dip" /> <LinearLayout  android:layout_width="fill_parent"  android:layout_height="wrap_content"  android:layout_alignBottom="@id/viewpager"  android:background="#44000000"  android:gravity="center"  android:orientation="vertical"  android:padding="5dip" >  <!-- Banner的文字描述 -->  <TextView   android:id="@+id/tv_banner_text_desc"   android:layout_width="wrap_content"   android:layout_height="wrap_content"   android:textColor="@android:color/white" />  <!-- 小圆点的父控件 -->  <LinearLayout   android:id="@+id/ll_dot_group"   android:layout_width="fill_parent"   android:layout_height="wrap_content"   android:layout_gravity="center_horizontal"   android:layout_marginTop="5dip"   android:gravity="center_horizontal"   android:orientation="horizontal" >  </LinearLayout> </LinearLayout></RelativeLayout>

因为小圆点共有两种状态,一个是 enable 为 true 的状态,和 enable 为 false 的状态。所以需要为小圆点编写一个 selector 的 xml 配置文件,放在 drawable 文件夹中。这里,为它命名为 dot_bg_selector.xml

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/point_bg_enable" android:state_enabled="true"></item> <item android:drawable="@drawable/point_bg_normal" android:state_enabled="false"></item></selector>

还需要再写两个 xml 文件,作为小圆点在不同状态下的样式
point_bg_enable.xml

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" > <corners android:radius="0.5dip" /> <solid android:color="#aaFFFFFF" /></shape>

point_bg_normal.xml

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" > <corners android:radius="0.5dip" /> <solid android:color="#55000000" /></shape>

准备图片资源
我在 res/drawable-hdpi 文件夹中放置了几张图片,以演示用


开始编码
代码都加上详细注释了,大家可以看看。有不明白的欢迎指出来

package com.owen.adbanner;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.os.Bundle;import android.os.SystemClock;import android.support.v4.view.PagerAdapter;import android.support.v4.view.ViewPager;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.Toast;import android.widget.LinearLayout.LayoutParams;import android.widget.TextView;/** * ViewPager实现Banner循环滚动 *  * @author owen */public class MainActivity extends Activity { /** ViewPager中ImageView的容器 */ private List<ImageView> imageViewContainer = null; /** 上一个被选中的小圆点的索引,默认值为0 */ private int preDotPosition = 0; /** Banner文字描述数组 */ private String[] bannerTextDescArray = {    "巩俐不低俗,我就不能低俗",    "朴树又回来了,再唱经典老歌引万人大合唱",   "揭秘北京电影如何升级",    "乐视网TV版大派送", "热血丝的反杀"  }; /** Banner滚动线程是否销毁的标志,默认不销毁 */ private boolean isStop = false; /** Banner的切换下一个page的间隔时间 */ private long scrollTimeOffset = 5000; private ViewPager viewPager; /** Banner的文字描述显示控件 */ private TextView tvBannerTextDesc; /** 小圆点的父控件 */ private LinearLayout llDotGroup; @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  initView();  startBannerScrollThread(); } /**  * 开启Banner滚动线程  */ private void startBannerScrollThread() {  new Thread(new Runnable() {   @Override   public void run() {    while (!isStop) {     //每个两秒钟发一条消息到主线程,更新viewpager界面     SystemClock.sleep(scrollTimeOffset);     runOnUiThread(new Runnable() {      public void run() {       int newindex = viewPager.getCurrentItem() + 1;       viewPager.setCurrentItem(newindex);      }     });    }   }  }).start(); } @Override protected void onDestroy() {  // 销毁线程  isStop = true;  super.onDestroy(); } private void initView() {  viewPager = (ViewPager) findViewById(R.id.viewpager);  llDotGroup = (LinearLayout) findViewById(R.id.ll_dot_group);  tvBannerTextDesc = (TextView) findViewById(R.id.tv_banner_text_desc);  imageViewContainer = new ArrayList<ImageView>();  int[] imageIDs = new int[] {     R.drawable.a,     R.drawable.b,     R.drawable.c,    R.drawable.d,    R.drawable.e,   };  ImageView imageView = null;  View dot = null;  LayoutParams params = null;  for (int id : imageIDs) {   imageView = new ImageView(this);   imageView.setBackgroundResource(id);   imageViewContainer.add(imageView);   // 每循环一次添加一个点到线行布局中   dot = new View(this);   dot.setBackgroundResource(R.drawable.dot_bg_selector);   params = new LayoutParams(5, 5);   params.leftMargin = 10;   dot.setEnabled(false);   dot.setLayoutParams(params);   llDotGroup.addView(dot); // 向线性布局中添加"点"  }  viewPager.setAdapter(new BannerAdapter());  viewPager.setOnPageChangeListener(new BannerPageChangeListener());  // 选中第一个图片、文字描述  tvBannerTextDesc.setText(bannerTextDescArray[0]);  llDotGroup.getChildAt(0).setEnabled(true);  viewPager.setCurrentItem(0); } /**  * ViewPager的适配器  */ private class BannerAdapter extends PagerAdapter {  @Override  public void destroyItem(ViewGroup container, int position, Object object) {   container.removeView(imageViewContainer.get(position % imageViewContainer.size()));  }  @Override  public Object instantiateItem(ViewGroup container, int position) {   View view = imageViewContainer.get(position % imageViewContainer.size());   // 为每一个page添加点击事件   view.setOnClickListener(new View.OnClickListener() {    @Override    public void onClick(View v) {     Toast.makeText(MainActivity.this, "Page 被点击了", Toast.LENGTH_SHORT).show();    }   });   container.addView(view);   return view;  }  @Override  public int getCount() {   return Integer.MAX_VALUE;  }  @Override  public boolean isViewFromObject(View view, Object object) {   return view == object;  } } /**  * Banner的Page切换监听器  */ private class BannerPageChangeListener implements ViewPager.OnPageChangeListener {  @Override  public void onPageScrollStateChanged(int arg0) {   // Nothing to do  }  @Override  public void onPageScrolled(int arg0, float arg1, int arg2) {   // Nothing to do  }  @Override  public void onPageSelected(int position) {   // 取余后的索引,得到新的page的索引   int newPositon = position % imageViewContainer.size();   // 根据索引设置图片的描述   tvBannerTextDesc.setText(bannerTextDescArray[newPositon]);   // 把上一个点设置为被选中   llDotGroup.getChildAt(preDotPosition).setEnabled(false);   // 根据索引设置那个点被选中   llDotGroup.getChildAt(newPositon).setEnabled(true);   // 新索引赋值给上一个索引的位置   preDotPosition = newPositon;  } }}

参考来源
http://blog.csdn.net/allen315410/article/details/39294343
https://github.com/331637495/BannerDemo

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表