在实际的开发中,我们市场会遇到这样的情况:点击某图片,浏览某列表(某列表详情)中的所有图片数据,当然,这些图片是可以放大和缩小的,比如我们看下百度贴吧的浏览大图的效果:
链接
这种功能,在一些app中是必不可少的!那如何实现呢?接下来,我将介绍通过ViewPager结合PhotoView开源组件,实现这么样的经典效果!
关于ViewPager如何使用,此文不多介绍,网络上太多相关的知识了;而PhotoView,因为它是一个开源的组件,所以如果你不深入研究它的话,只需要掌握它基本的用法即可!
何为PhotoView?
PhotoView的github地址: https://github.com/chrisbanes/PhotoView
PhotoView特性:
支持单点/多点触摸,即时缩放图片;
支持平滑滚动;
在滑动父控件下能够运行良好;(例如:ViewPager)
当用户的触点改变时可以触发通知。
关于如何PhotoView的详解,且参考如下文章:PhotoView开源项目剖析
当你了解了基本的知识后,下面直接带你进入实例:
1. 先定义网络请求,实现图片列表:
1.1 列表样式
1.2 适配器
public class KechengAdapter extends BaseAdapter {
private Context mContext;
private LayoutInflater mInflater;
private List mDatas;
private OnImgClickListener onImgClickListener;
public void setOnImgClickListener(OnImgClickListener onImgClickListener){
this.onImgClickListener = onImgClickListener;
}
public KechengAdapter(Context context, List 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;
}
}
注; Adapter中主要添加了一个回调接口,当你单机图片的时候,进入下一级图片浏览页面!
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 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() {
@Override
public void onSuccess(ResponseInfo 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 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定义
3.2 ViewPager逻辑实现:
public class ImageBrowseActivity extends Activity {
private ViewPager search_viewpager;
private List 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();
}
}
3.3 在ViewPager适配器PagerAdapter中实现网络图片的加载浏览:
public class MyViewPagerAdapter extends PagerAdapter {
List imgs;
Context mContext;
public MyViewPagerAdapter(Context context, List 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;
}
关于ImageLoader工具类,可以参考我之前的一篇博客:Android ListView性能优化实例讲解
基本上,通过以上方法,就可以实现网络图片在线浏览功能了,让我们看下效果吧:
后续: 本文主要介绍了通过PhotoView实现图片的缩放,放大缩小查看,其实还有一个开源项目GestureImageView,其github地址是:https://github.com/jasonpolites/gesture-imageview ,我也通过该开源项目实现了图片浏览,不过发现其效果并不如PhotoView那么好(主要表现在图片加载显示速度慢,不方面控制),代码会一起提供给大家参考。
源代码下载地址:https://github.com/zuiwuyuan/ImgsBrowse