之前因为项目需要,要做一个类似于金融app上的图片轮播,后来我才发现原来 时候时候发现很多要么是太复杂,要么是有一些bug,还有一些非要用到Universal_Image_loader或者一些第三方的lib包,我就很不理解,我就是想单独使用这个功能,干嘛非要引一些乱七八糟的包呢,难道就没有一个类似于官方控件的东西使用。总而言之,言而总之,就是没有那种拿来就可以用的东西。
经过几天的探索,也借鉴很多大神们的杰作,终于在一个月黑风高的下午,我完成了android图片轮播的第一步,将图片轮播的第一个版本做了出来,里面借鉴了一些github上的项目,例如https://github.com/loopj/android-smart-image-view(smartImageView_图片缓存),https://github.com/daikainan/imagecycleview(imagecycleview _图片轮播),这些都是精髓啊,童鞋们。
好了,童鞋们,言归正传,我们开始来看看我辛苦的结果
首先,先看效果
在这里实时项目的代码和资源文件,只要把这些拷到你的项目中,你的项目就已经完成来了两个功能,一个是引导界面,一个是图片轮播,是不是很开心
好了好了,为我们先看看怎么用吧,这样你就算不看下面的源码分析也一样可以使用我们的项目。
####carousel_view.xml: ####
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ad_rl"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v4.view.ViewPager
android:id="@+id/adv_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</android.support.v4.view.ViewPager>
<LinearLayout
android:id="@+id/viewGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="8dp"
android:gravity="center"
android:orientation="horizontal" >
</LinearLayout>
</RelativeLayout>
####UrlActivity:##
package com.dds.carousel;
import java.util.ArrayList;
import com.dds.carousel.carousel.CarouselView;
import com.dds.carousel.carousel.CarouselView.ImageCycleViewListener;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
/*
* 测试图片轮播效果 设置url
*/
public class UrlActivity extends Activity {
private CarouselView mAdView;
private ArrayList<String> mImageUrl = null;
// 此处的url一部获取到
private String imageUrl1 = "http://pic31.nipic.com/20130702/2926417_003653575119_2.jpg";
private String imageUrl2 = "http://pic.58pic.com/58pic/11/22/39/458PICK58PICgAk.jpg";
private String imageUrl3 = "http://pic2.ooopic.com/12/52/76/42bOOOPIC81_1024.jpg";
public int stype = 0;// 这个是底部指示器,1为长条形,0为圆形
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageUrl = new ArrayList<String>();
mImageUrl.add(imageUrl1);
mImageUrl.add(imageUrl2);
mImageUrl.add(imageUrl3);
mAdView = (CarouselView) findViewById(R.id.ad_view);
mAdView.setImageUrlResources(mImageUrl, mAdCycleViewListener, stype);
}
private ImageCycleViewListener mAdCycleViewListener = new ImageCycleViewListener() {
@Override
public void onImageClick(int position, View imageView) {
Toast.makeText(UrlActivity.this, mImageUrl.get(position) + position, Toast.LENGTH_SHORT).show();
}
};
}
是不是很简单,只需要你将url的列表设置上去就可以了,这个url可是你异步从晚上获取的哦,并且还可以设置点击的监听,再也不用担心图片轮播花费你的时间了,啊哈哈哈哈哈
,另外代码里面也写了获取本地资源文件的demo,从此以后你就可以省去做这一步的麻烦了 。
最后我们进行源码分析吧,
-
轮播分析
CarouselView.java:主要在这个文件中,点击它就可看到源码,
这里主要是用到了ViewPager,将滑动的数量设置为 Integer.MAX_VALUE,之前看到了别人写的代码是将最后一张放到第一张的前面,将第一张放到最后一张的后面,形成 C - A- B -C - A这样的顺序也可实现想要的效果,并且解决滑动中的小bug,但我总觉得那样不太好弄,而我这个的扩展性是很好的,我会慢慢往里面增加内容,大家共同学习 -
图片缓存
SmartImageView:
这是github上的一个项目,我单独提取一部分内容,后来我发现这个写的和我在培训机构里学到的原理居然是相同的,以前我在课堂上也写过一个类似的,我这里就不贴源码了,点击前面蓝色内容就可以跳转到项目界面,我还会将以前的代码放到github上和大家一起学习
本项目扩展性很好,大家可以一起交流学习,那么就到这了
https://github.com/ddssingsong/CarouselView.git
这个是Eclipse版本的内容,如果想换到android studio 请看下面的内容
@添加
2016年10月10日
之前对这个讲解的不是很透彻,搞的我自己都不是太明白,下面根 据https://github.com/ddssingsong/CirculateView_smartview,来具体讲解用法
基础控件:viewpager 重写LinearLayout
几个关键点
- 自动轮播
使用Handler中的postDelayed(Runnable r, long delayMillis)方法制作一个自动发送器,每隔3秒发送一个指令进行图片轮播,
代码如下
private Handler mHandler = new Handler();
/**
* 图片自动轮播Task
*/
private Runnable mImageTimerTask = new Runnable() {
@Override
public void run() {
mAdvPager.setCurrentItem(mAdvPager.getCurrentItem() + 1);
// 就一直在后台循环
mHandler.postDelayed(mImageTimerTask, 3000);
}
};
然后在轮播开启的时候注册这个自动发送器, 在轮播停止的时候移除这个轮播,并设置一个标志位表明轮播已经停止
mHandler.postDelayed(mImageTimerTask, 3000);//注册
mHandler.removeCallbacks(mImageTimerTask);//移除
2.无限轮播
这里的无限轮播是设置一个比较大的值`Integer.MAX_VALUE`作为ViewPager的中的Item个数,当滑动到最后一个item时,继续向里面添加数据,通过`position % mAdList.size() (位置%需要展示的图片个数=当前显示的图片的position)` 计算出需要装载的图片进行装填
代码如下
private class ImageCycleAdapter extends PagerAdapter {
/**
* 图片视图缓存列表
*/
private ArrayList<SmartImageView> mImageViewCacheList;
/**
* 图片资源列表
*/
private ArrayList<String> mAdList = new ArrayList<String>();
private ArrayList<String> mATitle = new ArrayList<String>();
/**
* 广告图片点击监听
*/
private ImageCycleViewListener mImageCycleViewListener;
private Context mContext;
public ImageCycleAdapter(Context context, ArrayList<String> adList, ArrayList<String> title,
ImageCycleViewListener imageCycleViewListener) {
this.mContext = context;
this.mAdList = adList;
this.mATitle = title;
mImageCycleViewListener = imageCycleViewListener;
mImageViewCacheList = new ArrayList<SmartImageView>();
}
@Override
public int getCount() {
return Integer.MAX_VALUE;//设置一个很大的值
}
@Override
public boolean isViewFromObject(View view, Object obj) {
return view == obj;
}
@Override
public Object instantiateItem(ViewGroup container, final int position) {
String imageUrl = mAdList.get(position % mAdList.size());//算出需要装填的图片
String title = mATitle.get(position % mATitle.size());//算出需要装填的标题,
viewGroup2.setText(title);
SmartImageView imageView = null;
if (mImageViewCacheList.isEmpty()) {
imageView = new SmartImageView(mContext);
imageView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
imageView.setScaleType(ScaleType.CENTER_CROP);
} else {
imageView = mImageViewCacheList.remove(0);
}
// 设置图片点击监听
imageView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mImageCycleViewListener.onImageClick(position % mAdList.size(), v);
}
});
imageView.setTag(imageUrl);
container.addView(imageView);
imageView.setImageUrl(imageUrl, null);//设置图片
return imageView;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
SmartImageView view = (SmartImageView) object;
mAdvPager.removeView(view);
mImageViewCacheList.add(view);
}
}
3.触摸时停止自动滑动,松开时重新开始
这个使用到了事件的分发,用到了`dispatchTouchEvent(MotionEvent event)`方法,来对触摸事件进行监听
代码如下
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
//当手指离开屏幕的时候开始滑动事件,其他事件停止滑动
if (event.getAction() == MotionEvent.ACTION_UP) {
startImageTimerTask();
} else {
stopImageTimerTask();
}
return super.dispatchTouchEvent(event);
}
4.图片的缓存
这里使用一个libary是SmartView,一个轻量级的图片缓存框架,这里只使用了它最简单的方法,
SmartImageView imageView = new SmartImageView(mContext);
imageView .setImageUrl(imageUrl, null)
这个框架可以进行三级缓存,也可以添加Loading中和Loadng失败的图片,具体请看上面的介绍。。。
5.设置轮播图片的点击监听,一个接口搞定,这里不再赘述
public interface ImageCycleViewListener {
void onImageClick(int position, View imageView);
}
6.指示器的添加
本demo中有两种指示器,以后再改,现在没时间了
**源码:**https://github.com/ddssingsong/CirculateView_smartview,持续更新中