Android ViewPager实现图片标题轮播和点击事件
2018.9.27补Github项目
https://github.com/luhuan97/ImageCarousel
优化了很多,但是我半年不写安卓了,今晚花了两个小时弄了出来。
------------------------------------------------------------------------
我在看别人文章的时候,最喜欢先找图看。
那我就先上效果图:
实现了图片自动轮播,手动滑动,轮播标题,以及点击事件。下面开始:
一、资源文件:
首先是布局:
- <?xml version="1.0" encoding="utf-8"?>
- <android.support.constraint.ConstraintLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context="xyz.ncvt.viewpagerdemo.MainActivity">
- <FrameLayout
- android:layout_width="0dp"
- android:layout_height="200dp" app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent">
- <android.support.v4.view.ViewPager
- android:id="@+id/viewPager"
- android:layout_width="match_parent"
- android:layout_height="match_parent" tools:layout_editor_absoluteY="0dp"
- tools:layout_editor_absoluteX="8dp"/>
- <LinearLayout
- android:weightSum="10"
- android:background="#33000000"
- android:orientation="horizontal"
- android:layout_gravity="bottom"
- android:gravity="center_vertical"
- android:layout_width="match_parent"
- android:layout_height="35dip">
- <TextView
- android:layout_weight="8"
- android:id="@+id/tv_pager_title"
- android:text="很长的标题。。。。。你懂我意思吧"
- android:paddingLeft="8dip"
- android:gravity="center_vertical"
- android:textColor="@color/white"
- android:layout_width="0dp" android:layout_height="35dip"/>
- <!--用来动态添加轮播小点-->
- <LinearLayout
- android:id="@+id/lineLayout_dot"
- android:layout_weight="2"
- android:gravity="center|right"
- android:layout_marginRight="5dp"
- android:paddingLeft="3dp"
- android:paddingRight="3dp"
- android:orientation="horizontal"
- android:layout_width="0dp" android:layout_height="match_parent">
- </LinearLayout>
- </LinearLayout>
- </FrameLayout>
- </android.support.constraint.ConstraintLayout>
轮播小点资源(Drawable):这个是vector,大家可以自行搜索了解。
- <vector android:height="5dp" android:viewportHeight="24.0"
- android:viewportWidth="24.0" android:width="5dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="#fff" android:pathData="M12,12m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"/>
- </vector>
创建一个图片ID资源文件,用于图片点击事件:存放在values文件夹内
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <item name="pager_image1" type="id" />
- <item name="pager_image2" type="id" />
- <item name="pager_image3" type="id" />
- <item name="pager_image4" type="id" />
- </resources>
二、定义一个适配器,可以是内部类也可以是单独一个类:适配器比较简单,重写了几个方法,定义了一个传入图片列表、ViewPager实例的构造方法。
- 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 java.util.List;
- public class ViewPagerAdapter extends PagerAdapter {
- private List<ImageView> images;
- private ViewPager viewPager;
- /**
- * 构造方法,传入图片列表和ViewPager实例
- * @param images
- * @param viewPager
- */
- public ViewPagerAdapter(List<ImageView> images, ViewPager viewPager){
- this.images = images;
- this.viewPager = viewPager;
- }
- @Override
- public int getCount() {
- return Integer.MAX_VALUE;//返回一个无限大的值,可以 无限循环
- }
- /**
- * 判断是否使用缓存, 如果返回的是true, 使用缓存. 不去调用instantiateItem方法创建一个新的对象
- */
- @Override
- public boolean isViewFromObject(View view, Object object) {
- return view == object;
- }
- /**
- * 初始化一个条目
- * @param container
- * @param position 当前需要加载条目的索引
- * @return
- */
- @Override
- public Object instantiateItem(ViewGroup container, int position) {
- // 把position对应位置的ImageView添加到ViewPager中
- ImageView iv = images.get(position % images.size());
- viewPager.addView(iv);
- // 把当前添加ImageView返回回去.
- return iv;
- }
- /**
- * 销毁一个条目
- * position 就是当前需要被销毁的条目的索引
- */
- @Override
- public void destroyItem(ViewGroup container, int position, Object object) {
- // 把ImageView从ViewPager中移除掉
- viewPager.removeView(images.get(position % images.size()));
- }
三、编写MainActivity代码:我还是不一部部分拆分代码了,我在代码写好完整的注释即可,不懂的可以留言给我。
- public class MainActivity extends AppCompatActivity {
- private ViewPager mViewPager;
- private TextView mTvPagerTitle;
- private List<ImageView> mImageList;//轮播的图片集合
- private String[] mImageTitles;//标题集合
- private int previousPosition = 0;//前一个被选中的position
- private List<View> mDots;//小点
- private boolean isStop = false;//线程是否停止
- private static int PAGER_TIOME = 5000;//间隔时间
- // 在values文件假下创建了pager_image_ids.xml文件,并定义了4张轮播图对应的id,用于点击事件
- private int[] imgae_ids = new int[]{R.id.pager_image1,R.id.pager_image2,R.id.pager_image3,R.id.pager_image4};
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- init();
- }
- /**
- * 第一步、初始化控件
- */
- public void init() {
- mViewPager = (ViewPager) findViewById(R.id.viewPager);
- mTvPagerTitle = (TextView) findViewById(R.id.tv_pager_title);
- initData();//初始化数据
- initView();//初始化View,设置适配器
- autoPlayView();//开启线程,自动播放
- }
- /**
- * 第二步、初始化数据(图片、标题、点击事件)
- */
- public void initData() {
- //初始化标题列表和图片
- mImageTitles = new String[]{"这是一个好看的标题1","这是一个优美的标题2","这是一个快乐的标题3","这是一个开心的标题4"};
- int[] imageRess = new int[]{R.drawable.ncvt_wifi_head,R.drawable.img1,R.drawable.img2,R.drawable.img3};
- //添加图片到图片列表里
- mImageList = new ArrayList<>();
- ImageView iv;
- for (int i = 0; i < mImageList.size(); i++) {
- iv = new ImageView(this);
- iv.setBackgroundResource(imageRess[i]);//设置图片
- iv.setId(imgae_ids[i]);//顺便给图片设置id
- iv.setOnClickListener(new pagerImageOnClick());//设置图片点击事件
- mImageList.add(iv);
- }
- //添加轮播点
- LinearLayout linearLayoutDots = (LinearLayout) findViewById(R.id.lineLayout_dot);
- mDots = addDots(linearLayoutDots,fromResToDrawable(this,R.drawable.ic_dot_normal),mImageList.size());//其中fromResToDrawable()方法是我自定义的,目的是将资源文件转成Drawable
- }
- //图片点击事件
- private class pagerImageOnClick implements View.OnClickListener{
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.pager_image1:
- Toast.makeText(MainActivity.this, "图片1被点击", Toast.LENGTH_SHORT).show();
- break;
- case R.id.pager_image2:
- Toast.makeText(MainActivity.this, "图片2被点击", Toast.LENGTH_SHORT).show();
- break;
- case R.id.pager_image3:
- Toast.makeText(MainActivity.this, "图片3被点击", Toast.LENGTH_SHORT).show();
- break;
- case R.id.pager_image4:
- Toast.makeText(MainActivity.this, "图片4被点击", Toast.LENGTH_SHORT).show();
- break;
- }
- }
- }
- /**
- * 第三步、给PagerViw设置适配器,并实现自动轮播功能
- */
- public void initView(){
- ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(mImageList, mViewPager);
- mViewPager.setAdapter(viewPagerAdapter);
- mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
- @Override
- public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
- }
- @Override
- public void onPageSelected(int position) {
- //伪无限循环,滑到最后一张图片又从新进入第一张图片
- int newPosition = position % mImageList.size();
- // 把当前选中的点给切换了, 还有描述信息也切换
- mTvPagerTitle.setText(mImageTitles[newPosition]);//图片下面设置显示文本
- //设置轮播点
- LinearLayout.LayoutParams newDotParams = (LinearLayout.LayoutParams) mDots.get(newPosition).getLayoutParams();
- newDotParams.width = 24;
- newDotParams.height = 24;
- LinearLayout.LayoutParams oldDotParams = (LinearLayout.LayoutParams) mDots.get(previousPosition).getLayoutParams();
- oldDotParams.width = 16;
- oldDotParams.height = 16;
- // 把当前的索引赋值给前一个索引变量, 方便下一次再切换.
- previousPosition = newPosition;
- }
- @Override
- public void onPageScrollStateChanged(int state) {
- }
- });
- setFirstLocation();
- }
- /**
- * 第四步:设置刚打开app时显示的图片和文字
- */
- private void setFirstLocation() {
- mTvPagerTitle.setText(mImageTitles[previousPosition]);
- // 把ViewPager设置为默认选中Integer.MAX_VALUE / t2,从十几亿次开始轮播图片,达到无限循环目的;
- int m = (Integer.MAX_VALUE / 2) % mImageList.size();
- int currentPosition = Integer.MAX_VALUE / 2 - m;
- mViewPager.setCurrentItem(currentPosition);
- }
- /**
- * 第五步: 设置自动播放,每隔PAGER_TIOME秒换一张图片
- */
- private void autoPlayView() {
- //自动播放图片
- new Thread(new Runnable() {
- @Override
- public void run() {
- while (!isStop){
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1);
- }
- });
- SystemClock.sleep(PAGER_TIOME);
- }
- }
- }).start();
- }
- /**
- * 资源图片转Drawable
- * @param context
- * @param resId
- * @return
- */
- public Drawable fromResToDrawable(Context context, int resId) {
- return context.getResources().getDrawable(resId);
- }
- /**
- * 动态添加一个点
- * @param linearLayout 添加到LinearLayout布局
- * @param backgount 设置
- * @return
- */
- public int addDot(final LinearLayout linearLayout, Drawable backgount) {
- final View dot = new View(this);
- LinearLayout.LayoutParams dotParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT);
- dotParams.width = 16;
- dotParams.height = 16;
- dotParams.setMargins(4,0,4,0);
- dot.setLayoutParams(dotParams);
- dot.setBackground(backgount);
- dot.setId(View.generateViewId());
- linearLayout.addView(dot);
- return dot.getId();
- }
- /**
- * 添加多个轮播小点到横向线性布局
- * @param linearLayout
- * @param backgount
- * @param number
- * @return
- */
- public List<View> addDots(final LinearLayout linearLayout, Drawable backgount, int number){
- List<View> dots = new ArrayList<>();
- for (int i = 0; i < number; i++) {
- int dotId = addDot(linearLayout,backgount);
- dots.add(findViewById(dotId));
- }
- return dots;
- }
诶呀,感觉有90%完美了,供大家学习参考。我优化一下代码,再上demo。
Android ViewPager实现图片标题轮播和点击事件的更多相关文章
- Android ViewPager PagerAdapter 图片轮播
ViewPager类直接继承了ViewGroup类,所有它是一个容器类,可以在其中添加其他的View类. ViewPager类需要一个PagerAdapter适配器类给它提供数据. ViewPager ...
- android ViewPager实现的轮播图广告自定义视图,网络获取图片和数据
public class SlideShowAdView extends FrameLayout { //轮播图图片数量 private static int IMAGE_COUNT = 3; ...
- Android Viewpager实现图片轮播(仿优酷效果)
1 http://blog.csdn.net/t12x3456/article/details/8160128 2 http://www.cnblogs.com/androidez/archive/2 ...
- ViewPager实现无限轮播踩坑记
最近笔者想通过ViewPager来实现一个广告Banner,并实现无限轮播的效果,但是在这个过程中踩了不少的坑,听我慢慢道来.如果大家有遇到和我一样的情况,可以参考我的解决方法,没有那就更好,如果针对 ...
- 仿百度壁纸客户端(二)——主页自定义ViewPager广告定时轮播图
仿百度壁纸客户端(二)--主页自定义ViewPager广告定时轮播图 百度壁纸系列 仿百度壁纸客户端(一)--主框架搭建,自定义Tab + ViewPager + Fragment 仿百度壁纸客户端( ...
- 通过ViewPager 实现图片轮播
通过ViewPager 实现图片轮播 首先来个效果图 布局文件: LinearLayout 用来存放下方的几个小白点. <?xml version="1.0" encodin ...
- 非常简单的方法实现ViewPager自动循环轮播
非常简单的方法实现ViewPager自动循环轮播,见红色代码部分,其它的代码可以忽略不看. 简洁高效是我解决问题的首要出发点. package com.shuivy.happylendandreadb ...
- Bootstrap 历练实例-轮播(carousel)插件的事件
事件 下表列出了轮播(Carousel)插件中要用到的事件.这些事件可在函数中当钩子使用. 事件 描述 实例 slide.bs.carousel 当调用 slide 实例方法时立即触发该事件. $(' ...
- 淘宝(阿里百川)手机客户端开发日记第二篇 android首页之顶部轮播特效制作 (二)
1.我们来设计flash_slide.xml 布局,这个xml主要做成模块化,方便其它的activity可以动态去调用. flash_slide.xml内容如下: <?xml version=& ...
随机推荐
- 楼梯T-SQL:超越基础6级:使用CASE表达式和IIF函数
从他的楼梯到T-SQL DML,Gregory Larsen涵盖了更多的高级方面的T-SQL语言,如子查询. 有时您需要编写一个可以根据另一个表达式的评估返回不同的TSQL表达式的单个TSQL语句. ...
- Linux系列教程(十二)——Linux软件包管理之yum在线管理
上一篇博客我们介绍了rpm包管理之rpm命令管理,我们发现在使用rpm命令手动安装rpm包的时候,会发现安装遇到到的依赖让你痛不欲生,安装一个rpm时会要先先安装某个依赖的rpm,而安装这个依赖的rp ...
- 部署 Graylog 日志系统 - 每天5分钟玩转 Docker 容器技术(92)
Graylog 是与 ELK 可以相提并论的一款集中式日志管理方案,支持数据收集.检索.可视化 Dashboard.本节将实践用 Graylog 来管理 Docker 日志. Graylog 架构 G ...
- JQ图片文件上传之前预览功能
1.先准备一个div onchange触发事件 <input type="file" onchange="preview(this)" >< ...
- elasticsearch 基础语句
1. doucument id 的两种生成方式 自动生成document id自动生成的id,长度为20个字符,URL安全,base64编码,GUID,分布式系统并行生成时不可能会发生冲突 POST ...
- 菜鸟谈谈C#中的构造函数和析构函数
本节说明对象的创建.初始化和销毁过程.本节介绍下列主题: l 类构造函数 l 结构构造函数 l 析构函数 类构造函数 本节将讨论三种类构造函数: 类构造 ...
- Python中的三种数据结构
Python中,有3种内建的数据结构:列表.元组和字典.1.列表 list是处理一组有序项目的数据结构,即你可以在一个列表中存储一个序列的项目.列表中的项目.列表中的项目应该包括在方括号中,这 ...
- 记录一下通过分析Tomcat内部jar包找出request.getReader()所用的字符编码在哪里设置和起效的完整分析流程
前言: 之前写Java服务端处理POST请求时遇到了请求体转换成字符流所用编码来源的疑惑,在doPost方法里通过request.getReader()获取的BufferedReader对象内部的 R ...
- Android Debug Bridge
Android Debug Bridge Introduction Android Debug Bridge (adb) is a versatile command line tool th ...
- Python 面向对象(五) 描述器
使用到了__get__,__set__,__delete__中的任何一种方法的类就是描述器 描述器的定义 一个类实现了__get__,__set__,__delete__中任意一个,这个类就是描述器. ...