2018.9.27补Github项目

https://github.com/luhuan97/ImageCarousel

优化了很多,但是我半年不写安卓了,今晚花了两个小时弄了出来。

------------------------------------------------------------------------

我在看别人文章的时候,最喜欢先找图看。

那我就先上效果图:

实现了图片自动轮播,手动滑动,轮播标题,以及点击事件。下面开始:

一、资源文件:

首先是布局:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <android.support.constraint.ConstraintLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. xmlns:app="http://schemas.android.com/apk/res-auto"
  6. android:layout_width="match_parent"
  7. android:layout_height="match_parent"
  8. tools:context="xyz.ncvt.viewpagerdemo.MainActivity">
  9.  
  10. <FrameLayout
  11. android:layout_width="0dp"
  12. android:layout_height="200dp" app:layout_constraintTop_toTopOf="parent"
  13. app:layout_constraintLeft_toLeftOf="parent"
  14. app:layout_constraintRight_toRightOf="parent">
  15.  
  16. <android.support.v4.view.ViewPager
  17. android:id="@+id/viewPager"
  18. android:layout_width="match_parent"
  19. android:layout_height="match_parent" tools:layout_editor_absoluteY="0dp"
  20. tools:layout_editor_absoluteX="8dp"/>
  21.  
  22. <LinearLayout
  23. android:weightSum="10"
  24. android:background="#33000000"
  25. android:orientation="horizontal"
  26. android:layout_gravity="bottom"
  27. android:gravity="center_vertical"
  28. android:layout_width="match_parent"
  29. android:layout_height="35dip">
  30. <TextView
  31. android:layout_weight="8"
  32. android:id="@+id/tv_pager_title"
  33. android:text="很长的标题。。。。。你懂我意思吧"
  34. android:paddingLeft="8dip"
  35. android:gravity="center_vertical"
  36. android:textColor="@color/white"
  37. android:layout_width="0dp" android:layout_height="35dip"/>
  38. <!--用来动态添加轮播小点-->
  39. <LinearLayout
  40. android:id="@+id/lineLayout_dot"
  41. android:layout_weight="2"
  42. android:gravity="center|right"
  43. android:layout_marginRight="5dp"
  44. android:paddingLeft="3dp"
  45. android:paddingRight="3dp"
  46. android:orientation="horizontal"
  47. android:layout_width="0dp" android:layout_height="match_parent">
  48. </LinearLayout>
  49.  
  50. </LinearLayout>
  51. </FrameLayout>
  52.  
  53. </android.support.constraint.ConstraintLayout>

轮播小点资源(Drawable):这个是vector,大家可以自行搜索了解。

  1. <vector android:height="5dp" android:viewportHeight="24.0"
  2. android:viewportWidth="24.0" android:width="5dp" xmlns:android="http://schemas.android.com/apk/res/android">
  3. <path android:fillColor="#fff" android:pathData="M12,12m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"/>
  4. </vector>

创建一个图片ID资源文件,用于图片点击事件:存放在values文件夹内

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3. <item name="pager_image1" type="id" />
  4. <item name="pager_image2" type="id" />
  5. <item name="pager_image3" type="id" />
  6. <item name="pager_image4" type="id" />
  7. </resources>

二、定义一个适配器,可以是内部类也可以是单独一个类:适配器比较简单,重写了几个方法,定义了一个传入图片列表、ViewPager实例的构造方法。

  1. import android.support.v4.view.PagerAdapter;
  2. import android.support.v4.view.ViewPager;
  3. import android.view.View;
  4. import android.view.ViewGroup;
  5. import android.widget.ImageView;
  6.  
  7. import java.util.List;
  8.  
  9. public class ViewPagerAdapter extends PagerAdapter {
  10. private List<ImageView> images;
  11. private ViewPager viewPager;
  12.  
  13. /**
  14. * 构造方法,传入图片列表和ViewPager实例
  15. * @param images
  16. * @param viewPager
  17. */
  18.  
  19. public ViewPagerAdapter(List<ImageView> images, ViewPager viewPager){
  20. this.images = images;
  21. this.viewPager = viewPager;
  22. }
  23.  
  24. @Override
  25. public int getCount() {
  26. return Integer.MAX_VALUE;//返回一个无限大的值,可以 无限循环
  27. }
  28.  
  29. /**
  30. * 判断是否使用缓存, 如果返回的是true, 使用缓存. 不去调用instantiateItem方法创建一个新的对象
  31. */
  32. @Override
  33. public boolean isViewFromObject(View view, Object object) {
  34. return view == object;
  35. }
  36.  
  37. /**
  38. * 初始化一个条目
  39. * @param container
  40. * @param position 当前需要加载条目的索引
  41. * @return
  42. */
  43. @Override
  44. public Object instantiateItem(ViewGroup container, int position) {
  45. // 把position对应位置的ImageView添加到ViewPager中
  46. ImageView iv = images.get(position % images.size());
  47. viewPager.addView(iv);
  48. // 把当前添加ImageView返回回去.
  49. return iv;
  50. }
  51. /**
  52. * 销毁一个条目
  53. * position 就是当前需要被销毁的条目的索引
  54. */
  55. @Override
  56. public void destroyItem(ViewGroup container, int position, Object object) {
  57. // 把ImageView从ViewPager中移除掉
  58. viewPager.removeView(images.get(position % images.size()));
  59.  
  60. }

三、编写MainActivity代码:我还是不一部部分拆分代码了,我在代码写好完整的注释即可,不懂的可以留言给我。

  1. public class MainActivity extends AppCompatActivity {
  2. private ViewPager mViewPager;
  3. private TextView mTvPagerTitle;
  4.  
  5. private List<ImageView> mImageList;//轮播的图片集合
  6. private String[] mImageTitles;//标题集合
  7. private int previousPosition = 0;//前一个被选中的position
  8. private List<View> mDots;//小点
  9.  
  10. private boolean isStop = false;//线程是否停止
  11. private static int PAGER_TIOME = 5000;//间隔时间
  12.  
  13. // 在values文件假下创建了pager_image_ids.xml文件,并定义了4张轮播图对应的id,用于点击事件
  14. private int[] imgae_ids = new int[]{R.id.pager_image1,R.id.pager_image2,R.id.pager_image3,R.id.pager_image4};
  15.  
  16. @Override
  17. protected void onCreate(Bundle savedInstanceState) {
  18. super.onCreate(savedInstanceState);
  19. setContentView(R.layout.activity_main);
  20. init();
  21. }
  22.  
  23. /**
  24. * 第一步、初始化控件
  25. */
  26. public void init() {
  27. mViewPager = (ViewPager) findViewById(R.id.viewPager);
  28. mTvPagerTitle = (TextView) findViewById(R.id.tv_pager_title);
  29. initData();//初始化数据
  30. initView();//初始化View,设置适配器
  31. autoPlayView();//开启线程,自动播放
  32. }
  33.  
  34. /**
  35. * 第二步、初始化数据(图片、标题、点击事件)
  36. */
  37. public void initData() {
  38. //初始化标题列表和图片
  39. mImageTitles = new String[]{"这是一个好看的标题1","这是一个优美的标题2","这是一个快乐的标题3","这是一个开心的标题4"};
  40. int[] imageRess = new int[]{R.drawable.ncvt_wifi_head,R.drawable.img1,R.drawable.img2,R.drawable.img3};
  41.  
  42. //添加图片到图片列表里
  43. mImageList = new ArrayList<>();
  44. ImageView iv;
  45. for (int i = 0; i < mImageList.size(); i++) {
  46. iv = new ImageView(this);
  47. iv.setBackgroundResource(imageRess[i]);//设置图片
  48. iv.setId(imgae_ids[i]);//顺便给图片设置id
  49. iv.setOnClickListener(new pagerImageOnClick());//设置图片点击事件
  50. mImageList.add(iv);
  51. }
  52.  
  53. //添加轮播点
  54. LinearLayout linearLayoutDots = (LinearLayout) findViewById(R.id.lineLayout_dot);
  55. mDots = addDots(linearLayoutDots,fromResToDrawable(this,R.drawable.ic_dot_normal),mImageList.size());//其中fromResToDrawable()方法是我自定义的,目的是将资源文件转成Drawable
  56.  
  57. }
  58.  
  59. //图片点击事件
  60. private class pagerImageOnClick implements View.OnClickListener{
  61.  
  62. @Override
  63. public void onClick(View v) {
  64. switch (v.getId()) {
  65. case R.id.pager_image1:
  66. Toast.makeText(MainActivity.this, "图片1被点击", Toast.LENGTH_SHORT).show();
  67. break;
  68. case R.id.pager_image2:
  69. Toast.makeText(MainActivity.this, "图片2被点击", Toast.LENGTH_SHORT).show();
  70. break;
  71. case R.id.pager_image3:
  72. Toast.makeText(MainActivity.this, "图片3被点击", Toast.LENGTH_SHORT).show();
  73. break;
  74. case R.id.pager_image4:
  75. Toast.makeText(MainActivity.this, "图片4被点击", Toast.LENGTH_SHORT).show();
  76. break;
  77. }
  78. }
  79. }
  80. /**
  81. * 第三步、给PagerViw设置适配器,并实现自动轮播功能
  82. */
  83. public void initView(){
  84. ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(mImageList, mViewPager);
  85. mViewPager.setAdapter(viewPagerAdapter);
  86. mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
  87. @Override
  88. public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
  89.  
  90. }
  91.  
  92. @Override
  93. public void onPageSelected(int position) {
  94. //伪无限循环,滑到最后一张图片又从新进入第一张图片
  95. int newPosition = position % mImageList.size();
  96. // 把当前选中的点给切换了, 还有描述信息也切换
  97. mTvPagerTitle.setText(mImageTitles[newPosition]);//图片下面设置显示文本
  98. //设置轮播点
  99. LinearLayout.LayoutParams newDotParams = (LinearLayout.LayoutParams) mDots.get(newPosition).getLayoutParams();
  100. newDotParams.width = 24;
  101. newDotParams.height = 24;
  102.  
  103. LinearLayout.LayoutParams oldDotParams = (LinearLayout.LayoutParams) mDots.get(previousPosition).getLayoutParams();
  104. oldDotParams.width = 16;
  105. oldDotParams.height = 16;
  106.  
  107. // 把当前的索引赋值给前一个索引变量, 方便下一次再切换.
  108. previousPosition = newPosition;
  109.  
  110. }
  111.  
  112. @Override
  113. public void onPageScrollStateChanged(int state) {
  114.  
  115. }
  116. });
  117. setFirstLocation();
  118. }
  119.  
  120. /**
  121. * 第四步:设置刚打开app时显示的图片和文字
  122. */
  123. private void setFirstLocation() {
  124. mTvPagerTitle.setText(mImageTitles[previousPosition]);
  125. // 把ViewPager设置为默认选中Integer.MAX_VALUE / t2,从十几亿次开始轮播图片,达到无限循环目的;
  126. int m = (Integer.MAX_VALUE / 2) % mImageList.size();
  127. int currentPosition = Integer.MAX_VALUE / 2 - m;
  128. mViewPager.setCurrentItem(currentPosition);
  129. }
  130.  
  131. /**
  132. * 第五步: 设置自动播放,每隔PAGER_TIOME秒换一张图片
  133. */
  134. private void autoPlayView() {
  135. //自动播放图片
  136. new Thread(new Runnable() {
  137. @Override
  138. public void run() {
  139. while (!isStop){
  140. runOnUiThread(new Runnable() {
  141. @Override
  142. public void run() {
  143. mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1);
  144. }
  145. });
  146. SystemClock.sleep(PAGER_TIOME);
  147. }
  148. }
  149. }).start();
  150. }
  151.  
  152. /**
  153. * 资源图片转Drawable
  154. * @param context
  155. * @param resId
  156. * @return
  157. */
  158. public Drawable fromResToDrawable(Context context, int resId) {
  159. return context.getResources().getDrawable(resId);
  160. }
  161.  
  162. /**
  163. * 动态添加一个点
  164. * @param linearLayout 添加到LinearLayout布局
  165. * @param backgount 设置
  166. * @return
  167. */
  168. public int addDot(final LinearLayout linearLayout, Drawable backgount) {
  169. final View dot = new View(this);
  170. LinearLayout.LayoutParams dotParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
  171. ViewGroup.LayoutParams.WRAP_CONTENT);
  172. dotParams.width = 16;
  173. dotParams.height = 16;
  174. dotParams.setMargins(4,0,4,0);
  175. dot.setLayoutParams(dotParams);
  176. dot.setBackground(backgount);
  177. dot.setId(View.generateViewId());
  178. linearLayout.addView(dot);
  179. return dot.getId();
  180. }
  181.  
  182. /**
  183. * 添加多个轮播小点到横向线性布局
  184. * @param linearLayout
  185. * @param backgount
  186. * @param number
  187. * @return
  188. */
  189. public List<View> addDots(final LinearLayout linearLayout, Drawable backgount, int number){
  190. List<View> dots = new ArrayList<>();
  191. for (int i = 0; i < number; i++) {
  192. int dotId = addDot(linearLayout,backgount);
  193. dots.add(findViewById(dotId));
  194. }
  195. return dots;
  196. }

诶呀,感觉有90%完美了,供大家学习参考。我优化一下代码,再上demo。

Android ViewPager实现图片标题轮播和点击事件的更多相关文章

  1. Android ViewPager PagerAdapter 图片轮播

    ViewPager类直接继承了ViewGroup类,所有它是一个容器类,可以在其中添加其他的View类. ViewPager类需要一个PagerAdapter适配器类给它提供数据. ViewPager ...

  2. android ViewPager实现的轮播图广告自定义视图,网络获取图片和数据

    public class SlideShowAdView extends FrameLayout { //轮播图图片数量    private static int IMAGE_COUNT = 3;  ...

  3. Android Viewpager实现图片轮播(仿优酷效果)

    1 http://blog.csdn.net/t12x3456/article/details/8160128 2 http://www.cnblogs.com/androidez/archive/2 ...

  4. ViewPager实现无限轮播踩坑记

    最近笔者想通过ViewPager来实现一个广告Banner,并实现无限轮播的效果,但是在这个过程中踩了不少的坑,听我慢慢道来.如果大家有遇到和我一样的情况,可以参考我的解决方法,没有那就更好,如果针对 ...

  5. 仿百度壁纸客户端(二)——主页自定义ViewPager广告定时轮播图

    仿百度壁纸客户端(二)--主页自定义ViewPager广告定时轮播图 百度壁纸系列 仿百度壁纸客户端(一)--主框架搭建,自定义Tab + ViewPager + Fragment 仿百度壁纸客户端( ...

  6. 通过ViewPager 实现图片轮播

    通过ViewPager 实现图片轮播 首先来个效果图 布局文件: LinearLayout 用来存放下方的几个小白点. <?xml version="1.0" encodin ...

  7. 非常简单的方法实现ViewPager自动循环轮播

    非常简单的方法实现ViewPager自动循环轮播,见红色代码部分,其它的代码可以忽略不看. 简洁高效是我解决问题的首要出发点. package com.shuivy.happylendandreadb ...

  8. Bootstrap 历练实例-轮播(carousel)插件的事件

    事件 下表列出了轮播(Carousel)插件中要用到的事件.这些事件可在函数中当钩子使用. 事件 描述 实例 slide.bs.carousel 当调用 slide 实例方法时立即触发该事件. $(' ...

  9. 淘宝(阿里百川)手机客户端开发日记第二篇 android首页之顶部轮播特效制作 (二)

    1.我们来设计flash_slide.xml 布局,这个xml主要做成模块化,方便其它的activity可以动态去调用. flash_slide.xml内容如下: <?xml version=& ...

随机推荐

  1. 楼梯T-SQL:超越基础6级:使用CASE表达式和IIF函数

     从他的楼梯到T-SQL DML,Gregory Larsen涵盖了更多的高级方面的T-SQL语言,如子查询. 有时您需要编写一个可以根据另一个表达式的评估返回不同的TSQL表达式的单个TSQL语句. ...

  2. Linux系列教程(十二)——Linux软件包管理之yum在线管理

    上一篇博客我们介绍了rpm包管理之rpm命令管理,我们发现在使用rpm命令手动安装rpm包的时候,会发现安装遇到到的依赖让你痛不欲生,安装一个rpm时会要先先安装某个依赖的rpm,而安装这个依赖的rp ...

  3. 部署 Graylog 日志系统 - 每天5分钟玩转 Docker 容器技术(92)

    Graylog 是与 ELK 可以相提并论的一款集中式日志管理方案,支持数据收集.检索.可视化 Dashboard.本节将实践用 Graylog 来管理 Docker 日志. Graylog 架构 G ...

  4. JQ图片文件上传之前预览功能

    1.先准备一个div onchange触发事件 <input  type="file" onchange="preview(this)" >< ...

  5. elasticsearch 基础语句

    1.  doucument id 的两种生成方式 自动生成document id自动生成的id,长度为20个字符,URL安全,base64编码,GUID,分布式系统并行生成时不可能会发生冲突 POST ...

  6. 菜鸟谈谈C#中的构造函数和析构函数

    本节说明对象的创建.初始化和销毁过程.本节介绍下列主题: l         类构造函数 l         结构构造函数 l         析构函数 类构造函数 本节将讨论三种类构造函数: 类构造 ...

  7. Python中的三种数据结构

    Python中,有3种内建的数据结构:列表.元组和字典.1.列表     list是处理一组有序项目的数据结构,即你可以在一个列表中存储一个序列的项目.列表中的项目.列表中的项目应该包括在方括号中,这 ...

  8. 记录一下通过分析Tomcat内部jar包找出request.getReader()所用的字符编码在哪里设置和起效的完整分析流程

    前言: 之前写Java服务端处理POST请求时遇到了请求体转换成字符流所用编码来源的疑惑,在doPost方法里通过request.getReader()获取的BufferedReader对象内部的 R ...

  9. Android Debug Bridge

    Android Debug Bridge Introduction     Android Debug Bridge (adb) is a versatile command line tool th ...

  10. Python 面向对象(五) 描述器

    使用到了__get__,__set__,__delete__中的任何一种方法的类就是描述器 描述器的定义 一个类实现了__get__,__set__,__delete__中任意一个,这个类就是描述器. ...