接上两篇:
前两篇介绍了发表界面的界面和图片选择的功能实现,这篇主要写图片预览功能的实现。
老规矩,先上效果图:
图像显示采用了开源的PhotoView,因为该开源项目在与ViewPager结合使用时存在一些bug,通过查阅资料,通过自定义ViewPager可以解决这个问题。具体代码如下:
public class PhotoViewPager extends ViewPager {
public PhotoViewPager(Context context) {
super(context);
}
public PhotoViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
try {
return super.onTouchEvent(ev);
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
try {
return super.onInterceptTouchEvent(ev);
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
使用了PhotoView的PagerAdapter需要做一些变化,具体如下:
public class PhotoViewPagerAdapter extends PagerAdapter {
private Context context;
private List<String> images;
private SparseArray<View> cacheView;
private ViewGroup containerGroup;
private LayoutInflater inflater;
public PhotoViewPagerAdapter(Context context, List<String> images) {
this.context = context;
this.images = images;
cacheView = new SparseArray<>(images.size());
inflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return images != null ? images.size() : 0;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
if (containerGroup == null) {
containerGroup = container;
}
View view = cacheView.get(position);
if (view == null) {
view = inflater.inflate(R.layout.layout_vp_image_item, container, false);
view.setTag(position);
final ImageView image = (ImageView) view.findViewById(R.id.id_image);
final PhotoViewAttacher photoViewAttacher = new PhotoViewAttacher(image);
if (images.get(position).startsWith("http")) {
Picasso.with(context)
.load(images.get(position))
.placeholder(R.drawable.ic_place_holder)
.error(R.drawable.ic_load_error)
.config(Bitmap.Config.RGB_565)
.into(image, new Callback() {
@Override
public void onSuccess() {
photoViewAttacher.update();
}
@Override
public void onError() {
}
});
} else {
Picasso.with(context)
.load(new File(images.get(position)))
.placeholder(R.drawable.ic_place_holder)
.error(R.drawable.ic_load_error)
.config(Bitmap.Config.RGB_565)
.into(image, new Callback() {
@Override
public void onSuccess() {
photoViewAttacher.update();
}
@Override
public void onError() {
}
});
}
photoViewAttacher.setOnPhotoTapListener(new PhotoViewAttacher.OnPhotoTapListener() {
@Override
public void onPhotoTap(View view, float v, float v1) {
Activity activity = (Activity) context;
activity.finish();
activity.overridePendingTransition(R.anim.zoom_in, R.anim.zoom_out);
}
@Override
public void onOutsidePhotoTap() {
}
});
}
container.addView(view);
return view;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
View view = (View) object;
container.removeView(view);
}
}
中间一段对字符串的判断是为了区别加载本地图片和网络图片。
准备工作做好其实功能基本上就完成了,主要就是通过ViewPager
来展示图片。先看布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.gdut.simple.view.widget.PhotoViewPager
android:id="@+id/id_photo_view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="@+id/id_photo_position"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="24dp"
android:textColor="@android:color/white"
android:textSize="16sp" />
</RelativeLayout>
布局文件采用了自定义的ViewPager
,主要是为了解决与PhotoView的冲突。
在PhotoPreviewActivity中,提供一个启动预览界面的方法:
public static void startActivity(Activity context, ArrayList<String> images, int position) {
Intent intent = new Intent(context, PhotoPreviewActivity.class);
intent.putStringArrayListExtra("images", images);
intent.putExtra("position", position);
context.startActivity(intent);
context.overridePendingTransition(R.anim.zoom_in, R.anim.zoom_out);
}
images
是要显示的图片地址,position
是第一张要显示图片的位置。通过这个方法启动Activity就可以通过以下方法处理数据:
private void initViewPager() {
Intent intent = getIntent();
if (intent != null) {
mImagesList = intent.getStringArrayListExtra("images");
mPosition = intent.getIntExtra("position", 0);
if (mImagesList == null) {
return;
}
mTotalCount = mImagesList.size();
mPhotoPosition.setText((mPosition + 1) + "/" + mTotalCount);
mPhotoAdapter = new PhotoViewPagerAdapter(this, mImagesList);
mPhotoViewPager.setAdapter(mPhotoAdapter);
mPhotoViewPager.setCurrentItem(mPosition);
mPhotoViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
mPosition = position;
mPhotoPosition.setText((mPosition + 1) + "/" + mTotalCount);
}
});
}
}
至此,图片预览的功能就已经实现。结合前两篇博客,一个发表动态的功能就已经实现了。
总结
通过写三篇博客,加深自己对该功能的理解,同时在编写过程中也发现程序的一些问题,这也算一种意外收获吧。在写博客的时候,才知道自己的语言是多么的贫乏,很多时候要靠代码去展示,可惜的是我的代码并没有什么注释,主要是因为功能比较简单,自己觉得不需要注释,但这终究不是一个好习惯,希望以后能改正。
代码或者是语言有不准确的地方,希望大家指出,莫要误人子弟。