概述

图片循环播放这种效果,在许多的场合都能看到,只要一打开各大主流网站的首页几乎都有一个这样的组件,它可以很显目的提供给用户最近最火热的信息。因为它应用得如此之广泛,今天,我们就来写一下这个组件。

前期准备

首先,分析我们所看到的图片轮播效果,它有:
1.若干张图片,一般为3-6张,不宜太多。
2.一个承载图片的容器。
3.一个线程,实现图片的自动轮播。
4.表示当前图片位置的一个指示器,一般在图片的底部。
以上,便是一个基本的图片轮播控件所需要具备的要素。接下来,我们来找找,安卓里都给我买提供了些什么:
1.图片来源,很丰富。可以在本地,在网上,在项目里。归根结底,我们只要用到它们的url。因为url的变动很小,所以我们可以创建一个公共类来专门保存它们。(在此例子中是 Images.mgIds)
2.容器。首先想到的便是imageView+fragment。通过查看API我们可以发现,一个叫做viewPageer的控件十分适合,它可以放置多张图片,并且可以自动回收那些没有显示出来的图片,十分的节省内存。
3.Thread或Timer
4.指示器当然是呀自己构造了,一个线性布局+对应图片数量的指示点。

布局

基本需要的东西已经分析完毕,接下来,我们便可以来搭载我们的布局了。
同上面分析的一致,我们需要一个ViewPager 和一个LinearLayout 因为指示器的多少是和图片的数量有关的(动态的),因此我们需要在代码中动态的加载它,布局文件如下:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
 
<android.support.v4.view.ViewPager
android:id="@+id/viewpage"
android:layout_width="match_parent"
android:layout_height="match_parent">
 
</android.support.v4.view.ViewPager>
 
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom">
 
<LinearLayout
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"></LinearLayout>
</RelativeLayout>
</FrameLayout>

编码

新建一个类,名为MyViewPager 继承你布局的根类,在这里,我们需要继承FrameLayout 并重写构造函数。这就是我们自定义view的第二种情况,组合已有的控件。

初始化

同在activity中的操作一样,我们需要先初始化我们布局中的控件。
LayoutInflater.from(context).inflate(R.layout.activtity_viewpage,this);
root = (LinearLayout) findViewById(R.id.root);
 
viewPager= (ViewPager) findViewById(R.id.viewpage);
 
adapter=new MyAdapter();
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(this);
使用viewPager时,我们需要自定义一个adapter:
@Override
public int getCount() {
return Images.mgIds.length;
}
 
@Override
public boolean isViewFromObject(View view, Object object) {
return object==view;
}
 
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(imageViews.get(position));
}
 
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(imageViews.get(position));
return imageViews.get(position);
}
getCount 返回的是数量,这里的Images.mgIds 是我们的图片数据源数组(url)。destroyItem 需要移除当前imageview,而instantiateItem 需要加入imageview。因为imageview需要这么操作,因此我们用一个list来保存它们的引用。
imageViews=new ArrayList<>();
for (int i = 0; i< Images.mgIds.length; i++){
ImageView img=new ImageView(context);
img.setImageResource(Images.mgIds[i]);
imageViews.add(img);
}
同样,因为指示器也需要后续使用,我们也用一个list进行保存
points = new ArrayList<>();
for (int i = 0; i < Images.mgIds.length; i++) {
ImageView img = new ImageView(context);
if (i == position) {
img.setImageResource(R.drawable.page_indicator_focused);
} else {
img.setImageResource(R.drawable.page_indicator_unfocused);
}
root.addView(img);
points.add(img);
}
此时,我们可以使用我们的控件了。但发现一个问题,那就是底部的指示器并没有动。因此,我们需实现viewPager的OnPageChangeListener接口
/**
* 当前展示的第position张图片
* @param position
*/
@Override
public void onPageSelected(int position) {
this.position=position;
setImageBackGround(position);
}

增加 自动播放功能

 首先,创建一个timer 和timerTask,这里要先取消原先的任务,否则会报错。
timer=new Timer();
if (task!=null){
task.cancel();
}
task=new viweTask();
timer.schedule(task,2000,3000);
/**
* 自动播放任务
*/
private class viweTask extends TimerTask{
 
@Override
public void run() {
if (position == Images.mgIds.length - 1) {
position = 0;
} else {
position++;
}
handler.sendEmptyMessage(1);
}
}
我们通过hander来更新我们的图片和指示器
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
viewPager.setCurrentItem(position);
setImageBackGround(position);
}
};
我们还可以在onPageScrollStateChanged 中通过状态来判断用户是否想自己进行滑动
/**
*
* @param state 1手指触摸屏幕;2 滑动;0 滑动完成
*/
@Override
public void onPageScrollStateChanged(int state) {
if (state==1){
playing=false;
}else {
playing=true;
}
}

增加 每一项的点击事件回调

直观的想,我们会直接覆盖诸如onclicklistener之类的方法。可是,我们用的是viewPager,每次图片进行切换时,都会销毁原来的图片,加载新的图片。因此,这个方法是没用的。我们应该在onPageSelected 中放置我们的钩子。
在这之前,我们先定义好我们的回调接口:
//设置回调接口
private OnPageImageItemClick mOnPageImageItemClick;
public interface OnPageImageItemClick{
public void PageImageItemClick(ImageView imageItem,int position);
}
 
public void setOnPageImageItemClick(OnPageImageItemClick click){
this.mOnPageImageItemClick=click;
}
之后,我们便可以放置好我们的接口
final ImageView nowView=imageViews.get(position);
nowView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// Log.d(TAG, "position:" + position+" clicked!");
mOnPageImageItemClick.PageImageItemClick(nowView,position);
}
});
测试,在activity中调用
viewPager.setOnPageImageItemClick(new MyViewPager.OnPageImageItemClick() {
@Override
public void PageImageItemClick(ImageView imageItem, int position) {
Log.d("MainActivity", "position:" + position);
}
});
 
 

使用viewPage实现图片轮播的更多相关文章

  1. Android 使用ViewPager 做的半吊子的图片轮播

    Android 使用ViewPager 做的半吊子的图片轮播 效果图 虽然不咋样,但是最起码的功能是实现了,下面我们来一步步的实现它. 界面 下面我们来分析一下界面的构成 整体的布局: 因为我们要做出 ...

  2. 原生js+css3实现图片自动切换,图片轮播

    运用CSS3transition及opacity属性 制作图片轮播动画 自己这两天根据用js来控制触发CSS3中transition属性,从而写出来的以CSS3动画为基础,js控制过程的图片轮播 运用 ...

  3. 纯javaScript、jQuery实现个性化图片轮播

    纯javaScript实现个性化图片轮播 轮播原理说明<如上图所示>: 1. 画布部分(可视区域)属性说明:overflow:hidden使得超出画布部分隐藏或说不可见.position: ...

  4. jQuery个性化图片轮播效果

    jQuery个性化图片轮播效果 购物产品展示:图片轮播器<效果如下所示> 思路说明: 每隔一段时间,实现图片的自动切换及选项卡选中效果,鼠标划入图片动画停止,划出或离开动画开始 两个区域: ...

  5. 原生JS实现"旋转木马"效果的图片轮播插件

    一.写在最前面 最近都忙一些杂七杂八的事情,复习软考.研读经典...好像都好久没写过博客了... 我自己写过三个图片轮播,一个是简单的原生JS实现的,没有什么动画效果的,一个是结合JQuery实现的, ...

  6. 基于面向对象的图片轮播(js原生代码)

    无论你想走多远,你都需要不断地走下去.前端最精华的便是原生的js,这也是我们前端工程师的技术分层的重要指标,也提现这你的代码能力,开发的水平.废话不多说,进入今天的主要分享————基于面向对象思想的图 ...

  7. jquery 图片轮播demo实现

    转载注明出处!!! 转载注明出处!!! 转载注明出处!!! 图片轮播demo,弄清楚过程其实是一个很简单的东西,看网上都没有什么实质性的代码,就自己把过程捋了一遍实现了. 这次因为随手写的,所以没有做 ...

  8. PgwSlideshow-基于Jquery的图片轮播插件

    0 PgwSlideshow简介 PgwSlideshow是一款基于Jquery的图片轮播插件,基本布局分为上下结构,上方为大图轮播区域,用户可自定义图片轮播切换的间隔时间,也可以通过单击左右方向按键 ...

  9. 一分钟搞定AlloyTouch图片轮播

      一分钟搞定AlloyTouch图片轮播 轮播图也涉及到触摸和触摸反馈,同时,AlloyTouch可以把惯性运动打开或者关闭,并且设置min和max为运动区域,超出会自动回弹.除了一般的竖向滚动,A ...

随机推荐

  1. selenium2等待元素加载

    1.硬性等待 Thread.sleep(8000); 所谓的硬性等待就是,执行完相应操作就等待我设置的8s.无论网速快与慢,网速快的话,也许5s就打开网页了,可是程序必须接着等待剩下的3秒. 网速慢的 ...

  2. [转载] C语言细节,写的非常棒!

    这篇文章主要讨论C语言细节问题.在找一份工作的时候,语言细节占的比例非常小,之前看某个贴着讨论,估计语言细节在面试中,占了10%的比重都不到,那为什么还要研究C语言的细节呢,我觉得有三个原因促使我总结 ...

  3. Django基于Pycharm开发之一【创建django工程】

    Django的工程结构,可以通过pycharm里面,选择创建django工程来直接创建,也可以通过命令行通过pip来安装. 一.通过命令行安装的步骤 Install Python. Install a ...

  4. session属性的清除和非法登录

    有的项目会将登录用户的资料存于session的一个属性中,这样方便获取一些数据使用,但是用户退出时需要将session的这个属性清除,一面造成一些不必要的麻烦,但是有些时候,在后台清除了这个属性,在拦 ...

  5. luogu1501 [国家集训队]Tree II

    lct裸题 #include <iostream> #include <cstdio> using namespace std; typedef long long ll; i ...

  6. Leetcode31--->Next Permutation(数字的下一个排列)

    题目: 给定一个整数,存放在数组中,求出该整数的下一个排列(字典顺序):要求原地置换,且不能分配额外的内存 举例: 1,2,3 → 1,3,2:  3,2,1 → 1,2,3:  1,1,5 → 1, ...

  7. day05_05 for循环、break语句

    1.0 输入用户名,密码练习 _user = "alex" _passwd = "abc123" username = input("Username ...

  8. PHP 教父鸟哥 Yar 的原理分析

    模块越来越多,业务越来越复杂,RPC 就上场了,在 PHP 的世界里,鸟哥的作品一直备受广大网友的青睐.下面一起学习下鸟哥的 PRC 框架 Yar . 揭开 Yar 神秘面纱 RPC 采用客户端/服务 ...

  9. R语言采坑系列——Warning message: In validDetails.polygon(x) : 强制改变过程中产生了NA

    用ggplot2的geom_density_2d时,总是不能填充图案,并报错: Warning message: In validDetails.polygon(x) : 强制改变过程中产生了NA 解 ...

  10. [译] Pandas中根据列的值选取多行数据

    # 选取等于某些值的行记录 用 == df.loc[df['column_name'] == some_value] # 选取某列是否是某一类型的数值 用 isin df.loc[df['column ...