一百行代码实现微信朋友圈九宫格图片显示
前言
代码编写
先自定义一个View集成ViewGroup,编辑器会提示你实现OnLayout方法,实现之,这里我们动态的添加的话其实不用到OnLayout方法,自定义一个layoutChildrenView()用来为子view设定位置就行了,该方法的实现如下:
这代码里面在调用子view的layout方法的同时设定了本身ViewGroup的高度大小,因为NineGridView的高度是要根据子View的高度来确定的.
- private void layoutChildrenView(){
- int childrenCount = listData.size();
- int singleWidth = (totalWidth - gap * (3 - 1)) / 3;
- int singleHeight = singleWidth;
- //根据子view数量确定高度
- ViewGroup.LayoutParams params = getLayoutParams();
- params.height = singleHeight * rows + gap * (rows - 1);
- setLayoutParams(params);
- for (int i = 0; i < childrenCount; i++) {
- CustomImageView childrenView = (CustomImageView) getChildAt(i);
- childrenView.setImageUrl(((Image) listData.get(i)).getUrl());
- int[] position = findPosition(i);
- int left = (singleWidth + gap) * position[1];
- int top = (singleHeight + gap) * position[0];
- int right = left + singleWidth;
- int bottom = top + singleHeight;
- childrenView.layout(left, top, right, bottom);
- }
- }
复制代码
添加一个设置图片资源的接口,一般情况下我们都是用在listview来显示数据,而数据都是封装好的,这里提供一个Image封装类,接口和封装类代码如下:
- public void setImagesData(List<Image> lists) {
- if (lists == null || lists.isEmpty()) {
- return;
- }
- //初始化布局
- generateChildrenLayout(lists.size());
- //这里做一个重用view的处理
- if (listData == null) {
- int i = 0;
- while (i < lists.size()) {
- CustomImageView iv = generateImageView();
- addView(iv,generateDefaultLayoutParams());
- i++;
- }
- } else {
- int oldViewCount = listData.size();
- int newViewCount = lists.size();
- if (oldViewCount > newViewCount) {
- removeViews(newViewCount - 1, oldViewCount - newViewCount);
- } else if (oldViewCount < newViewCount) {
- for (int i = 0; i < newViewCount - oldViewCount; i++) {
- CustomImageView iv = generateImageView();
- addView(iv,generateDefaultLayoutParams());
- }
- }
- }
- listData = lists;
- layoutChildrenView();
- }
复制代码
Image封装类:
- public class Image {
- private String url;
- private int width;
- private int height;
- public Image(String url, int width, int height) {
- this.url = url;
- this.width = width;
- this.height = height;
- L.i(toString());
- }
- public String getUrl() {
- return url;
- }
- public void setUrl(String url) {
- this.url = url;
- }
- public int getWidth() {
- return width;
- }
- public void setWidth(int width) {
- this.width = width;
- }
- public int getHeight() {
- return height;
- }
- public void setHeight(int height) {
- this.height = height;
- }
- @Override
- public String toString() {
- return "image---->>url="+url+"width="+width+"height"+height;
- }
- }
复制代码
在添加数据的时候,我们要根据图片的个数来确定具体的布局情况,这个函数就是generateChildrenLayout(),实现如下:
- /**
- * 根据图片个数确定行列数量
- * 对应关系如下
- * num row column
- * 1 1 1
- * 2 1 2
- * 3 1 3
- * 4 2 2
- * 5 2 3
- * 6 2 3
- * 7 3 3
- * 8 3 3
- * 9 3 3
- *
- * @param length
- */
- private void generateChildrenLayout(int length) {
- if (length <= 3) {
- rows = 1;
- columns = length;
- } else if (length <= 6) {
- rows = 2;
- columns = 3;
- if (length == 4) {
- columns = 2;
- }
- } else {
- rows = 3;
- columns = 3;
- }
- }
复制代码
这些,就是NineGridLayout的核心代码了,是不是很简单,整个类的源码如下:
- package com.weixinninegridlayout;
- import android.content.Context;
- import android.graphics.Color;
- import android.graphics.drawable.ColorDrawable;
- import android.util.AttributeSet;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.ImageView;
- import java.util.List;
- /**
- * Created by Pan_ on 2015/2/2.
- */
- public class NineGridlayout extends ViewGroup {
- /**
- * 图片之间的间隔
- */
- private int gap = 5;
- private int columns;//
- private int rows;//
- private List listData;
- private int totalWidth;
- public NineGridlayout(Context context) {
- super(context);
- }
- public NineGridlayout(Context context, AttributeSet attrs) {
- super(context, attrs);
- ScreenTools screenTools=ScreenTools.instance(getContext());
- totalWidth=screenTools.getScreenWidth()-screenTools.dip2px(80);
- }
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- }
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- }
- private void layoutChildrenView(){
- int childrenCount = listData.size();
- int singleWidth = (totalWidth - gap * (3 - 1)) / 3;
- int singleHeight = singleWidth;
- //根据子view数量确定高度
- ViewGroup.LayoutParams params = getLayoutParams();
- params.height = singleHeight * rows + gap * (rows - 1);
- setLayoutParams(params);
- for (int i = 0; i < childrenCount; i++) {
- CustomImageView childrenView = (CustomImageView) getChildAt(i);
- childrenView.setImageUrl(((Image) listData.get(i)).getUrl());
- int[] position = findPosition(i);
- int left = (singleWidth + gap) * position[1];
- int top = (singleHeight + gap) * position[0];
- int right = left + singleWidth;
- int bottom = top + singleHeight;
- childrenView.layout(left, top, right, bottom);
- }
- }
- private int[] findPosition(int childNum) {
- int[] position = new int[2];
- for (int i = 0; i < rows; i++) {
- for (int j = 0; j < columns; j++) {
- if ((i * columns + j) == childNum) {
- position[0] = i;//行
- position[1] = j;//列
- break;
- }
- }
- }
- return position;
- }
- public int getGap() {
- return gap;
- }
- public void setGap(int gap) {
- this.gap = gap;
- }
- public void setImagesData(List<Image> lists) {
- if (lists == null || lists.isEmpty()) {
- return;
- }
- //初始化布局
- generateChildrenLayout(lists.size());
- //这里做一个重用view的处理
- if (listData == null) {
- int i = 0;
- while (i < lists.size()) {
- CustomImageView iv = generateImageView();
- addView(iv,generateDefaultLayoutParams());
- i++;
- }
- } else {
- int oldViewCount = listData.size();
- int newViewCount = lists.size();
- if (oldViewCount > newViewCount) {
- removeViews(newViewCount - 1, oldViewCount - newViewCount);
- } else if (oldViewCount < newViewCount) {
- for (int i = 0; i < newViewCount - oldViewCount; i++) {
- CustomImageView iv = generateImageView();
- addView(iv,generateDefaultLayoutParams());
- }
- }
- }
- listData = lists;
- layoutChildrenView();
- }
- /**
- * 根据图片个数确定行列数量
- * 对应关系如下
- * num row column
- * 1 1 1
- * 2 1 2
- * 3 1 3
- * 4 2 2
- * 5 2 3
- * 6 2 3
- * 7 3 3
- * 8 3 3
- * 9 3 3
- *
- * @param length
- */
- private void generateChildrenLayout(int length) {
- if (length <= 3) {
- rows = 1;
- columns = length;
- } else if (length <= 6) {
- rows = 2;
- columns = 3;
- if (length == 4) {
- columns = 2;
- }
- } else {
- rows = 3;
- columns = 3;
- }
- }
- private CustomImageView generateImageView() {
- CustomImageView iv = new CustomImageView(getContext());
- iv.setScaleType(ImageView.ScaleType.CENTER_CROP);
- iv.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- }
- });
- iv.setBackgroundColor(Color.parseColor("#f5f5f5"));
- return iv;
- }
- }
复制代码
因为微信那些图片在点击的时候是有一个灰色的蒙版的,实现起来其实很简单,我们这里在自定义一个imageview,叫做CustomImageView,复写onTouchEvent方法,在onKeyDown的时候添加一个colorfilter,然后再onKeyUp的时候clear掉,这样就实现了点击有灰色蒙版的效果,同时为了方便项目加载图片的解耦,我加载图片用了picasso这个开源库,这个开源库的地址为点击打开链接 ,具体的代码如下:
- package com.weixinninegridlayout;
- import android.content.Context;
- import android.graphics.Color;
- import android.graphics.PorterDuff;
- import android.graphics.drawable.ColorDrawable;
- import android.graphics.drawable.Drawable;
- import android.text.TextUtils;
- import android.util.AttributeSet;
- import android.view.MotionEvent;
- import android.widget.ImageView;
- import com.squareup.picasso.Picasso;
- /**
- * Created by Pan_ on 2015/2/2.
- */
- public class CustomImageView extends ImageView {
- private String url;
- private boolean isAttachedToWindow;
- public CustomImageView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
- public CustomImageView(Context context) {
- super(context);
- }
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- Drawable drawable=getDrawable();
- if(drawable!=null) {
- drawable.mutate().setColorFilter(Color.GRAY,
- PorterDuff.Mode.MULTIPLY);
- }
- break;
- case MotionEvent.ACTION_MOVE:
- break;
- case MotionEvent.ACTION_CANCEL:
- case MotionEvent.ACTION_UP:
- Drawable drawableUp=getDrawable();
- if(drawableUp!=null) {
- drawableUp.mutate().clearColorFilter();
- }
- break;
- }
- return super.onTouchEvent(event);
- }
- @Override
- public void onAttachedToWindow() {
- isAttachedToWindow = true;
- setImageUrl(url);
- super.onAttachedToWindow();
- }
- @Override
- public void onDetachedFromWindow() {
- Picasso.with(getContext()).cancelRequest(this);
- isAttachedToWindow = false;
- setImageBitmap(null);
- super.onDetachedFromWindow();
- }
- public void setImageUrl(String url) {
- if (!TextUtils.isEmpty(url)) {
- this.url = url;
- if (isAttachedToWindow) {
- Picasso.with(getContext()).load(url).placeholder(new ColorDrawable(Color.parseColor("#f5f5f5"))).into(this);
- }
- }
- }
- }
一百行代码实现微信朋友圈九宫格图片显示相关推荐
- Android 实现仿微信朋友圈九宫格图片+NineGridView+ImageWatcher(图片查看:1.预览,2.拖动,3.放大,4.左右滑动,5.长按保存到手机)的功能
一.测试 实现: 二.添加依赖包: implementation 'androidx.appcompat:appcompat:1.1.0'implementation 'androidx.recycl ...
- 30行代码实现微信朋友圈自动点赞
首先祝大家新年快乐,过年了,允许我水一篇博客.不知道大家都回老家了没,不过我是没有回去,晚上吃完年夜饭看到很多人发朋友圈,为了增进和大家的友谊,于是就想着给大家点个赞,无奈内容太多了,就搞个自动化脚本 ...
- 【Android 控件使用及源码解析】 GridView规则显示图片仿微信朋友圈发图片
今天闲下来想用心写一点东西,发现没什么可写的,就写一下最近项目上用到的一些东西吧.最近项目要求上传多图并且多图显示,而且要规则的显示,就像微信朋友圈的图片显示一样. 想了一下用GridView再适合不 ...
- android从九宫格全屏预览,仿微信朋友圈展示图片的九宫格图片展示控件,支持点击图片全屏预览大图...
AssNineGridView 仿微信朋友圈展示图片的九宫格图片展示控件,支持点击图片全屏预览大图(可自定义). 写在前面 这是一个九宫格控件,本来是很久之前就写好了,现在才开源出来,也是看了很多优秀 ...
- 世界那么大,我想去看看。Django仿制微信朋友圈九宫格相册(1)
前面文章里的Python和Django知识点很重要,但过于零散.我们学习最终的目的还是应用.我们今天就来看下如何利用Django仿制微信朋友圈的九宫格相册.本教程比较长,会分成2部分发布,欢迎持续关注 ...
- 微信朋友圈的图片上传,多图上传怎么去撸才合适?我们一起来实现吧!
微信朋友圈的图片上传,多图上传怎么去撸才合适?我们一起来实现吧! 图片上传是非常常见的功能,而多图上传在大多数应用中也是非常常见的,比如微信的朋友圈,微博的动态,都是有九宫格图片的,那这里肯定涉及了多 ...
- 一个仿微信朋友圈的图片查看框架 - PhotoViewer
PhotoViewer 该图片查看器是模仿微信朋友圈查看图片编写 allprojects {repositories {...maven { url 'https://jitpack.io' }}}复 ...
- 安卓开发仿微信图片拖拽_仿微信朋友圈发表图片拖拽和删除功能
原标题:仿微信朋友圈发表图片拖拽和删除功能 中国联通在香港公布了上市公司2017年中期业绩.2017年上半年,公司主要业绩指标持续向好,收入稳步回升,服务收入达到人民币1,241.1亿元,同比增长3. ...
- 朋友圈(类似微信朋友圈)的显示
我们都知道,朋友圈的图片显示基本是随机的(一张图片时一排显示一张,两张图片时一排显示两张,三张图片时显示三张,超过三张就换行显示),这在很多应用中都经常运用到.这是示例图片 以android stud ...
最新文章
- 当人工智能遇到神经科学,二者联手势不可挡!
- python中outside loop_Python: 'break' outside loop
- (转载)如斯场景 似曾相识
- 面试问:Kafka 为什么速度那么快?
- OPEN(SAP) UI5 扫盲
- Spring(2)bean注入--Set方法注入
- 委托、事件的个人理解
- 视觉工程师面试指南_选择正确视觉效果的终极指南
- centos7--shell脚本自动实现bond配置-第二版
- drools 7.x DSL领域语言入门
- ecshop修改后台登陆密码
- HTML+CSS淘宝 页眉导航栏以及Logo搜索框的实现
- kaldi中文语音识别
- 六大接口管理平台,总有一款适合你的!
- aspen压缩因子_Aspen物性参数中英文对照
- 智慧金融系统软件需求规格说明(IEEE 830 标准)最终版
- python之dict
- linux chown sh,chown命令示例
- JavaScript mongodb(数据库)简单值
- android常用控件实验报告,ui设计实验报告.doc
热门文章
- Stay Hungry,Stay Foolish的解读
- 高级架构师_Redis_第1章_缓存原理与设计
- 计算机windows7启动不了桌面,电脑开机进不了桌面,教您电脑开机进不了桌面怎么办...
- 第二章:IEEE2030.5官网相关资料介绍
- 破解分布式数据库全局死锁难题 GBase 8c引领数据库领域变革
- python识别汉字笔画_Python识别图片中的文字
- Bootstrap 组件:缩略图组件(thumbnail)
- 注册淘宝安装工要求 淘宝安装工怎么接活
- 【数据库原理】概念结构、逻辑结构设计案例
- 聚类dbi指数_聚类算法