android微信群聊功能,Android仿微信群聊头像效果

在网上找了些仿微信群聊头像的开源库后,发现没特别好用的,或者说满足我需求的,就只好在别人的基础上改了下,也就有了这样的自定义控件了,以此来实现微信群聊头像的效果,效果图如下所示:

3875ec3675fcf48b0ff986c0456b87a1.png

主要实现:

一、自定义viewGroup,以此来实现主要的代码逻辑

public class NineGridImageView extends ViewGroup{

private int mRowCount; //行数

private int mColumnCount; //列数

private int mMaxSize = 9; //最大图片数

private int mGap; //宫格间距

private int parentWidth;//父组件宽

private int parentHeight;//父组件高

private List mImageViewList = new ArrayList<>();

private List mImgDataList;

private NineGridImageViewAdapter mAdapter;

public NineGridImageView(Context context) {

this(context,null);

}

public NineGridImageView(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public NineGridImageView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.NineGridImageView);

this.mGap = (int) typedArray.getDimension(R.styleable.NineGridImageView_imgGap, 8);

typedArray.recycle();

}

/**

* 设定宽高

*/

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

parentWidth = measureWidth(widthMeasureSpec);

parentHeight = measureHeight(heightMeasureSpec);

setMeasuredDimension(parentWidth,parentHeight);

}

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

layoutChildrenView();

}

/**

* 为子ImageView布局

*/

private void layoutChildrenView(){

if(mImgDataList == null){

return;

}

int childrenCount = mImgDataList.size();

for(int i = 0; i < childrenCount; i++){

ImageView childrenView = (ImageView)getChildAt(i);

if(mAdapter != null){

mAdapter.onDisplayImage(getContext(), childrenView, mImgDataList.get(i));

}

int rowNum = i / mColumnCount;//当前行数

int columnNum = i % mColumnCount;//当前列数

int mImageSize = (parentWidth-(mColumnCount+1)*mGap)/mColumnCount;//图片尺寸

int t_center = (parentHeight + mGap)/2;//中间位置以下的顶点(有宫格间距)

int b_center = (parentHeight - mGap)/2;//中间位置以上的底部(有宫格间距)

int l_center = (parentWidth + mGap)/2;//中间位置以右的左部(有宫格间距)

int r_center = (parentWidth - mGap)/2;//中间位置以左的右部(有宫格间距)

int center = (parentHeight - mImageSize)/2;//中间位置以上顶部(无宫格间距)

int left = mImageSize * columnNum + mGap * (columnNum + 1);

int top = mImageSize * rowNum + mGap * (rowNum + 1);

int right = left + mImageSize;

int bottom = top + mImageSize;

/**

* 不同子view情况下的不同显示

*/

if(childrenCount == 1){

childrenView.layout(left, top, right, bottom);

}else if(childrenCount == 2){

childrenView.layout(left, center, right, center + mImageSize);

}else if(childrenCount == 3){

if(i == 0){

childrenView.layout(center, top, center+mImageSize, bottom);

}else {

childrenView.layout(mGap * i +mImageSize * (i - 1), t_center, mGap * i +mImageSize * i, t_center+mImageSize);

}

}else if(childrenCount == 4){

childrenView.layout(left, top, right, bottom);

}else if(childrenCount == 5){

if(i == 0){

childrenView.layout(r_center - mImageSize, r_center - mImageSize, r_center, r_center);

}else if(i == 1){

childrenView.layout(l_center , r_center - mImageSize, l_center + mImageSize, r_center);

}else{

childrenView.layout(mGap * (i - 1) + mImageSize * (i - 2),t_center,mGap * (i - 1) + mImageSize * (i - 1),t_center+mImageSize);

}

}else if(childrenCount == 6){

if(i < 3) {

childrenView.layout(mGap * (i + 1) +mImageSize * i, b_center - mImageSize, mGap * (i + 1) + mImageSize * (i+1), b_center);

}else{

childrenView.layout(mGap * (i - 2) + mImageSize * (i - 3),t_center,mGap * (i - 2) + mImageSize * (i - 2),t_center+mImageSize);

}

}else if(childrenCount == 7){

if(i == 0){

childrenView.layout(center,mGap,center+mImageSize,mGap+mImageSize);

}else if(i > 0 && i < 4){

childrenView.layout(mGap * i +mImageSize * (i - 1),center,mGap * i +mImageSize * i,center+mImageSize);

}else{

childrenView.layout(mGap * (i - 3) + mImageSize * (i - 4),t_center+mImageSize/2,mGap * (i - 3) + mImageSize * (i - 3),t_center+mImageSize/2+mImageSize);

}

}else if(childrenCount == 8){

if(i == 0){

childrenView.layout(r_center - mImageSize,mGap,r_center,mGap+mImageSize);

}else if(i == 1){

childrenView.layout(l_center,mGap,l_center+mImageSize,mGap+mImageSize);

}else if(i > 1 && i < 5){

childrenView.layout(mGap * (i - 1) +mImageSize * (i - 2), center, mGap * (i - 1) +mImageSize * (i - 1), center+mImageSize);

}else{

childrenView.layout(mGap * (i - 4) + mImageSize * (i - 5), t_center+mImageSize/2, mGap * (i - 4) + mImageSize * (i - 4), t_center+mImageSize/2+mImageSize);

}

}else if(childrenCount == 9){

childrenView.layout(left, top, right, bottom);

}

}

}

/**

* 设置图片数据

*

* @param lists 图片数据集合

*/

public void setImagesData(List lists){

if(lists == null || lists.isEmpty()){

this.setVisibility(GONE);

return;

}else {

this.setVisibility(VISIBLE);

}

if(mMaxSize > 0 && lists.size() > mMaxSize){

lists = lists.subList(0, mMaxSize);

}

int[] gridParam = calculateGridParam(lists.size());

mRowCount = gridParam[0];

mColumnCount = gridParam[1];

if(mImgDataList == null){

int i = 0;

while (i < lists.size()){

ImageView iv = getImageView(i);

if(iv == null){

return;

}

addView(iv,generateDefaultLayoutParams());

i++;

}

}else {

int oldViewCount = mImgDataList.size();

int newViewCount = lists.size();

if(oldViewCount > newViewCount){

removeViews(newViewCount, oldViewCount - newViewCount);

}else if(oldViewCount < newViewCount){

for(int i = oldViewCount; i < newViewCount; i++){

ImageView iv = getImageView(i);

if(iv == null){

return;

}

addView(iv, generateDefaultLayoutParams());

}

}

}

mImgDataList = lists;

requestLayout();

}

/**

* 获得 ImageView

* 保证了 ImageView的重用

*

* @param position 位置

*/

private ImageView getImageView(final int position){

if(position < mImageViewList.size()){

return mImageViewList.get(position);

}else{

if(mAdapter != null){

ImageView imageView = mAdapter.generateImageView(getContext());

mImageViewList.add(imageView);

return imageView;

}else{

Log.e("NineGirdImageView", "Your must set a NineGridImageViewAdapter for NineGirdImageView");

return null;

}

}

}

/**

* 设置宫格参数

*

* @param imagesSize 图片数量

* @return 宫格参数 gridParam[0] 宫格行数 gridParam[1] 宫格列数

*/

protected static int[] calculateGridParam(int imagesSize){

int[] gridParam = new int[2];

if(imagesSize < 3){

gridParam[0] = 1;

gridParam[1] = imagesSize;

}else if(imagesSize <= 4){

gridParam[0] = 2;

gridParam[1] = 2;

}else{

gridParam[0] = imagesSize/3 + (imagesSize % 3 == 0?0:1);

gridParam[1] = 3;

}

return gridParam;

}

/**

* 设置适配器

*

* @param adapter 适配器

*/

public void setAdapter(NineGridImageViewAdapter adapter){

mAdapter = adapter;

}

/**

* 设置宫格间距

*

* @param gap 宫格间距 px

*/

public void setGap(int gap){

mGap = gap;

}

/**

* 对宫格的宽高进行重新定义

*/

private int measureWidth(int measureSpec){

int result = 0;

int specMode = MeasureSpec.getMode(measureSpec);

int specSize = MeasureSpec.getSize(measureSpec);

if(specMode == MeasureSpec.EXACTLY){

result = specSize;

}else{

result = 200;

if(specMode == MeasureSpec.AT_MOST){

result = Math.min(result,specSize);

}

}

return result;

}

private int measureHeight(int measureSpec){

int result = 0;

int specMode = MeasureSpec.getMode(measureSpec);

int specSize = MeasureSpec.getSize(measureSpec);

if(specMode == MeasureSpec.EXACTLY){

result = specSize;

}else{

result = 200;

if(specMode == MeasureSpec.AT_MOST){

result = Math.min(result,specSize);

}

}

return result;

}

}

二、你要显示你的网络图片所需要的代码

public abstract class NineGridImageViewAdapter {

protected abstract void onDisplayImage(Context context, ImageView imageView, T t);

protected ImageView generateImageView(Context context){

ImageView imageView = new ImageView(context);

imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);

return imageView;

}

//这里可以添加你所需要的事件之类的方法

}

对了,别忘了配置间隔属性,记得添加attrs.xml文件,加上如下代码

三、用法

NineGridImageViewAdapter mAdapter = new NineGridImageViewAdapter() {

@Override

protected void onDisplayImage(Context context, ImageView imageView, String s) {

Picasso.with(context).load(s).placeholder(R.mipmap.ic_holding).error(R.mipmap.ic_error).into(imageView);

}

@Override

protected ImageView generateImageView(Context context) {

return super.generateImageView(context);

}

};

groudIcon1.setAdapter(mAdapter);

groudIcon1.setImagesData(mPostList1);

四、总结

用适配器模式的方法给群聊头像加图片的方式是想可以在这里可以用不同方式来实现图片的加载方式,这里普及下适配器模式的知识,主要是把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作,优点是更好的复用性和扩展性,缺点则是过多使用会使系统零乱,不易整体把握。好像有点偏题了,这里就附上:GroupIconSample源码地址

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/42936.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android高仿微信UI点击头像显示大图片效果

用过微信的朋友朋友都见过微信中点击对方头像显示会加载大图&#xff0c;先贴两张图片说明下&#xff1a; 这种UI效果对用户的体验不错&#xff0c;今天突然有了灵感&#xff0c;试着去实现&#xff0c;结果就出来了。。 下面说说我的思路&#xff1a; 1.点击图片时跳转到另一…

Android高仿微信头像裁剪

最近公司的APP很多用户反应无法上传头像&#xff0c;于是打算修改原来头像裁剪的代码。参考微信、QQ、唱吧头像裁剪的操作&#xff0c;决定就仿微信头像裁剪来上传用户头像&#xff0c;在Android大神鸿洋的一篇高仿微信头像的博客(博客地址结尾会贴出来)的基础上加了一些代码&a…

Android仿微信群聊头像合成

最近碰见仿照微信头像的需求&#xff0c;提供多个url的组合头像&#xff0c;做成微信群聊一样的头像&#xff0c;网上查了下&#xff0c;有两类&#xff0c;一种是合成的&#xff0c;一种是多个view合并展示的&#xff0c;合成的做的感觉很简陋&#xff0c;不太满足需求&#x…

android 仿微信群聊头像 合成图片

android 仿微信群聊头像 合成图片&#xff0c;微信中可以显示出群头像为多个用户的头像网格&#xff0c;这里讲方法已经封装好&#xff0c; 如果有记得点赞哦&#xff01;&#xff01; 先看效果&#xff1a; 使用例子&#xff1a; Override public void onClick(View v) {P…

Android 仿QQ讨论组头像

一、效果图 二、实现 基本实现过程&#xff1a; 1.将原图片读取为bitmap 2.在Canvas画布上计算出图片位置&#xff0c;并绘制新的图片。 &#xff08;ps:计算位置对我来说是难点&#xff0c;花了好长时间&#xff09;&#xff1b; 三、源码 1.布局文件 <?xml version…

仿照微信或qq头像双击摇晃效果

1.资源文件anim下加入 cycles_anim.xml (插值器可以设置不同的插值器) <?xml version"1.0" encoding"utf-8"?> <cycleInterpolator xmlns:android"http://schemas.android.com/apk/res/android"android:cycles"2" />an…

Android之头像图片变圆形

一&#xff1a;效果图、 二&#xff1a;实现步骤、 1.自定义一个转换工具类、 package com.common.base.util;import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.BitmapShader; import an…

Android 高仿微信群聊头像

最近小编搞了一个仿微信群聊头像的一个功能&#xff0c;分享给大家...工作中需要实现仿钉钉群头像的一个功能&#xff0c;就是个人的头像拼到一起显示&#xff0c;看了一下市场上的APP好像微信的群聊头像是组合的&#xff0c;QQ的头像不是&#xff0c;别的好像也没有了。今天给…

QQ头像无法加载,显示初始默认头像的解决方法

前言 终于。。终于&#xff01;查过那么多资料&#xff0c;翻过无数带有蛛丝马迹的信息&#xff0c;根本没有人能解决我遇到的这个问题&#xff0c;它是如此独特&#xff0c;如此难以排查&#xff01;&#xff01; 删过文件、改过网络配置、本地测试过相关数据接口、重装过QQ、…

软考-数据库系统工程师

软考之数据库系统工程师 前言 怎么会突然想起来考这个呢&#xff1f;说实话很惭愧&#xff0c;大学四年&#xff0c;毕业两年多都不知道有这个证书&#xff0c;也是今天看朋友圈看到一个学妹晒出了自己的这个证书&#xff0c;也是软考但是不是数据库系统工程师&#xff0c;她…

数据库(SQL Sever)水平证书复习题

全国信息技术水平考试数据库应用系统设计技术水平证书&#xff08;SQL Server&#xff09;复习题 第一大题&#xff1a;单选题 数据库系统是数据库、硬件、软件和&#xff08; &#xff09;的集合体。 (A) DBMS (B) DBS © DB (D) DBA下列选项中&#xff0c;不属于数据模…

软考中级——数据库系统工程师

第十一章—事务管理 自己关于备考软考中级&#xff08;数据库系统工程师&#xff09;的一些知识点的补充文章目录 第十一章—事务管理1 事务的基本概念1.1事务定义语句1.2 事务的特性&#xff08;ACID&#xff09; 2 数据库的并发控制2.1事务调度2.2并发操作带来的问题2.3两段…

全国OSTA计算机高新技术SQLSever数据库四级证书--考证复习知识点集合(附下载地址)

全国OSTA计算机高新技术SQLSever四级证书 说明&#xff1a;没找到一样的图、但长就是长这样的。分享给即将考证的朋友们&#xff01;适合临场考试复习整理思路理顺&#xff01;有其他点问题欢迎提出&#xff01;谢谢&#xff01;祝逢考必过&#xff01;&#xff08;文末有文档下…

MSSQL SERVER DBA 2门证书考试

微软Microsoft 70-764 - Administering a SQL Database Infrastructure 和 70-765 - Provisioning SQL Databases考试心得 由于公司不涨工资&#xff0c;所以只能硬着头皮考个DBA证书增添个人色彩了。 微软的DBA需要2个考试&#xff0c;70-764和70-765. 由于疫情&#xff0c;所…

aspnet+sqlserver英语等级考试报名系统

考试报名数据处理系统的开发目的是使考试报名数据处理模式从手工记录转变成信息管理&#xff0c;为考试报名数据处理人员提供方便条件。对考试报名的实际情况进行调研之后&#xff0c;进行详细的需求分析&#xff0c;目 录 摘 要 I Abstract II 1 引言 1 1.1 项…

华为鸿蒙HarmonyOS 4定档8月;ChatGPT之父的加密货币正式上线;微软必应聊天将推出重新生成答案功能|极客头条

「极客头条」—— 技术人员的新闻圈&#xff01; CSDN 的读者朋友们早上好哇&#xff0c;「极客头条」来啦&#xff0c;快来看今天都有哪些值得我们技术人关注的重要新闻吧。 整理 | 梦依丹 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; 一分钟速览新闻点&…

注册Gmail邮箱

注册Gmail邮箱 文章目录 注册Gmail邮箱1. 安装谷歌浏览器2. 注册Gmail邮箱2.1 创建新账号2.2 填写信息2.3 设置邮箱地址2.4 不用填号码直接跳过&#xff01;2.5 同意隐私条款2.6 返回登录2.7 访问油管验证成功 1. 安装谷歌浏览器 vivo自带的应用商店 2. 注册Gmail邮箱 2.1 …

Email,电子邮箱免费注册流程

工欲善其事&#xff0c;必先利其器。要做好工作&#xff0c;先要有锋利的工具。日常办公也是一样&#xff0c;申请一个好用的电子邮箱很重要&#xff0c;同事客户之间发送个文件都可以通过电子邮箱进行&#xff0c;并且现在很多平台注册帐号都需要填写email&#xff0c;比如百度…

Petya勒索病毒

Petya勒索病毒 1、原理说明 2017年6月27日晚&#xff0c;印度、俄罗斯、西班牙以及欧洲多国遭受大规模Petya勒索病毒袭击&#xff0c;该病毒远程锁定设备&#xff0c;并索要赎金。其中乌克兰地区受灾害最为严重&#xff0c;政府、银行、电力系统、通讯系统、企业等都受到不同…