微信朋友圈的实现(图片查看,手势放大、缩小)

效果图:
这里写图片描述
简单的就这样,实现效果的方法有多种,可以使用ListView嵌套GridView,也可以直接使用RecycleView,这里只说RecycleView的实现方法。
难一点的地方就是每个item添加图片,这里使用的是自定义LinearLayout,LinearLayout里面主要做图片点击处理,设置图片布局,行数列数的排列。代码不多,直接贴代码了:


public class MultiImageView extends LinearLayout {
    public static int MAX_WIDTH = 0;

    // 照片的Url列表
    private List<String> imagesList;

    /**
     * 长度 单位为Pixel
     **/
    private int pxOneWidth = DensityUtil.dip2px(getContext(), 200); // 单张图时候的宽
    private int pxOneHeight = DensityUtil.dip2px(getContext(), 150); // 单张图时候的高
    private int pxMoreWandH = 0; // 多张图的宽高
    private int pxImagePadding = DensityUtil.dip2px(getContext(), 2);// 图片间的间距

    private int MAX_PER_ROW_COUNT = 3;// 每行显示最大数

    private LayoutParams onePicPara;
    private LayoutParams morePara;
    private LayoutParams rowPara;

    private OnItemClickListener mOnItemClickListener;

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        mOnItemClickListener = onItemClickListener;
    }

    public MultiImageView(Context context) {
        super(context);

    }

    public MultiImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setList(List<String> lists) throws IllegalArgumentException {
        if (lists == null) {
            throw new IllegalArgumentException("imageList is null...");
        }
        imagesList = lists;

        if (MAX_WIDTH > 0) {
            pxMoreWandH = MAX_WIDTH / 3 - pxImagePadding;
            // pxOneWidth = MAX_WIDTH / 2;
            // pxOneHeight = MAX_WIDTH * 2 / 3;
            initImageLayoutParams();
        }
        initView();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (MAX_WIDTH == 0) {
            int width = measureWidth(widthMeasureSpec);
            if (width > 0) {
                MAX_WIDTH = width;
                if (imagesList != null && imagesList.size() > 0) {
                    setList(imagesList);
                }
            }
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    /**
     * @param measureSpec
     * @return 返回View的宽度
     */
    private int measureWidth(int measureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if (specMode == MeasureSpec.EXACTLY) {
            // We were told how big to be
            result = specSize;
        } else {
            // Measure the text
            // result = (int) mTextPaint.measureText(mText) + getPaddingLeft()
            // + getPaddingRight();
            if (specMode == MeasureSpec.AT_MOST) {
                // Respect AT_MOST value if that was what is called for by
                // measureSpec
                result = Math.min(result, specSize);
            }
        }
        return result;
    }

    private void initImageLayoutParams() {

        onePicPara = new LayoutParams(pxOneWidth, pxOneHeight);

        morePara = new LayoutParams(pxMoreWandH, pxMoreWandH);
        morePara.setMargins(0, 0, pxImagePadding, 0);

        int wrap = LayoutParams.WRAP_CONTENT;
        int match = LayoutParams.MATCH_PARENT;
        rowPara = new LayoutParams(match, wrap);
        rowPara.setMargins(0, 0, 0, pxImagePadding);
    }

    // 根据imageView的数量初始化不同的View布局,还要为每一个View作点击效果
    private void initView() {
        this.setOrientation(VERTICAL);
        this.removeAllViews();
        if (MAX_WIDTH == 0) {
            // 为了触发onMeasure()来测量MultiImageView的最大宽度,MultiImageView的宽设置为match_parent
            addView(new View(getContext()));
            return;
        }

        if (imagesList == null || imagesList.size() == 0) {
            return;
        }

        if (imagesList.size() == 1) {
            for (final String url : imagesList) {
                final ImageView imageView = new ImageView(getContext());
                imageView.setId(url.hashCode()); // 指定id
                imageView.setLayoutParams(onePicPara);
                imageView.setMinimumWidth(pxMoreWandH);
                imageView.setScaleType(ScaleType.CENTER_CROP);

                Glide.with(getContext()).load(url).into(imageView);

                imageView.setOnClickListener(mImageViewOnClickListener);
                addView(imageView);
            }

        } else {
            int allCount = imagesList.size();
            if (allCount == 4) {
                MAX_PER_ROW_COUNT = 2;
            } else {
                MAX_PER_ROW_COUNT = 3;
            }
            int rowCount = allCount / MAX_PER_ROW_COUNT + (allCount % MAX_PER_ROW_COUNT > 0 ? 1 : 0);// 行数
            for (int rowCursor = 0; rowCursor < rowCount; rowCursor++) {
                LinearLayout rowLayout = new LinearLayout(getContext());
                rowLayout.setOrientation(LinearLayout.HORIZONTAL);

                rowLayout.setLayoutParams(rowPara);
                if (rowCursor == 0) {
                    rowLayout.setPadding(0, pxImagePadding, 0, 0);
                }

                int columnCount = allCount % MAX_PER_ROW_COUNT == 0 ? MAX_PER_ROW_COUNT : allCount % MAX_PER_ROW_COUNT;// 每行的列数
                if (rowCursor != rowCount - 1) {
                    columnCount = MAX_PER_ROW_COUNT;
                }
                addView(rowLayout);

                int rowOffset = rowCursor * MAX_PER_ROW_COUNT;// 行偏移
                for (int columnCursor = 0; columnCursor < columnCount; columnCursor++) {
                    int position = columnCursor + rowOffset;
                    String thumbUrl = imagesList.get(position);

                    final ImageView imageView = new ImageView(getContext());
                    imageView.setId(thumbUrl.hashCode());// 指定id
                    imageView.setLayoutParams(morePara);
                    imageView.setScaleType(ScaleType.CENTER_CROP);
                    imageView.setTag(R.string.app_name, position);
                    Glide.with(getContext()).load(thumbUrl).into(imageView);

                    imageView.setOnClickListener(mImageViewOnClickListener);
                    rowLayout.addView(imageView);
                }
            }
        }
    }

    // 图片点击事件
    private View.OnClickListener mImageViewOnClickListener = new OnClickListener() {

        @Override
        public void onClick(View view) {
            if (mOnItemClickListener != null) {
                mOnItemClickListener.onItemClick(view, view.getTag() + "");
            }
        }
    };

    public interface OnItemClickListener {
        void onItemClick(View view, String position);
    }

}

在activity里面绑定适配器之后,还需要实现图片点击查看,这也不难,我们在定义的时候顺便也定义了图片点击的接口了,直接调用就行了:

   viewHolder.gridView.setOnItemClickListener(new MultiImageView.OnItemClickListener() {
                @Override
                public void onItemClick(View view, String position) {
                    addPic(itemModle);
                    Intent intent = new Intent(mContext, GalleryActivity.class);
                    intent.putStringArrayListExtra("imagePath", images);
                    intent.putExtra("position", position);
                    mContext.startActivity(intent);
                }
            });

然后来看看图片查看类,先上效果图:
这里写图片描述

点击放大、缩小直接使用PhotoView来实现,左右滑动使用ViewPager,这里注意一下,Viewpager与PhotoView一起使用的时候,重写一下ViewPager,

/**
 * photoView 和Viewpager 套用,必须重写,避免异常崩溃
 *
 * Created by hedong on 2016/7/1.
 */
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 (IllegalArgumentException ex) {
            ex.printStackTrace();
        }
        return false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        try {
            return super.onInterceptTouchEvent(ev);
        } catch (IllegalArgumentException ex) {
            ex.printStackTrace();
        }
        return false;
    }

}

再点击图片跳转时,我们会把图片路径添加到集合传过来,然后再次加载显示。

 class SamplePagerAdapter extends PagerAdapter {

        @Override
        public int getCount() {
            return imagePath.size();
        }

        @Override
        public View instantiateItem(ViewGroup container, int position) {
            final PhotoView photoView = new PhotoView(container.getContext());
            Glide.with(container.getContext()).load(imagePath.get(position)).into(photoView);
            //给view做标记
            photoView.setId(position);

            //单击退出
            photoView.setOnViewTapListener(new PhotoViewAttacher.OnViewTapListener() {
                @Override
                public void onViewTap(View view, float x, float y) {
                    GalleryActivity.this.finish();
                }
            });

            container.addView(photoView, ViewPager.LayoutParams.MATCH_PARENT,
                    ViewPager.LayoutParams.MATCH_PARENT);

            return photoView;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

    }

其他的没多少难度,后面直接附源码。
源码:https://github.com/hedongBlog/WXFriend

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值