Android动态轮播焦点图
之前写过一个简单的轮播焦点图demo:Android 轮播焦点图简单实现,实现的功能比较简单,每一个轮播要单独写一个fragment,设置xml布局然后配置图片地址,昨天一个程序媛朋友提到要用网络图片来制作轮播焦点图.如果要像这样根据后台动态修改轮播的话,首先数量不确定,其次每一张图片都要建一个页面,修改起来也显得死板,并且不利于性能优化,于是写了一个工具类来帮助我们完成这些繁琐的操作,下面来看看代码:
首先是工具类 UrlImageHelper.java
package com.learn.fei.autoscroll;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.nostra13.universalimageloader.core.ImageLoader;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
/**
* 使用此工具类的方法:
* 准备工作:
* ①/导入Image_Loderjar包/
* ②/AndroidManifest中配置权限:
* <uses-permission android:name="android.permission.INTERNET" />
* <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
* ③/新建MyApplication配置Imageloder适配器
* ④/AndroidManifest中在Application中加入name属性/
* 正式使用:
* 1,调用setImg方法,传入对应参数
* 2,在需要的地方调用 autoScroll方法开始线程
* 3,在需要停止的调用stopAutoScroll方法停止自动滚动的线程
* Created by fei on 2015/12/25.
*/
public class UrlImageHelper {
private static Timer timer;
//初始banner下标
private static int bannerCount = 0;
//制作fragment工厂的xml.例如:R.layout.xxx
private static int resource;
//制作fragment工厂的xml里的ImageView的控件
private static int imageView;
//网络图片url数组
private static String[] imgs;
//viewpager
private static ViewPager viewPager;
//get set传入的viewpager
public static ViewPager getViewPager() {
return viewPager;
}
public static void setViewPager(ViewPager viewPager) {
UrlImageHelper.viewPager = viewPager;
}
//get set网络图片url数组
public static String[] getImgs() {
return imgs;
}
public static void setImgs(String[] imgs) {
UrlImageHelper.imgs = imgs;
}
/**
* 设置你的轮播画面的xml布局文件,需要内部包含一个ImageView
*
* @param resource 这个是你的xml文件,例如:R.layout.banner.xml
*/
public static void setResource(int resource) {
UrlImageHelper.resource = resource;
}
public static int getResource() {
return resource;
}
/**
* 设置你的轮播画面viewpager的xml布局文件里面的ImageView控件
*
* @param imageView 这个是你的xml文件中的图片的控件,例如:View view = findViewById(R.id.image_view);
*/
public static void setImageView(int imageView) {
UrlImageHelper.imageView = imageView;
}
public static int getImageView() {
return imageView;
}
/**
* 每一个fragment滚动画面的工厂方法
*/
public static class Banners extends Fragment {
private View parent;
private ImageView img;
private String imgUrl;
public Banners(String imgUrl) {
this.imgUrl = imgUrl;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
parent = LayoutInflater.from(getActivity()).inflate(getResource(), container, false);
img = (ImageView) parent.findViewById(getImageView());
ImageLoader.getInstance().displayImage(imgUrl, img);
return parent;
}
}
/**
* 这个方法用于迭代你的图片url数组,然后给每个图片实例一个fragment.
*
* @param fragmentActivity 这个是继承FragmentActivity的主java的Activity
* @param imgs 这个是要传的所有网络图片的String数组
* @param imageView 这个是你的xml文件中的图片的控件,
* 例如:ImageView imageView = (ImageView)findViewById(R.id.image_view)
* @param resources 放图片的xml的layout 例如:R.layout.xxx
* @param viewPager 继承FragmentActivity的主java的Activity的xml中的viewPager控件
*/
public static void setImg(FragmentActivity fragmentActivity, String[] imgs, int imageView, int resources, ViewPager viewPager) {
//设置fragment工厂的xml
setResource(resources);
//设置fragment工厂的中的ImageView控件
setImageView(imageView);
//创建一个map集合存储
Map<Integer, Banners> map = new HashMap<>();
//设置imgs
setImgs(imgs);
//设置viewPager
setViewPager(viewPager);
//每次循环添加一个banners到map中
for (int i = 0; i < imgs.length; i++) {
//给每个实例化的一个唯一标识
Integer bannerNames = i;
//这里 前面这个是每个new的banners的唯一标识,后面是实例化的Banners;
map.put(bannerNames, new Banners(imgs[i]));
}
/*
为了管理Activity中的fragments,需要使用FragmentManager.为了得到它,
需要调用Activity中的getFragmentManager()方法。
因为FragmentManager的API是在 Android 3.0,也即API level 11开始引入的,
所以对于之前的版本,需要使用support library中的FragmentActivity,
并且使用getSupportFragmentManager()方法。
*/
//如果多层嵌套fragment这里变成:manager = getChildFragmentManager();
FragmentManager manager = fragmentActivity.getSupportFragmentManager();
//调用viewpager适配器
MyPagerAdapter myPagerAdapter = new MyPagerAdapter(manager, map);
viewPager.setAdapter(myPagerAdapter);
//滑动监听
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
//滑动后调用initFocus改变其视图
initFocus(position);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
/**
* 自动滚动的方法
*
* @param howWaitScroll 延迟多久启动(秒为单位)
* @param howLongScroll 多久秒滚动一次(秒为单位)
*/
public static void autoScroll(int howWaitScroll, int howLongScroll) {
int howLongScrollS = howLongScroll * 1000;
int howWaitScrollS = howWaitScroll * 1000;
timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
//滚动逻辑
if (bannerCount < UrlImageHelper.getImgs().length - 1) {
bannerCount = getViewPager().getCurrentItem();
bannerCount++;
} else {
bannerCount = 0;
}
//发送消息给handler
Message message = mHandler.obtainMessage();
message.what = 1001;
message.obj = bannerCount;
mHandler.sendMessage(message);
}
};
timer.schedule(task, howWaitScrollS, howLongScrollS);
}
public static void stopAutoScroll() {
timer.cancel();
}
/**
* handler接收消息并交给initFocus方法处理
*/
public static Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 1001) {
int count = (int) msg.obj;
initFocus(count);
}
}
};
/**
* 这个是滑动后显示当前传入count的下标的轮播画面
* 之所以提出来是增强扩展性,如果要加入轮播下面的小焦点或者加入文字的话,
* 都可以在这里面初始化并根据count改变内容
*
* @param count 你要显示的轮播子页面的下标
*/
public static void initFocus(int count) {
getViewPager().setCurrentItem(count);
}
}
/**
* fragment的自定义适配器
*/
class MyPagerAdapter extends FragmentStatePagerAdapter {
private Map<Integer, UrlImageHelper.Banners> map;
public MyPagerAdapter(FragmentManager fm, Map<Integer, UrlImageHelper.Banners> map) {
super(fm);
this.map = map;
}
@Override
public Fragment getItem(int position) {
return map.get(position);
}
@Override
public int getCount() {
return map.size();
}
}
下面是演示的例子:
主java文件: MainActivity.java
package com.learn.fei.autoscroll;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager viewPger = (ViewPager) findViewById(R.id.banner_pager);
//模拟数据源
String[] ImageUrls ={"http://f.hiphotos.baidu.com/zhidao/pic/item/1ad5ad6eddc451dac40eaa9ab6fd5266d11632c2.jpg"
,"http://g.hiphotos.baidu.com/zhidao/pic/item/9f510fb30f2442a797a55138d043ad4bd0130287.jpg"
,"http://b.hiphotos.baidu.com/zhidao/pic/item/241f95cad1c8a786e003f0d66509c93d70cf5038.jpg"
,"http://attachments.gfan.com/forum/attachments2/day_111015/11101516078db7b14d1d8ebe71.jpg"
,"http://pic.33.la/zmbz/katong/dies%20iraed_35951.jpg"
,"http://imgsrc.baidu.com/forum/pic/item/54fbb2fb43166d22c3cd8c09462309f79152d2f1.jpg"};
//传入对应参数
UrlImageHelper.setImg(MainActivity.this, ImageUrls, R.id.image_view, R.layout.view_pager, viewPger);
//设置开始的延迟和滚动间隔秒数(秒为单位)
UrlImageHelper.autoScroll(2,2);
}
@Override
protected void onDestroy() {
super.onDestroy();
//设置什么时候停止滚动的这个线程
UrlImageHelper.stopAutoScroll();
}
}
Application的配置文件: MyApplication.java
package com.learn.fei.autoscroll;
import android.app.Application;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
/**
*
* Created by fei on 2015/12/8.
*/
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
//****************
DisplayImageOptions options = new DisplayImageOptions.Builder()
// .showImageOnFail(R.drawable.add_photo_default)
// .showImageOnLoading(R.drawable.add_photo_default)
//图片显示大小恰好
.imageScaleType(ImageScaleType.EXACTLY)
.cacheInMemory(true)
.cacheOnDisk(true)
.build();
ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.Builder(this)
// .memoryCacheExtraOptions(480,720)
.defaultDisplayImageOptions(options)
.build();
ImageLoader.getInstance().init(configuration);
///**************
}
}
配置完成后需要在manifests配置文件的Application标签中加入name属性: android:name=".MyApplication"
并在manifests中添加权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
xml布局:
主mainActivity的布局xml: main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#8dc178"
tools:context=".MainActivity">
<android.support.v4.view.ViewPager
android:id="@+id/banner_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
viewPager的布局xml: view_pager.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<ImageView
android:id="@+id/image_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
以上就是完整的例子展示了,其中可扩展的地方还很多,当然也有很多不足之处,如果有什么意见或者疑问的话可以在私信或者评论,大家一起交流讨论一番.