首页 > 其他分享 >Android仿微信图片浏览

Android仿微信图片浏览

时间:2023-06-22 10:34:43浏览次数:43  
标签:浏览 void private mList new Android 仿微信 public View


实现原理

自定义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();

作者:九狼

标签:浏览,void,private,mList,new,Android,仿微信,public,View
From: https://blog.51cto.com/u_16163453/6534318

相关文章

  • Android 的下一个风口在哪里 ? 车载、智能家具、音视频。。。
    现在客户端卷的风起云涌,很多安卓开发者都是抱怨连天。内卷之下,相比本来就堪忧的发量,前途未卜的迷茫带来的精神折磨更是雪上加霜。在突破内卷这件事儿上,很多开发者都把目光对准了车企:智能座舱、车载系统,看起来都是不错的方向。那么我们来看一看,想要成功转型,最需要具备的素质是什么:想......
  • 以阿里社招Android面试为例,详讲面对面试官到面试中到面试结束
    前言今天有个小伙伴和我说,Android技术还行,主要是对面试没什么把握,小编想了想,不该是多半面试题都会迎难而解,怎么会什么把握呢?但仔细又一想,技术和面试也是两回事,技术可以也不代表面试就可以过,那咱们就来好好叨叨该如何去面试面对面试官我在网上看到了很多面试官的分享,他们面过上百人,......
  • 写给女*友的中级Android面试秘籍(含详细答案,15k级别)
    前言本篇文章,献给我家女朋友,祝她在杭州找一个965的好公司!因为Android面试考点众多,而网上各个知识点的博客文章又太多,看的眼花缭乱……所以便整理了一下常见考点的精华回答,尽量覆盖该知识点的下容易被面试到的所有内容。面试题都整理成了PDF文档,包含Java基础、Android基础、UI控件篇......
  • 为什么Android面试总是被问到性能优化问题?
    随着Android开发越来越规范,国内工程师的素质,以及用户对产品的要求也越来越高。这也间接导致我们对研发项目的质量要求到了近乎苛刻的地步,内存优化、UI卡顿优化、App崩溃监控等性能调优也逐渐成了人手必备的技能。工作之余,难免让我们感慨学无止境,以及Android开发也是水深不......
  • Android面试题:Handler、Binder、AMS、WMS面试必问题(带答案,万字总结,精心打磨,快收藏)
    前言业内一直有一个说法:技术好的未必底层够硬,但底层扎实的学起来进步如飞。这也是为什么如今的大厂都非常注重对底层原理的考察:除了可以看出面试者的即战力,底层原理更能看出一个开发者的发展潜力。大家对此应该也深有感受,在面试的过程中,底层原理是无论如何都躲不过去的一关。最典型......
  • 牛掰,阿里P7程序员花了半个月,编成这份1880页的《Android百大框架源码解析》,快来收藏
    为什么要深入了解源码?只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是浮于表象,这对我们的知识体系的建立和完备以及实战技术的提升都是不利的。真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读Android系统源码,还包括各种优秀的开源库。一方面,这些作品都......
  • Android | Activity 启动流程分析
    前言Activity类是android应用的关键组件,在日常开发中,绝对少不了组件。既然用了这么久,你知道他的启动流程......
  • 心酸,30岁深漂失业3个月,从巅峰跌落谷底,大龄Android开发必须要懂的事
    2022年3月,我的前同事,在我们群里说他准备回老家了,问我们有没有人可以暂时收养他的猫。——他说,这周末就要离开深圳了。他失业了、3个多月没收入,还要交着房租,过年来之后因为疫情找不到合适的工作。不过他还算乐观,说刚好可以回家陪陪父母…30多岁的他,来深圳7,8年了,工作一直不愠不火,间......
  • 浏览器插件管理工具 auto-extension-manager
    背景最初的需求是,能够根据当前TAB的URL,自动打开或者关闭某些浏览器插件。找到了一个扩展管理工具(本身也是个扩展),有类似的功能,但却失效了,而且作者看起来没有再维护了。所以,就自己写了一个。插件JasonGrass/auto-extension-manager:achromeextensionmanagerwhereyouca......
  • Android Kotlin Retrofit MVP网络请求封装(四)
    依赖implementation'com.squareup.retrofit2:retrofit:2.9.0'implementation'com.google.code.gson:gson:2.8.8'implementation'com.squareup.okhttp3:okhttp:4.9.1'implementation'com.squareup.retrofit2:retrof......