本人最新公众号《Android百科全书》,汇集了各个公众号的优秀文章,进行分类整理,让大家能够更方便的查阅,希望大家多多支持,来个关注奥。

这个开源项目,之前就想写,一直没有时间整理,这次整理出来,方便以后使用,封装成了库,支持定制,废话不多说,先上图

这是微信的朋友圈发布选择器,一般大家都是用recyclerview或者gridview写一个出来,然后里面再做其他处理,当时我就想,我能不能把它封装成一个控件,然后以后就再也不用写了,得出的结论是能,于是开始封装,封装完成呢,效果图就是下面这个

动图太大上传不了了,那就放出github地址来

单纯的上传图片展示控件ImageShowPicker

这里的readme有动态图,大家可以看下。

废话不多说,大家先来看看怎么使用这个控件

 ImageShowPickerView  pickerView = (ImageShowPickerView)findViewById(R.id.it_picker_view);final List<ImageBean> list = getItem(position);pickerView.setImageLoaderInterface(new Loader());pickerView.setNewData(list);//展示有动画和无动画//设置监听pickerView.setPickerListener(new ImageShowPickerListener() {@Overridepublic void addOnClickListener(int remainNum) {Toast.makeText(context, "remainNum" + remainNum, Toast.LENGTH_SHORT).show();//在listview或recyclerview才会使用这个list.add(),其他情况都不用list.add(new ImageBean("http://pic78.huitu.com/res/20160604/1029007_20160604114552332126_1.jpg"));pickerView.addData(new ImageBean("http://pic78.huitu.com/res/20160604/1029007_20160604114552332126_1.jpg"));}@Overridepublic void picOnClickListener(List<ImageShowPickerBean> list, int position, int remainNum) {Toast.makeText(context, list.size() + "========" + position + "remainNum" + remainNum, Toast.LENGTH_SHORT).show();}@Overridepublic void delOnClickListener(int position, int remainNum) {list.remove(position);Toast.makeText(context, "delOnClickListenerremainNum" + remainNum, Toast.LENGTH_SHORT).show();}});//所有设置完毕后调用该方法pickerView.show();//获取所有数据pickerView.getDataList();

声明控件后做一些设置就使用这个控件了,是不是比之前的自己写recyclerview简单多了,再也不用一次次重写了,
这里就不做过多说明,更详细的使用方法,请大家移步github,欢迎star呀

下面,来为大家做一下介绍,看看我们的这个picker到底是怎么封装的,我是通过这几部来封装的

  • 1、分析需求,分析定制目标
  • 2、选择实现方法
  • 3、编写代码
  • 4、完善方法
    以上4步就是我这个项目的经历过程,下面一一介绍,并说明原理

1、分析需求,分析定制目标

我们要写的这个选择器,首先他要轻便,就是不抢其他人的工作,不去给开发者带来其他的局限性,so我们就不能
直接指定某个图片加载框架,者就是一个需求;其次,我们的选择器应该有多种定制选择,比如微信的选择器就没
有删除小按钮,但是其他的app里有,我们就要定制这一个属性,让用户来选择是否显示,还有recyclerview自
带的增加删除动画,有的app就想要,有的就不想要,so我们也要提供方法让使用者来定制。

2、选择实现方法

实现方法的选择是个问题,关于图片加载的实现方法,我参考了[banner]这个开源项目的接口处理,十分感谢该
项目给我的思路,他的地址如下https://github.com/youth5201314/banner,解决了这个问题,还有一个
问题困扰我,就是如何获取数据,开始我想用反射来进行操作,但是反射的性能不好,同时使用者混淆代码时,又
增添了很多麻烦,因为数据类的参数的不确定性,所以抛弃了这种处理方式,最后选择继承重写方法的这个思路来
实现。

3、编写代码

解决了上面两个问题,下面就可以开始写代码了,一点点来说

(1).为view 设置属性

这里一定要注意,自定义控件设置属性后一定要调用typedArray.recycle();这个方法,否则后果你可以试试,爽到飞起

  TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ImageShowPickerView);mPicSize = typedArray.getDimensionPixelSize(R.styleable.ImageShowPickerView_pic_size, SizeUtils.getSizeUtils().dp2px(getContext(), PIC_SIZE));isShowDel = typedArray.getBoolean(R.styleable.ImageShowPickerView_is_show_del, true);isShowAnim = typedArray.getBoolean(R.styleable.ImageShowPickerView_is_show_anim, false);mAddLabel = typedArray.getResourceId(R.styleable.ImageShowPickerView_add_label, R.mipmap.image_show_piceker_add);mDelLabel = typedArray.getResourceId(R.styleable.ImageShowPickerView_del_label, R.mipmap.image_show_piceker_del);oneLineShowNum = typedArray.getInt(R.styleable.ImageShowPickerView_one_line_show_num, ONE_LINE_SHOW_NUM);maxNum = typedArray.getInt(R.styleable.ImageShowPickerView_max_num, MAX_NUM);typedArray.recycle();

(2).添加数据时刷新,这里就包括动画的处理了

这只是其中一个方法,写到这里就是为了让大家了解一下,提供个思路

 /*** 添加新数据** @param bean* @param <T>*/public <T extends ImageShowPickerBean> void addData(T bean) {if (bean == null) {return;}this.list.add(bean);if (isShowAnim) {if (adapter != null) {adapter.notifyItemChanged(list.size() - 1);adapter.notifyItemChanged(list.size());}} else {adapter.notifyDataSetChanged();}}

(3).重头戏来了,也就是加载图片接口

我们定义这个接口,用来实现加载图片的自定义化,无论你用什么框架,就都可以兼容了,第一眼看,有的人可能没明白怎么处理,其实就是继承接口后重写这个方法,我们在view里只不过把这个方法当成已经写好的方法,调用了一下他的方法名,这样解释是不是就更清晰些,动手试试就懂了

/*** Author 姚智胜* Version V1.0版本* Description: 加载图片接口* Date: 2017/4/6*/
public interface ImageLoaderInterface<T extends View> extends Serializable {void displayImage(Context context, String path, T imageView);void displayImage(Context context, @DrawableRes Integer resId, T imageView);T createImageView(Context context);
}

(4).RecyclerView的holder处理

把这个放到这里,主要是为了给大家看下onclick事件应该写在哪里,如果写到onBindViewHolder这个方法里,那就是无限的重复创建了,没有理解Holder的作用,我们要在最开始就对他进行创建,然后去复用他

  //自定义的ViewHolder,持有每个Item的的所有界面元素public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {public View iv_pic;public ImageView iv_del;private ImageShowPickerPicListener picOnClickListener;public ViewHolder(View view, ImageLoaderInterface imageLoaderInterface, ImageShowPickerPicListener picOnClickListener) {super(view);this.picOnClickListener = picOnClickListener;iv_pic = imageLoaderInterface.createImageView(view.getContext());FrameLayout.LayoutParams pic_params = new FrameLayout.LayoutParams(iconHeight,iconHeight);pic_params.setMargins(10, 10, 10, 10);iv_pic.setLayoutParams(pic_params);iv_del = new ImageView(view.getContext());FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);layoutParams.gravity = Gravity.TOP | Gravity.END;iv_del.setPadding(5, 5, 5, 5);iv_del.setLayoutParams(layoutParams);iv_pic.setId(R.id.iv_image_show_picker_pic);iv_del.setId(R.id.iv_image_show_picker_del);iv_pic.setOnClickListener(this);iv_del.setOnClickListener(this);}@Overridepublic void onClick(View v) {int i = v.getId();if (i == R.id.iv_image_show_picker_pic) {picOnClickListener.onPicClickListener(getLayoutPosition());} else if (i == R.id.iv_image_show_picker_del) {picOnClickListener.onDelClickListener(getLayoutPosition());}}}

(5).意外发现recyclerview的bug

在代码里,我们在adapter内部使用了notifyItemChanged,程序却异常崩溃了,查阅过资料后,发现这个google的bug,所以重写了这个布局管理器,处理这个问题,算是意外收获

/*** Author 姚智胜* Version V1.0版本* Description: 处理recyclerview在adapter内调用notifyItemChanged崩溃的解决方法* Date: 2017/4/15*/public class MyGridLayoutManager extends GridLayoutManager {public MyGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);}public MyGridLayoutManager(Context context, int spanCount) {super(context, spanCount);}public MyGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {super(context, spanCount, orientation, reverseLayout);}@Overridepublic boolean supportsPredictiveItemAnimations() {return false;}@Overridepublic void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {//override this method and implement code as belowtry {super.onLayoutChildren(recycler, state);} catch (Exception e) {e.printStackTrace();}}
}

(6).数据类的父类

原理很简单,只是思路问题,我们继承这个父类后,只需重写两个方法,把我们数据类的url,为指定方法赋值就可以了,一个小思路,有可能不是最好的,希望有更好意见的来提下意见

/*** Author 姚智胜* Version V1.0版本* Description: 显示数据类的父类,必须继承于该类* Date: 2017/4/10*/public abstract class ImageShowPickerBean {public String getImageShowPickerUrl() {return setImageShowPickerUrl();}public int getImageShowPickerDelRes() {return setImageShowPickerDelRes();}/*** 为URL赋值,必须重写方法** @return*/public abstract String setImageShowPickerUrl();/*** 为删除label赋值,必须重写方法** @return*/public abstract int setImageShowPickerDelRes();}

4、完善方法

这里要做的其实就是小修小补,比如我们的封装的view ,在最后的时候我又增加了几个自定义属性,让他的可定制性更强,也是在这个步骤里对我们的封装进行最后一次的检查和完善。

以上就是我在写ImageShowPickerView的时候走的几个步骤,会有比我这个更加好的模式,分享出来,就是为了共同进步,和给自己写完一个项目的总结,继续努力,向资深程序员进发!!!

仿微信朋友圈9图上传选择器相关推荐

  1. 微信朋友圈的图片上传,多图上传怎么去撸才合适?我们一起来实现吧!

    微信朋友圈的图片上传,多图上传怎么去撸才合适?我们一起来实现吧! 图片上传是非常常见的功能,而多图上传在大多数应用中也是非常常见的,比如微信的朋友圈,微博的动态,都是有九宫格图片的,那这里肯定涉及了多 ...

  2. android com.mylhyl,Android 高仿微信朋友圈拍照上传功能

    模仿微信朋友圈发布动态,输入文字支持文字多少高度自增,有一个最小输入框高度,输入文字有限制,不过这些都很easy! 1. photopicker的使用 这是一个支持选择多张图片,点击图片放大,图片之间 ...

  3. android 微信高仿,Android 高仿微信朋友圈拍照上传功能

    模仿微信朋友圈发布动态,输入文字支持文字多少高度自增,有一个最小输入框高度,输入文字有限制,不过这些都很easy! 1. PhotoPicker的使用 这是一个支持选择多张图片,点击图片放大,图片之间 ...

  4. Android 仿微信朋友圈添加图片

    github地址(欢迎下载Demo) https://github.com/zhouxu88/WXCircleAddPic 老习惯,先上图,着急用的朋友,直接带走Demo,先拿来用吧,毕竟老板催的紧, ...

  5. 仿微信朋友圈【九宫格的实现】

    仿微信朋友圈[九宫格的实现] 标签: 九宫格自定义viewgroup 2017-04-18 18:39  561人阅读  评论(0)  收藏  举报   分类: Android(25)  版权声明:本 ...

  6. 安卓开发仿微信图片拖拽_仿微信朋友圈发表图片拖拽和删除功能

    原标题:仿微信朋友圈发表图片拖拽和删除功能 中国联通在香港公布了上市公司2017年中期业绩.2017年上半年,公司主要业绩指标持续向好,收入稳步回升,服务收入达到人民币1,241.1亿元,同比增长3. ...

  7. 混合开发之仿微信朋友圈

    转载于:Android 混合开发之仿微信朋友圈 - CSDN博客 https://blog.csdn.net/u013144863/article/details/53230786 开发之前 大约从去 ...

  8. Android仿微信朋友圈5实现朋友圈列表

    前言: 微信朋友圈网上有很多开源的例子,本文是自己手写,之前的几篇都是单个功能,感觉很零散,这次放出完整的点赞评论和朋友圈列表功能,大家有兴趣可以看一下 1.定义四种item类型,可以按后台接口自行定 ...

  9. android从九宫格全屏预览,仿微信朋友圈展示图片的九宫格图片展示控件,支持点击图片全屏预览大图...

    AssNineGridView 仿微信朋友圈展示图片的九宫格图片展示控件,支持点击图片全屏预览大图(可自定义). 写在前面 这是一个九宫格控件,本来是很久之前就写好了,现在才开源出来,也是看了很多优秀 ...

最新文章

  1. pythonprint end_python print end =''
  2. 【Python学习系列二十六】networkx库图最短路径求解
  3. NIPS 2016 | Best Paper, Dual Learning, Review Network, VQA 等论文选介
  4. Git之深入解析如何通过GPG签署和验证工作
  5. 杂牌手柄模拟xboxone手柄_手机就能玩Switch游戏,蛋蛋模拟器+盖世小鸡X2手柄体验...
  6. 一个基于vue和element-ui的树形穿梭框组件
  7. C++--第1课 - C到C++的升级
  8. php的敏感词过滤类库,敏感词过滤的php类库
  9. 马尔可夫链与隐马尔可夫模型
  10. android 触摸屏校准软件,触摸屏软件(eGalaxTouch)下载_触摸屏软件(eGalaxTouch)官方下载-太平洋下载中心...
  11. Cocoa设计模式(iOS常用设计模式) Cocoa Design Patterns
  12. 计算机NIC配置,在主计算机或 VM 上创建新的 NIC 团队
  13. ActiveMQ在win7下启动失败解决方案
  14. 文件丢失了怎么能复原
  15. ROM、RAM、DRAM、SRAM、FLASH区别
  16. 加工生产调度(Johnson算法 双机流水作业调度问题)
  17. 服务器 控制台 的作用是,电脑中的MMC控制台的作用和用法是什么?
  18. 2019经济寒冬,软件定制开发公司的竞争力在哪里??
  19. 《线性代数及其应用》阅读笔记:一 1.5 线性方程组的解集
  20. 【转载】C++的就业状况与方案。

热门文章

  1. 怎么用计算机弹出逆战,windows10系统运行逆战出现乱码如何修复
  2. vue vlc插件的使用
  3. 关于fgetc,getc,getchar和scanf的一些小知识
  4. vs局域网内远程调试
  5. c51汇编语言读写idata,汇编语言用[bx+idata]的方式进行数组的处理
  6. 拼多多商家版知识解答-企立方
  7. 小学机器人编程用什么语言
  8. JSON传输图片帮助类
  9. EWMA之——EWMA指数加权移动平均模型的Java实现
  10. 食养农品:没有场景配套的功能诉求是低效的