Android的banner(轮播图)的实现
来源:互联网 发布:java 毫秒和秒的换算 编辑:程序博客网 时间:2024/05/21 10:16
本文使用了ViewPager来实现轮播图的功能,轮播的图片资源来源于网上。
一、思路
我们想要实现一个轮播图的功能,首先能想到的是使用ViewPager来实现,根据上一篇文章的内容
http://blog.csdn.net/llayjun/article/details/51362905,我们能想到有一个区别如下:
1、就是使得ViewPager实现启动页来无限的轮播图片
2、启动一个定时器来完成自动的轮播效果。
二、写布局代码
1、我们先是来看一下效果图,如何,还是可以的吧。
注意点:这一节对于上一节,有几处是不相同的。相对于ViewPager来实现启动页
1、上一节的指示器是固定在xml文件中写的,此一节,我们动态来实现。
2、主界面布局准备。
先把布局文件画好。在layout文件中的activity.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"> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="150dp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignBottom="@id/viewpager" android:background="#33000000" android:orientation="vertical" android:padding="5dp"> <TextView android:id="@+id/tv_bannertext" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:padding="5dp" android:text="我是第一个广告语" android:textColor="@android:color/white" /> <LinearLayout android:id="@+id/points" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:orientation="horizontal"> </LinearLayout> </LinearLayout></RelativeLayout>
注意点:
1、使用相对布局,可以是重叠效果更好的实现。
2、一共有三个部分,ViewPager,TextVeiw和指示器的LinearLayout
3、指示器动态生成
3、指示器布局代码
①实现点击效果布局代码drawable文件中point_selector.xml文件
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/v_point_up" android:state_enabled="true"></item> <item android:drawable="@drawable/v_point_down" android:state_enabled="false"></item></selector>
②点击效果文件drawable文件中v_point_down.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.5dp" /> <solid android:color="#55000000" /></shape>
③未点击效果文件drawable文件中v_point_up.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.5dp" /> <solid android:color="#AAFFFFFF" /></shape>
三、写Activity代码
思路:主要分为四个部分,我分别写在了四个方法里,
initView();初始化主布局中的控件,ViewPager,TextView,LinearLayout
initDate();初始化一些数据,包含:ViewPager的资源,根据轮播图的数量来动态生成指示器的数量
initAction();将ViewPager和指示器进行连接起来,这样子ViewPager滚动的时候才能带动指示器
initThread();开启一个线程来自动循环轮播图,在onDestory()方法中,关闭这个线程
我就直接上代码了,代码中注释也是非常清楚了。BannerActivity.java文件
public class BannerActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener, View.OnClickListener { //设置数据源集合 private List<BannerBean> listBannerBean; //设置视图的集合 private List<ImageView> listImageView; //ViewPager的声明 private ViewPager viewPager; private TextView textView; private LinearLayout linearLayout; //设置圆点View private View view; LinearLayout.LayoutParams layoutParams; //圆圈标志位置 private int pointIndex = 0; // 线程标志 private boolean isStop = false; //设置ViewPager适配器 private BannerAdapter bannerAdapter; //Volley加载网络图片 private RequestQueue mQueue; private ImageLoader mImageLoader; private ImageLoader.ImageListener imageListener; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_banner); initView(); initDate(); initAction(); initThread(); } private void initThread() { // 开启新线程,2秒一次更新Banner new Thread(new Runnable() { @Override public void run() { while (!isStop) { SystemClock.sleep(3000); runOnUiThread(new Runnable() { @Override public void run() { viewPager.setCurrentItem(viewPager.getCurrentItem() + 1); } }); } } }).start(); } private void initAction() { //取中间数来作为起始位置 int index = (Integer.MAX_VALUE / 2) - (Integer.MAX_VALUE / 2 % listImageView.size()); //用来出发监听器 viewPager.setCurrentItem(index); linearLayout.getChildAt(pointIndex).setEnabled(true); } private void initView() { viewPager = (ViewPager) findViewById(R.id.viewpager); textView = (TextView) findViewById(R.id.tv_bannertext); linearLayout = (LinearLayout) findViewById(R.id.points); mQueue = Volley.newRequestQueue(this); } private void initDate() { BannerBean bannerBean1 = new BannerBean("http://image.tianjimedia.com/uploadImages/2012/236/L1Q2D11EJEUR.jpg", "田野和蓝天"); BannerBean bannerBean2 = new BannerBean("http://image.tianjimedia.com/uploadImages/2012/236/ZU667K72270N.jpg", "海洋和帆船"); BannerBean bannerBean3 = new BannerBean("http://image.tianjimedia.com/uploadImages/2012/236/6477R0H2JBTU.jpg", "雪景"); BannerBean bannerBean4 = new BannerBean("http://image.tianjimedia.com/uploadImages/2012/236/1327ORB0XR68.jpg", "古堡"); BannerBean bannerBean5 = new BannerBean("http://image.tianjimedia.com/uploadImages/2012/236/2Q682OB9JGG8.jpg", "园林风景"); BannerBean bannerBean6 = new BannerBean("http://image.tianjimedia.com/uploadImages/2012/236/2V5E4MEHVT8L.jpg", "春夏秋冬"); listBannerBean = new ArrayList<>(); listBannerBean.add(bannerBean1); listBannerBean.add(bannerBean2); listBannerBean.add(bannerBean3); listBannerBean.add(bannerBean4); listBannerBean.add(bannerBean5); listBannerBean.add(bannerBean6); listImageView = new ArrayList<>(); for (int i = 0; i < listBannerBean.size(); i++) { //设置广告图 ImageView imageView = new ImageView(this); imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); imageView.setScaleType(ImageView.ScaleType.FIT_XY);//设置缩放样式 mImageLoader = new ImageLoader(mQueue, new ImageLoader.ImageCache() { @Override public Bitmap getBitmap(String s) { return null; } @Override public void putBitmap(String s, Bitmap bitmap) { } }); imageListener = ImageLoader.getImageListener(imageView, R.mipmap.ic_launcher, R.mipmap.ic_launcher); mImageLoader.get(listBannerBean.get(i).getImageUrl(), imageListener); listImageView.add(imageView); //设置圆点 view = new View(this); layoutParams = new LinearLayout.LayoutParams(20, 20); layoutParams.leftMargin = 10; view.setBackgroundResource(R.drawable.point_selector); view.setLayoutParams(layoutParams); view.setEnabled(false); linearLayout.addView(view); } bannerAdapter = new BannerAdapter(listImageView, this, listBannerBean); viewPager.setAdapter(bannerAdapter); viewPager.setOnPageChangeListener(this); } @Override public void onClick(View v) { //此处实现点击指示器,来显示第几个轮播图,但我觉得一般轮播图里的点太小,可能会产出误触,不建议 } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { int newPosition = position % listBannerBean.size(); textView.setText(listBannerBean.get(newPosition).getText()); linearLayout.getChildAt(newPosition).setEnabled(true); linearLayout.getChildAt(pointIndex).setEnabled(false); pointIndex = newPosition; } @Override public void onPageScrollStateChanged(int state) { } @Override protected void onDestroy() { // 关闭定时器 isStop = true; super.onDestroy(); }
注意点:
1、
private void initAction() {
//取中间数来作为起始位置
int index = (Integer.MAX_VALUE / 2) - (Integer.MAX_VALUE / 2 % listImageView.size());
//用来出发监听器
viewPager.setCurrentItem(index);
linearLayout.getChildAt(pointIndex).setEnabled(true);
}
这一段代码要好好注意,因为起始位置不能为0,为0的话,当滑动到第一张时,就不能再向左滑动了,所以我们选取一个中间值得位置作为起始位置,这样就不用担心两边会滑到头了。
四、ViewPager的适配器
直接上代码:BannerAdapter.java
public class BannerAdapter extends PagerAdapter { private List<ImageView> list; private Context context; private List<BannerBean> bannerBeanList; public BannerAdapter(List<ImageView> list, Context context, List<BannerBean> bannerBeanList) { this.list = list; this.context = context; this.bannerBeanList = bannerBeanList; } @Override public int getCount() { //取超大的数,实现无线循环效果 return Integer.MAX_VALUE; } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(list.get(position % list.size())); } @Override public Object instantiateItem(ViewGroup container, final int position) { //这边有一个很大的问题待解决,当图片数量小于3的时候,不会调用destroyItem(ViewGroup container, int position, Object object)这个方法,则会出现问题。 //如果是多余三张的时候,是会调用,然后进行移除。 container.addView(list.get(position % list.size())); list.get(position % list.size()).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(context, bannerBeanList.get(position % list.size()).getText(), Toast.LENGTH_SHORT).show(); } }); return list.get(position % list.size()); }}
注意:
1、在getCount()方法中返回的是Integer.MAX_VALUE;因为想要实现无限次的轮播效果,所以不能返回轮播图的数量。
2、然后之前的position就要用position % list.size()来取代,这样就不会出现越界的现象。
3、这里还有一个问题没有解决,就是当轮播图的图片少于三张的时候,会出现空白的问题。因为少于3张图的时候,不会调用destroyItem()这个方法,就不会销毁之前的图。以后再解决吧!希望大家也能够给点意见。
- Android的banner(轮播图)的实现
- Android顶部banner轮播图的两种实现(ViewPager+ViewPagerIndicator/banner)
- Android 轮播图Banner的简单实现
- banner轮播图的实现
- Android中利用banner实现轮播图的效果
- android 实现自动滚动的 Banner 横幅
- android 实现自动滚动的 Banner 横幅
- Android 图片轮播Banner的实现
- Android之最简单的Banner实现
- android banner 实现轮播图
- Banner的简单实现
- Banner框架的简单使用(实现轮播图)
- android轮播图Banner的使用及详解
- Banner (android 轮播图)
- 实现简单的banner变换
- Banner和XBanner的实现
- 利用Android属性动画实现Banner的原理与实践
- Android 用ViewPager实现可自动循环的Banner图
- POJ 1125 Stockbroker Grapevine
- 安卓动态调试七种武器之离别钩 – Hooking(下)
- Python获取当前目录下所有文件的绝对路径并存储在文件中
- poj 1837 Balance
- SignalR实现web在线即时聊天(C#)
- Android的banner(轮播图)的实现
- SICP(1985) ex2-2 line-segment
- 指针的内容 ; 指针的地址 指针所指向的内容 指针的类型 指针所指向的类型
- php 集成redis
- 链接属性
- 多个关键领域掀起革新浪潮,权威专家预言未来属于量子点科技
- Android中与Service交互的三种方式
- 作用域
- 接口返回<null>时的处理