android 應用中,如歡迎指引頁面, 和圖片輪播功能, 或者更多的內容在一頁顯示不了,要分成多個頁面,這時候viewpager是很好用的。
首先看下效果:
下面是一個例子,帶異步網絡加載圖片,並帶導航小圓點<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PGJyPgo8L3A+CjxwPjwvcD4KPHByZSBjbGFzcz0="brush:java;">package com.example.viewpagertest;
import java.io.IOException;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreConnectionPNames;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
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.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.example.viewpagertest.MainActivity.AsyncImageLoader.ImageCallback;
/***
*
* 說明:ViewPager ,帶小圓點導航,適配器采用PagerAdapter,基本可以滿足需求
* 也可以采用FragmentPagerAdapter,有人說,Fragment可以更好的適應平板和手機,
* 並且可以更好的代碼重用,具體這些好處大家試一下就知道了。
*
* @author andylaw
*
* 更多內容請查看博客:http://blog.csdn.net/lyc66666666666
*
*/
@SuppressLint("NewApi")
public class MainActivity extends Activity {
private ViewPager view_pager;
private LayoutInflater inflater;
// 圖片的地址,這裡可以從服務器獲取
String[] urls = new String[]{
"http://a.hiphotos.baidu.com/image/pic/item/3bf33a87e950352ad6465dad5143fbf2b2118b6b.jpg",
"http://a.hiphotos.baidu.com/image/pic/item/c8177f3e6709c93d002077529d3df8dcd0005440.jpg",
"http://f.hiphotos.baidu.com/image/pic/item/7aec54e736d12f2ecc3d90f84dc2d56285356869.jpg",
"http://e.hiphotos.baidu.com/image/pic/item/9c16fdfaaf51f3de308a87fc96eef01f3a297969.jpg",
"http://d.hiphotos.baidu.com/image/pic/item/f31fbe096b63f624b88f7e8e8544ebf81b4ca369.jpg",
"http://h.hiphotos.baidu.com/image/pic/item/11385343fbf2b2117c2dc3c3c88065380cd78e38.jpg",
"http://c.hiphotos.baidu.com/image/pic/item/3801213fb80e7bec5ed8456c2d2eb9389b506b38.jpg"
};
private ImageView image;
private View item ;
private MyAdapter adapter ;
private ImageView[] indicator_imgs = new ImageView[7];//存放引到圖片數組
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
view_pager = (ViewPager) findViewById(R.id.view_pager);
List list = new ArrayList();
inflater = LayoutInflater.from(this);
/**
* 創建多個item (每一條viewPager都是一個item)
* 從服務器獲取完數據(如文章標題、url地址) 後,再設置適配器
*/
for (int i = 0; i < 7; i++) {
item = inflater.inflate(R.layout.item, null);
((TextView) item.findViewById(R.id.text_view)).setText("第 " + i+ " 個 viewPager");
list.add(item);
}
//創建適配器, 把組裝完的組件傳遞進去
adapter = new MyAdapter(list);
view_pager.setAdapter(adapter);
//綁定動作監聽器:如翻頁的動畫
view_pager.setOnPageChangeListener(new MyListener());
initIndicator();
}
/**
* 初始化引導圖標
* 動態創建多個小圓點,然後組裝到線性布局裡
*/
private void initIndicator(){
ImageView imgView;
View v = findViewById(R.id.indicator);// 線性水平布局,負責動態調整導航圖標
for (int i = 0; i < 7; i++) {
imgView = new ImageView(this);
LinearLayout.LayoutParams params_linear = new LinearLayout.LayoutParams(10,10);
params_linear.setMargins(7, 10, 7, 10);
imgView.setLayoutParams(params_linear);
indicator_imgs[i] = imgView;
if (i == 0) { // 初始化第一個為選中狀態
indicator_imgs[i].setBackgroundResource(R.drawable.indicator_focused);
} else {
indicator_imgs[i].setBackgroundResource(R.drawable.indicator);
}
((ViewGroup)v).addView(indicator_imgs[i]);
}
}
/**
* 適配器,負責裝配 、銷毀 數據 和 組件 。
*/
private class MyAdapter extends PagerAdapter {
private List mList;
private AsyncImageLoader asyncImageLoader;
public MyAdapter(List list) {
mList = list;
asyncImageLoader = new AsyncImageLoader();
}
/**
* Return the number of views available.
*/
@Override
public int getCount() {
// TODO Auto-generated method stub
return mList.size();
}
/**
* Remove a page for the given position.
* 滑動過後就銷毀 ,銷毀當前頁的前一個的前一個的頁!
* instantiateItem(View container, int position)
* This method was deprecated in API level . Use instantiateItem(ViewGroup, int)
*/
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// TODO Auto-generated method stub
container.removeView(mList.get(position));
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
// TODO Auto-generated method stub
return arg0==arg1;
}
/**
* Create the page for the given position.
*/
@Override
public Object instantiateItem(final ViewGroup container, final int position) {
Drawable cachedImage = asyncImageLoader.loadDrawable(
urls[position], new ImageCallback() {
public void imageLoaded(Drawable imageDrawable,
String imageUrl) {
View view = mList.get(position);
image = ((ImageView) view.findViewById(R.id.image));
image.setBackground(imageDrawable);
container.removeView(mList.get(position));
container.addView(mList.get(position));
// adapter.notifyDataSetChanged();
}
});
View view = mList.get(position);
image = ((ImageView) view.findViewById(R.id.image));
image.setBackground(cachedImage);
container.removeView(mList.get(position));
container.addView(mList.get(position));
// adapter.notifyDataSetChanged();
return mList.get(position);
}
}
/**
* 動作監聽器,可異步加載圖片
*
*/
private class MyListener implements OnPageChangeListener{
@Override
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub
if (state == 0) {
//new MyAdapter(null).notifyDataSetChanged();
}
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
@Override
public void onPageSelected(int position) {
// 改變所有導航的背景圖片為:未選中
for (int i = 0; i < indicator_imgs.length; i++) {
indicator_imgs[i].setBackgroundResource(R.drawable.indicator);
}
// 改變當前背景圖片為:選中
indicator_imgs[position].setBackgroundResource(R.drawable.indicator_focused);
}
}
/**
* 異步加載圖片
*/
static class AsyncImageLoader {
// 軟引用,使用內存做臨時緩存 (程序退出,或內存不夠則清除軟引用)
private HashMap> imageCache;
public AsyncImageLoader() {
imageCache = new HashMap>();
}
/**
* 定義回調接口
*/
public interface ImageCallback {
public void imageLoaded(Drawable imageDrawable, String imageUrl);
}
/**
* 創建子線程加載圖片
* 子線程加載完圖片交給handler處理(子線程不能更新ui,而handler處在主線程,可以更新ui)
* handler又交給imageCallback,imageCallback須要自己來實現,在這裡可以對回調參數進行處理
*
* @param imageUrl :須要加載的圖片url
* @param imageCallback:
* @return
*/
public Drawable loadDrawable(final String imageUrl,
final ImageCallback imageCallback) {
//如果緩存中存在圖片 ,則首先使用緩存
if (imageCache.containsKey(imageUrl)) {
SoftReference softReference = imageCache.get(imageUrl);
Drawable drawable = softReference.get();
if (drawable != null) {
imageCallback.imageLoaded(drawable, imageUrl);//執行回調
return drawable;
}
}
/**
* 在主線程裡執行回調,更新視圖
*/
final Handler handler = new Handler() {
public void handleMessage(Message message) {
imageCallback.imageLoaded((Drawable) message.obj, imageUrl);
}
};
/**
* 創建子線程訪問網絡並加載圖片 ,把結果交給handler處理
*/
new Thread() {
@Override
public void run() {
Drawable drawable = loadImageFromUrl(imageUrl);
// 下載完的圖片放到緩存裡
imageCache.put(imageUrl, new SoftReference(drawable));
Message message = handler.obtainMessage(0, drawable);
handler.sendMessage(message);
}
}.start();
return null;
}
/**
* 下載圖片 (注意HttpClient 和httpUrlConnection的區別)
*/
public Drawable loadImageFromUrl(String url) {
try {
HttpClient client = new DefaultHttpClient();
client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 1000*15);
HttpGet get = new HttpGet(url);
HttpResponse response;
response = client.execute(get);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
Drawable d = Drawable.createFromStream(entity.getContent(),
"src");
return d;
} else {
return null;
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
//清除緩存
public void clearCache() {
if (this.imageCache.size() > 0) {
this.imageCache.clear();
}
}
}
}
下面是layout主文件:
下面是每一條item文件:
代碼下載地址