編輯:關於Android編程
Demo實現的效果圖如下:

工程目錄如下圖:

一個Application,一個實體類,一個Activity,另一個是自定義的AutoPlayingViewPager繼承FrameLayout。
首先看一下自定義的AutoPlayingViewPager,功能都在這裡實現。采用了第三方圖片加載框架:universal_image_loader;
package com.skycracks.autoplayingviewpager;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import com.nostra13.universalimageloader.core.ImageLoader;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Scroller;
import android.widget.TextView;
/**
* 創建時間: 2016年1月10日 下午3:43:22
* 版本: [v1.0]
* 類描述: 實現ViewPager輪播圖
* 使用了ImageLoader 對圖片進行加載,所以使用前必須初始化ImageLoader
* stopPlaying() 當輪播所在頁面不在頂棧時,有必要停止定時並且釋放資源
* startPlaying() 當再次恢復時調用
*
*/
public class AutoPlayingViewPager extends FrameLayout {
private final static String TAG = "AutoPlayingViewPager";
/**
* 輪播圖圖片數量
*/
private int IMAGE_COUNT;
/**
* 自動輪播的時間間隔
*/
private final static int TIME_INTERVAL = 5;
/**
* 切換圖片過度時間
*/
private int swapDuration = 1000;
/**
* 默認圖片資源(本地圖片資源Id)
*/
private int [] defaultIds = new int[] {
R.drawable.image01,R.drawable.image02,
R.drawable.image03,R.drawable.image04,R.drawable.image05};
/**
* 默認圖片資源(圖片URL地址)
*/
private String [] defaultUrl = new String[] {
"http://g.hiphotos.baidu.com/imgad/pic/item/a8773912b31bb051be533b24317adab44aede043.jpg",
"http://g.hiphotos.baidu.com/imgad/pic/item/c75c10385343fbf22c362d2fb77eca8065388fa0.jpg",
"http://liaoning.sinaimg.cn/2014/1111/U10435P1195DT20141111220802.jpg",
"http://photocdn.sohu.com/20151124/mp43786429_1448294862260_4.jpeg",
"http://h.hiphotos.baidu.com/image/pic/item/faedab64034f78f0b00507c97e310a55b3191cf9.jpg" };
private String [] defaultTitle = new String [] {
"今晚打老虎","今晚打松鼠","今晚打LOL","今晚打DOTA1","今晚打DOTA2"};
/**
* 自定義輪播圖資源
*/
private List mAutoPlayInfoList;
/**
* 放圓點的View的list
*/
private List dotViewsList;
/**
* 輪播容器
*/
private ViewPager mViewPager;
/**
* 當前輪播頁
*/
private int currentItem = 0;
/**
* 定時器對象
*/
private ScheduledExecutorService scheduledExecutorService;
private Context mContext;
private LayoutInflater mInflate;
/**
* ViewPageItem點擊回調接口
*/
private OnPageItemClickListener onPageItemClickListener;
public void setOnPageItemClickListener(OnPageItemClickListener onPageItemClickListener){
this.onPageItemClickListener = onPageItemClickListener;
}
public interface OnPageItemClickListener{
/**
* ViewPageItem點擊事件回調
*/
void onPageItemClick(int position, String adLink);
}
/**
* 消息處理器、設置當前顯示頁
*/
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
mViewPager.setCurrentItem(currentItem);
}
};
public AutoPlayingViewPager(Context context) {
this(context, null);
}
public AutoPlayingViewPager(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public AutoPlayingViewPager(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
this.mContext = context;
initData();
}
/**
* 通過本地圖片資源Id獲得默認的數據
*/
private List getImageIdAutoPlayInfoList(int [] imageIds){
List autoPlayInfoList = new ArrayList();
for(int i = 0 ; i < imageIds.length ; i ++){
AutoPlayInfo autoPlayInfo = new AutoPlayInfo();
autoPlayInfo.setImageId(imageIds[i]);
autoPlayInfoList.add(autoPlayInfo);
}
return autoPlayInfoList;
}
/**
* 通過圖片URL地址獲得默認的數據
*/
private List getDefaultUrlAutoPlayInfoList(){
List autoPlayInfoList = new ArrayList();
for(int i = 0 ; i < defaultUrl.length ; i ++){
AutoPlayInfo autoPlayInfo = new AutoPlayInfo();
autoPlayInfo.setImageUrl(defaultUrl[i]);
autoPlayInfo.setAdLinks("http://m.baidu.com");
autoPlayInfo.setTitle(defaultTitle[i]);
autoPlayInfoList.add(autoPlayInfo);
}
return autoPlayInfoList;
}
/**
* 初始化
* @param imageIds 需要加載的圖片Id,根據傳入數量動態創建容器。
* @return
*/
public AutoPlayingViewPager initialize(int [] imageIds) {
if (imageIds != null && imageIds.length != 0) {
mAutoPlayInfoList = getImageIdAutoPlayInfoList(imageIds);
} else {//沒有數據使用默認的圖片資源
mAutoPlayInfoList = getImageIdAutoPlayInfoList(defaultIds);
}
IMAGE_COUNT = mAutoPlayInfoList.size();
return this;
}
/**
* 初始化
*
* @param imageUrls 需要加載的圖片地址,根據傳入數量動態創建容器。
* @return
*/
public AutoPlayingViewPager initialize(List autoPlayInfoList) {
if (autoPlayInfoList != null && !autoPlayInfoList.isEmpty()) {
mAutoPlayInfoList = autoPlayInfoList;
} else {//沒有數據使用默認的圖片資源
mAutoPlayInfoList = getDefaultUrlAutoPlayInfoList();
}
IMAGE_COUNT = mAutoPlayInfoList.size();
return this;
}
/**
* 設置圖片之間自動切換時間
*
* @param duration
* 切換時間
* @return
*/
public AutoPlayingViewPager setSwapDuration(int duration) {
this.swapDuration = duration;
return this;
}
/**
* 開始輪播圖切換 輪播之前必須調initialize()及build()
*/
public void startPlaying() {
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
scheduledExecutorService.scheduleAtFixedRate(new SlideShowTask(), 1,
TIME_INTERVAL, TimeUnit.SECONDS);
}
/**
* 停止輪播釋放資源
*/
public void stopPlaying() {
scheduledExecutorService.shutdown();
}
/**
* 初始化相關Data
*/
private void initData() {
dotViewsList = new ArrayList();
}
/**
* 初始化Views 及組件UI
*/
public void build() {
if (mAutoPlayInfoList == null || mAutoPlayInfoList.isEmpty()) {
Log.d(TAG, "init image fail ");
return;
}
mInflate = LayoutInflater.from(mContext);
mInflate.inflate(R.layout.view_layout_slideshow,this, true);
LinearLayout dotLayout = (LinearLayout) findViewById(R.id.dotLayout);
dotLayout.removeAllViews();// 清除布局中的子視圖,下面使用代碼動態添加與圖片對應的圓點
// 熱點個數與圖片數量相等
for (int i = 0; i < IMAGE_COUNT; i++) {
ImageView dotView = new ImageView(mContext);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.leftMargin = 4;
params.rightMargin = 4;
dotLayout.addView(dotView, params);
dotViewsList.add(dotView);
}
mViewPager = (ViewPager) findViewById(R.id.viewPager);
setViewPagerScrollSpeed();
mViewPager.setFocusable(true);
mViewPager.setOffscreenPageLimit(2);// 設置緩存頁面,當前頁面的相鄰N各頁面都會被緩存
mViewPager.setAdapter(new AutoPlayingPagerAdapter());
AutoPlayingPageChangeListener mPageChangeListener = new AutoPlayingPageChangeListener();
mViewPager.addOnPageChangeListener(mPageChangeListener);
}
/**
* 填充ViewPager的頁面適配器
*/
private class AutoPlayingPagerAdapter extends PagerAdapter {
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
@Override
public Object instantiateItem(ViewGroup container, final int position) {
final AutoPlayInfo autoPlayInfo = mAutoPlayInfoList.get(position % IMAGE_COUNT);
View view = mInflate.inflate(R.layout.item_label_auto_play_viewpager, null);
ImageView imageView = (ImageView) view.findViewById(R.id.img_item_auto_play);
TextView labelTitle = (TextView) view.findViewById(R.id.tv_item_label_title);
/* if(!TextUtils.isEmpty(autoPlayInfo.getAdLinks())){//有鏈接時才添加監聽
}*/
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
onPageItemClickListener.onPageItemClick(position % IMAGE_COUNT,autoPlayInfo.getAdLinks());
}
});
if(!TextUtils.isEmpty(autoPlayInfo.getImageUrl())){//通過URL時使用ImageLoader加載圖片
ImageLoader.getInstance().displayImage(autoPlayInfo.getImageUrl(),imageView);
}else if(autoPlayInfo.getImageId() != 0){//本地圖片時直接設置
imageView.setImageResource(autoPlayInfo.getImageId());
}
if(!TextUtils.isEmpty(autoPlayInfo.getTitle())){//有標題數據才顯示
labelTitle.setText(autoPlayInfo.getTitle());
}else{//沒有標題數據不顯示文本透明背景
labelTitle.setBackgroundDrawable(null);
}
container.addView(view);
return view;
}
@Override
public int getCount() {
return Integer.MAX_VALUE;
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
}
/**
* ViewPager的監聽器 當ViewPager中頁面的狀態發生改變時調用
*
*/
private class AutoPlayingPageChangeListener implements OnPageChangeListener {
// boolean isChange = false;
@Override
public void onPageScrollStateChanged(int arg0) {
switch (arg0) {
case 1:// 手勢滑動,空閒中
// isChange = false;
break;
case 2:// 界面切換中
// isChange = true;
break;
case 0:// 滑動結束,即切換完畢或者加載完畢
break;
}
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageSelected(int pos) {
currentItem = pos;
int p = pos % IMAGE_COUNT;
for (int i = 0; i < dotViewsList.size(); i++) {
if (i == p) {
dotViewsList.get(p).setBackgroundResource(
R.drawable.icon_cricle_check);
} else {
dotViewsList.get(i).setBackgroundResource(
R.drawable.icon_cricle_uncheck);
}
}
}
}
/**
* 執行輪播圖切換任務
*
*/
boolean isLR = false;
private class SlideShowTask implements Runnable {
@Override
public void run() {
synchronized (mViewPager) {
currentItem++;
handler.obtainMessage().sendToTarget();
}
}
}
/**
* 使用反射往ViewPager中設置新的Scroller對象 覆蓋默認的setCurrentItem切換時間
*/
private void setViewPagerScrollSpeed() {
try {
Field mScroller = null;
mScroller = ViewPager.class.getDeclaredField("mScroller");
mScroller.setAccessible(true);
FixedSpeedScroller scroller = new FixedSpeedScroller(
mViewPager.getContext());
mScroller.set(mViewPager, scroller);
} catch (NoSuchFieldException e) {
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
}
}
class FixedSpeedScroller extends Scroller {
public FixedSpeedScroller(Context context) {
super(context);
}
public FixedSpeedScroller(Context context, Interpolator interpolator) {
super(context, interpolator);
}
public FixedSpeedScroller(Context context, Interpolator interpolator,
boolean flywheel) {
super(context, interpolator, flywheel);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy,
int duration) {
super.startScroll(startX, startY, dx, dy, swapDuration);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy) {
super.startScroll(startX, startY, dx, dy, swapDuration);
}
}
}
當然想用上ImageLoad而必須在Application裡面注冊一下:
@Override
public void onCreate() {
super.onCreate();
initImageLoader();
}
/**
* 初始化UIL,這裡初始化以後,就不在初始化了
*/
public void initImageLoader() {
DisplayImageOptions.Builder options = new DisplayImageOptions.Builder()
.cacheInMemory(true)// 內存緩存
.cacheOnDisk(true)// 磁盤緩存
.showImageOnFail(R.drawable.ic_faile)//加載失敗顯示的圖片
.considerExifParams(true)// 是否考慮EXIF信息,比如拍照方向
.displayer(new FadeInBitmapDisplayer(300));//淡入動畫
ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(getApplicationContext());
// 取消緩存多張尺寸不同的同一張圖片
config.denyCacheImageMultipleSizesInMemory();
// 設置顯示選項
config.defaultDisplayImageOptions(options.build());
// 生成緩存文件的生成器,保證唯一的文件名,可以不設置,默認使用hash算法,也是可以保證不重名的
config.diskCacheFileNameGenerator(new Md5FileNameGenerator());
// 磁盤緩存大小
config.diskCacheSize(100 * 1024 * 1024); // 100 MB
// 內存緩存大小
config.memoryCacheSize((int) (Runtime.getRuntime().freeMemory() / 4));
// 任務處理順序,默認是FIFO 先進先出, LIFO 後進先出
config.tasksProcessingOrder(QueueProcessingType.LIFO);
// 打印調試日志
config.writeDebugLogs(); // Remove for release app
ImageLoader.getInstance().init(config.build());
}
最關鍵的就是調用:
布局直接調用自定義的ViewPager:
主方法中運用很簡單,只需把接收的對象集合傳到自定義的AutoPlayingViewPager。
看代碼:
package com.skycracks.autoplayingviewpager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;
import com.skycracks.autoplayingviewpager.AutoPlayingViewPager.OnPageItemClickListener;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private AutoPlayingViewPager mAutoPlayingViewPager;
/**
* 模擬網絡請求獲取的圖片URL
*/
private String [] imageUrl = new String[] {
"http://g.hiphotos.baidu.com/image/pic/item/d0c8a786c9177f3e117088eb75cf3bc79e3d568b.jpg",
"http://upload.cebnet.com.cn/2014/1217/1418776413348.jpg",
"http://n.sinaimg.cn/transform/20150917/7DDk-fxhytwp5363222.jpg",
"http://n.sinaimg.cn/transform/20151019/YtA_-fxivsce6931363.jpg"
};
private String [] imageTitle = new String [] {
"趙麗穎","高圓圓","王鷗","唐嫣"};
private List mAutoPlayInfoList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAutoPlayingViewPager = (AutoPlayingViewPager) findViewById(R.id.auto_play_viewpager);
mAutoPlayInfoList=new ArrayList<>();
for(int i = 0 ; i < imageUrl.length ; i ++){
//把模擬的數據添加到集合裡面
AutoPlayInfo autoPlayInfo = new AutoPlayInfo();
autoPlayInfo.setImageUrl(imageUrl[i]);
autoPlayInfo.setAdLinks("");
autoPlayInfo.setTitle(imageTitle[i]);
mAutoPlayInfoList.add(autoPlayInfo);
}
//通過這個方法把集合傳進去,並設置圖片的點擊事件,可以做跳轉
mAutoPlayingViewPager.initialize(mAutoPlayInfoList).build();
mAutoPlayingViewPager.setOnPageItemClickListener(onPageItemClickListener);
}
private OnPageItemClickListener onPageItemClickListener = new OnPageItemClickListener() {
@Override
public void onPageItemClick(int position, String adLink) {
Toast.makeText(MainActivity.this,"第"+position,Toast.LENGTH_LONG).show();
}
};
@Override
public void onStart() { //當Activity onRestart();還要執行,
//沒有數據時不執行startPlaying,避免執行幾次導致輪播混亂
if(mAutoPlayInfoList != null && !mAutoPlayInfoList.isEmpty()){
mAutoPlayingViewPager.startPlaying();
}
super.onResume();
}
@Override
public void onPause() {
mAutoPlayingViewPager.stopPlaying();
super.onPause();
}
}
最後幾個就是實體類:
public class AutoPlayInfo {
//輪播圖片URL
private String imageUrl;
//輪播本地圖片資源Id
private int imageId;
//鏈接
private String adLinks;
//圖片對應的標題
private String title;
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public int getImageId() {
return imageId;
}
public void setImageId(int imageId) {
this.imageId = imageId;
}
public String getAdLinks() {
return adLinks;
}
public void setAdLinks(String adLinks) {
this.adLinks = adLinks;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
另外,還有一種通過自定義ViewPager實現和本博文相同效果的廣告界面Demo,這裡就不再貼代碼。
Android-自定義滑動菜單(抽屜效果)
在Andoird使用Android自帶的那些組件,像SlidingDrawer和DrawerLayout都是抽屜效果的菜單,但是在項目很多要實現的功能都收到Android
最新基於高德地圖的android進階開發(3)GPS地圖定位
1.下面示例是一個簡單的定位,來自官網,對這些源碼加了一些注釋,這樣看起來可能會更容易理解一點。2.直接上源碼androidManifest.xml
騰訊wifi管家破解wifi密碼教程
騰訊Wifi管家app這是騰訊旗下的一款類似Wifi萬能鑰匙。一款騰訊WiFi管家在手,讓你一鍵連接WiFi,很多朋友都在問騰訊WiFi管家怎麼破解密碼?快
Android手機同時使用Wi-Fi和數據流量
Android手機同時使用Wi-Fi和數據流量大家都知道,當手機成功連接到Wi-Fi熱點以後,手機所產生的上網流量都是通過Wi-Fi來傳輸的,而手機的移動流量會被禁用。但