Android 使用ViewPager結合PhotoView開源元件實現網路圖片線上瀏覽功能
在實際的開發中,我們市場會遇到這樣的情況:點選某圖片,瀏覽某列表(某列表詳情)中的所有圖片資料,當然,這些圖片是可以放大和縮小的,比如我們看下百度貼吧的瀏覽大圖的效果:
連結
這種功能,在一些app中是必不可少的!那如何實現呢?接下來,我將介紹通過ViewPager結合PhotoView開源元件,實現這麼樣的經典效果!
關於ViewPager如何使用,此文不多介紹,網路上太多相關的知識了;而PhotoView,因為它是一個開源的元件,所以如果你不深入研究它的話,只需要掌握它基本的用法即可!
何為PhotoView?
PhotoView特性:
支援單點/多點觸控,即時縮放圖片;
支援平滑滾動;
在滑動父控制元件下能夠執行良好;(例如:ViewPager)
當用戶的觸點改變時可以觸發通知。
關於如何PhotoView的詳解,且參考如下文章:PhotoView開源專案剖析
當你瞭解了基本的知識後,下面直接帶你進入例項:
1. 先定義網路請求,實現圖片列表:
1.1 列表樣式
<?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" android:orientation="vertical"> <ImageView android:id="@+id/picBig" android:layout_width="fill_parent" android:layout_height="180dp" android:scaleType="fitXY" android:src="@mipmap/ic_launcher" /> <TextView android:id="@+id/name" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="CSS動畫實用技巧" android:singleLine="true" android:padding="10dp" android:textSize="15sp" /> <TextView android:id="@+id/description" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="教你使用CSS實現驚豔的動畫效果!" android:textSize="12sp" android:lines="2" android:padding="10dp" /> </LinearLayout>
1.2 介面卡
注; Adapter中主要添加了一個回撥介面,當你單機圖片的時候,進入下一級圖片瀏覽頁面!public class KechengAdapter extends BaseAdapter { private Context mContext; private LayoutInflater mInflater; private List<KeCheng> mDatas; private OnImgClickListener onImgClickListener; public void setOnImgClickListener(OnImgClickListener onImgClickListener){ this.onImgClickListener = onImgClickListener; } public KechengAdapter(Context context, List<KeCheng> datas) { mContext = context; mInflater = LayoutInflater.from(mContext); mDatas = datas; } @Override public int getCount() { return (mDatas != null ? mDatas.size() : 0); } @Override public Object getItem(int position) { return (mDatas != null ? mDatas.get(position) : null); } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { convertView = mInflater.inflate(R.layout.list_item_kecheng, null); holder = new ViewHolder(); holder.picBig = (ImageView) convertView.findViewById(R.id.picBig); holder.name = (TextView) convertView.findViewById(R.id.name); holder.description = (TextView) convertView.findViewById(R.id.description); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } final KeCheng keCheng = mDatas.get(position); if (keCheng != null) { ImageLoaderUtil.getInstance().displayListItemImage(keCheng.picBig, holder.picBig); holder.name.setText(keCheng.name); holder.description.setText(keCheng.description); holder.picBig.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onImgClickListener.handleBrowse(position); } }); } return convertView; } public interface OnImgClickListener{ void handleBrowse(int position); } static class ViewHolder { ImageView picBig; TextView name; TextView description; } }
2. 列表邏輯實現,及點選某一個圖片,進入下一級頁面,該頁面即為圖片瀏覽頁面:
public class MainActivity extends Activity implements KechengAdapter.OnImgClickListener {
private String BASE_URL = "http://www.imooc.com/api/teacher?type=4&num=10";
@ViewInject(R.id.main_layout)
private RelativeLayout main_layout;
@ViewInject(R.id.list_kecheng)
private ListView listKecheng;
private List<KeCheng> cks;
private KechengAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
ViewUtils.inject(this);
getDataFromServer();
}
/**
* 獲取網路資料
*/
private void getDataFromServer() {
HttpUtils http = new HttpUtils();
http.configCurrentHttpCacheExpiry(1000 * 5);
// 設定超時時間
http.configTimeout(5 * 1000);
http.configSoTimeout(5 * 1000);
http.send(HttpRequest.HttpMethod.GET, BASE_URL, null, new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
Gson gson = new Gson();
RspData rspData = gson.fromJson(responseInfo.result, RspData.class);
cks = rspData.data;
if (mAdapter == null) {
mAdapter = new KechengAdapter(MainActivity.this, cks);
listKecheng.setAdapter(mAdapter);
mAdapter.setOnImgClickListener(MainActivity.this);
} else {
mAdapter.notifyDataSetChanged();
}
}
@Override
public void onFailure(HttpException e, String s) {
}
});
}
@Override
public void handleBrowse(int position) {
ArrayList<String> imgs = new ArrayList<>();
for (KeCheng data : cks) {
imgs.add(data.picBig);
}
Intent intent = new Intent(this, ImageBrowseActivity.class);
intent.putExtra("position", position);
intent.putStringArrayListExtra("imgs", imgs);
startActivity(intent);
}
}
3. 圖片瀏覽頁面,使用ViewPager實現突破瀏覽:
3.1 ViewPager定義
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="@+id/imgs_viewpager"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
<ImageView
android:id="@+id/img_browse_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="25dp"
android:padding="5dp"
android:onClick="onBack"
android:src="@mipmap/img_browse_back" />
</FrameLayout>
注: ViewPager為圖片滑動瀏覽容器,ImageView為返回按鈕(返回到上一級頁面)
3.2 ViewPager邏輯實現:
public class ImageBrowseActivity extends Activity {
private ViewPager search_viewpager;
private List<String> imgs;
private int position;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_browse);
this.position = getIntent().getIntExtra("position", 0);
this.imgs = getIntent().getStringArrayListExtra("imgs");
search_viewpager = (ViewPager) this.findViewById(R.id.imgs_viewpager);
search_viewpager.setOffscreenPageLimit(2);
System.out.println("position:" + position);
System.out.println("imgs :" + imgs.size());
PagerAdapter adapter = new MyViewPagerAdapter(this, imgs);
search_viewpager.setAdapter(adapter);
search_viewpager.setCurrentItem(position);
}
public void onBack(View view) {
finish();
}
}
注: 設定ViewPager基本資訊,並通過viewPager.setCurrentItem來定義當前顯示哪一個圖片,(位置的資訊由上一級頁面傳遞過來);
3.3 在ViewPager介面卡PagerAdapter中實現網路圖片的載入瀏覽:
public class MyViewPagerAdapter extends PagerAdapter {
List<String> imgs;
Context mContext;
public MyViewPagerAdapter(Context context, List<String> imgs) {
this.mContext = context;
this.imgs = imgs;
}
@Override
public int getCount() { // 獲得size
return imgs.size();
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((View) object);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
String imgUrl = imgs.get(position);
LinearLayout view = (LinearLayout) LayoutInflater.from(mContext).inflate(R.layout.img_browse, null);
PhotoView img = (PhotoView) view.findViewById(R.id.img_plan);
img.setTag(imgUrl);
ImageLoaderUtil.getInstance().displayListItemImage(imgs.get(position), img);
((ViewPager) container).addView(view);
return view;
}
注: 此處重點是兩個方法,instantiateItem主要是載入View,在此處,通過ImageLoader載入網路圖片;destroyItem中需要移除該View,避免View重複載入。
基本上,通過以上方法,就可以實現網路圖片線上瀏覽功能了,讓我們看下效果吧:
後續: 本文主要介紹了通過PhotoView實現圖片的縮放,放大縮小檢視,其實還有一個開源專案GestureImageView,其github地址是:https://github.com/jasonpolites/gesture-imageview ,我也通過該開源專案實現了圖片瀏覽,不過發現其效果並不如PhotoView那麼好(主要表現在圖片載入顯示速度慢,不方面控制),程式碼會一起提供給大家參考。