Android仿微信图片选择器(三)

2017-05-12  本文已影响0人  逸先森

接上两篇:

前两篇介绍了发表界面的界面和图片选择的功能实现,这篇主要写图片预览功能的实现。

老规矩,先上效果图:

图片预览界面

图像显示采用了开源的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);
                }
            });
        }
    }

至此,图片预览的功能就已经实现。结合前两篇博客,一个发表动态的功能就已经实现了。

总结

通过写三篇博客,加深自己对该功能的理解,同时在编写过程中也发现程序的一些问题,这也算一种意外收获吧。在写博客的时候,才知道自己的语言是多么的贫乏,很多时候要靠代码去展示,可惜的是我的代码并没有什么注释,主要是因为功能比较简单,自己觉得不需要注释,但这终究不是一个好习惯,希望以后能改正。

代码或者是语言有不准确的地方,希望大家指出,莫要误人子弟。

上一篇下一篇

猜你喜欢

热点阅读