Android仿微信图片浏览

1,558 阅读1分钟

「这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战

实现原理

自定义PopupWindow+RecyclerView+TouchImageView

PopupWindow与AlertDialog的区别

最关键的区别是AlertDialog不能指定显示位置,只能默认显示在屏幕最中间(当然也可以通过设置WindowManager参数来改变位置)。而PopupWindow是可以指定显示位置的,十分灵活。
要生成一个PopupWindow最基本的三个条件是一定要设置的:

View contentView,int width, int height ;

少任意一个就不可能弹出来

PictureBrowsing

PictureBrowsing的布局文件 view_image.xml

<?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"
    >

    <View
        android:id="@+id/bg"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#000"
        android:alpha="0"
        />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
    <TextView
        android:id="@+id/tv_savePicture"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:layout_alignParentStart="true"
        android:textColor="@color/white"
        android:layout_marginTop="26dp"
        android:layout_marginRight="16dp"
        android:paddingLeft="15dp"
        android:paddingRight="15dp"
        android:paddingTop="4dp"
        android:paddingBottom="4dp"
        android:text="保存图片"
        android:textSize="19dp"
        android:background="@drawable/bg_operator"
        />

    <ImageView
        android:id="@+id/cover"
        android:layout_width="0dp"
        android:layout_height="0dp"
        />
</FrameLayout>

重写PopupWindow里面放入一个横向的RecyclerView

完整代码比较简单,主要就是RecyclerView的使用

public class PictureBrowsing extends PopupWindow {

    private Context mContext;//上下文
    private View mParent;
    private View mBg;//背景图片
    private RecyclerView mRecyclerView;
    private ImageView mCover;//当前的图面
    
    private List<PictureBean> mList;
    private int mPosition;//当前的图面的位置
    private ActionListener mActionListener; //自定义点击接口

    private int recyclerViewCurrentPosition = -1; // RecyclerView当前前位置
    private TextView savePicture;//保存图片

  //构造函数
    public PictureBrowsing(Context context, View parent, List<PictureBean> bean) {
        mContext = context;
        mParent = parent;
        mList = new ArrayList<>();
        mList .addAll( bean);
        mPosition = 1;

        //设置布局
        setContentView(initView());
        //设置布局宽高
        setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
        setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
        //背景
        setBackgroundDrawable(new ColorDrawable());
        //点击外面销毁弹窗
        setOutsideTouchable(true);
        setClippingEnabled(false);
        setFocusable(true);
        //销毁事件监听
        setOnDismissListener(new OnDismissListener() {
            @Override
            public void onDismiss() {
                if (mActionListener != null) {
                    mActionListener.onImageDialogDismiss();
                }
                mActionListener = null;
                mRecyclerView = null;
            }
        });
    }

//初始化RecyclerView
    private View initView() {
        View v = LayoutInflater.from(mContext).inflate(R.layout.view_image, null);
        mBg = v.findViewById(R.id.bg);
        mRecyclerView = v.findViewById(R.id.recyclerView);
        mRecyclerView.setHasFixedSize(true);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false));
        mCover = v.findViewById(R.id.cover);
        //适配器
        PictureBrowsingAdapter adapter = new PictureBrowsingAdapter(mContext, mList);
        adapter.setActionListener(new PictureBrowsingAdapter.ActionListener() {
            @Override
            public void onImageClick() {
                dismiss();
            }
        });
        mRecyclerView.setAdapter(adapter);
        if (mPosition >= 0 && mPosition < mList.size()) {
            mRecyclerView.scrollToPosition(mPosition);
        }
        return v;
    }

    public int getRecyclerViewCurrentPosition() {
        return recyclerViewCurrentPosition;
    }

    public void show() {
       //PopupWindow弹出位置
        showAtLocation(mParent, Gravity.BOTTOM, 0, 0);
    }

    public void setActionListener(ActionListener actionListener) {
        mActionListener = actionListener;
    }
    //自定义点击接口
    public interface ActionListener {
        void onImageDialogDismiss();
    }

PictureBrowsingAdapter

public class PictureBrowsingAdapter extends RecyclerView.Adapter<PictureBrowsingAdapter.Vh> {

    private Context mContext;
    private List<PictureBean> mList;//简单封装的实体类
    private LayoutInflater mInflater;//布局填充器
    private View.OnClickListener mOnClickListener;//点击监听
    private ActionListener mActionListener;  //自定义点击接口
    
    //传参_list
    public PictureBrowsingAdapter(Context context, List<PictureBean> list) {
        mContext=context;
        mList = new ArrayList<>();
        mList.addAll( list);
        mInflater = LayoutInflater.from(context);
        //销毁弹窗的点击事件,模仿微信,点击图片返回聊天界面
        mOnClickListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(!ClickUtil.canClick()){
                    return;
                }
                if (mActionListener != null) {
                    mActionListener.onImageClick();
                }
            }
        };
    }

    @NonNull
    @Override
    public Vh onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new Vh(mInflater.inflate(R.layout.item_im_chat_img, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull Vh vh, int position) {
        vh.setData(mList.get(position).getPicture());
    }

    @Override
    public int getItemCount() {
        return mList.size();
    }


    @Override
    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
        PagerSnapHelper pagerSnapHelper = new PagerSnapHelper();
        pagerSnapHelper.attachToRecyclerView(recyclerView);
    }

    class Vh extends RecyclerView.ViewHolder {
   
       //初始化ImageView
        ImageView mImg;
        public Vh(View itemView) {
            super(itemView);

            mImg =itemView.findViewById(R.id.MyZoomImageView);
            mImg.setOnClickListener(mOnClickListener);

        }
        //设置图片
        void setData(Bitmap bean) {
            mImg.setImageBitmap(bean);
        }
    }

    public void setActionListener(ActionListener actionListener) {
        mActionListener = actionListener;
    }

    public interface ActionListener {
        void onImageClick();
    }
}

条目的布局就一个ImageView item_im_chat_img

<?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="#000"
     >
    <ImageView
        android:id="@+id/MyZoomImageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@mipmap/ic_3"
        />
</FrameLayout>

使用方法

PictureBrowsing mChatImageDialog = new PictureBrowsing(this, v,list);
mChatImageDialog.show();

效果图

ezgif.com-gif-maker (5).gif