仿微信,qq组合头像
2016-07-01 13:09
471 查看
参考原文:点击打开链接
从网上找了一些仿微信群聊头像demo,发现是studio编写的,我一直习惯用eclpise,所以参考着完成了eclipse版的,
这个界面是写在适配器里面嵌套的,用法和平时一样,
主要实现代码:
显示图片的适配器:
还要记得在value文件夹下attrs添加属性;
主类调用:
总结:
用适配器模式的方法给群聊头像加图片的方式是想可以在这里可以用不同方式来实现图片的加载方式,这里普及下适配器模式的知识,主要是把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作,优点是更好的复用性和扩展性,缺点则是过多使用会使系统零乱,不易整体把握。
Demo:http://download.csdn.net/detail/luckrr/9564775
参考:https://github.com/laobie/NineGridImageView
从网上找了一些仿微信群聊头像demo,发现是studio编写的,我一直习惯用eclpise,所以参考着完成了eclipse版的,
这个界面是写在适配器里面嵌套的,用法和平时一样,
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/rl_people" android:layout_width="match_parent" android:layout_height="@dimen/dialog_heght" android:background="@drawable/selector_rl_item" android:gravity="center_vertical" android:paddingBottom="5dp" android:paddingLeft="@dimen/pdingLeftRight" android:paddingTop="5dp" > <RelativeLayout android:id="@+id/rl_chat_icon" android:layout_width="wrap_content" android:layout_height="match_parent" > <com.jingxinlawyer.lawchat.buisness.contacts.headerimg.NineGridImageView android:id="@+id/iv_people_icon1" android:layout_width="70dp" android:layout_height="70dp" android:contentDescription="@string/description" android:scaleType="fitXY" android:src="@drawable/shap_iv_default_l" /> </RelativeLayout> <TextView android:id="@+id/tv_people_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignTop="@+id/rl_chat_icon" android:layout_marginLeft="5dp" android:layout_marginTop="5dp" android:layout_toRightOf="@+id/rl_chat_icon" android:ellipsize="end" android:singleLine="true" /> <TextView android:id="@+id/tv_people_member" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignBottom="@+id/rl_chat_icon" android:layout_marginBottom="5dp" android:layout_marginLeft="5dp" android:layout_toRightOf="@+id/rl_chat_icon" android:ellipsize="end" android:ems="20" android:singleLine="true" /> </RelativeLayout>
主要实现代码:
public class NineGridImageView<T> extends ViewGroup { private int mRowCount; // 行数 private int mColumnCount; // 列数 private int mMaxSize = 4; // 最大图片数 private int mGap; // 宫格间距 private int parentWidth;// 父组件宽 private int parentHeight;// 父组件高 private List<ImageView> mImageViewList = new ArrayList<ImageView>(); private List<T> mImgDataList; private NineGridImageViewAdapter<T> 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 { Logger.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<T> { 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; } }
还要记得在value文件夹下attrs添加属性;
<declare-styleable name="NineGridImageView"> <attr format="dimension" name="imgGap"/> </declare-styleable>
主类调用:
NineGridImageViewAdapter<String> mAdapter = new NineGridImageViewAdapter<String>() { @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);
总结:
用适配器模式的方法给群聊头像加图片的方式是想可以在这里可以用不同方式来实现图片的加载方式,这里普及下适配器模式的知识,主要是把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作,优点是更好的复用性和扩展性,缺点则是过多使用会使系统零乱,不易整体把握。
Demo:http://download.csdn.net/detail/luckrr/9564775
参考:https://github.com/laobie/NineGridImageView
相关文章推荐
- 开源中国 OsChina Android 客户端源码分析(5)摇一摇
- Android学习-手把手教学实现仿微信发带图片朋友圈的UI设计
- 仿微信小视频
- Android 仿微信群聊头像
- 仿微信popupwindow的实现方式
- android开发之仿微信输入框效果
- Android之附加图片—— 仿微信图片选择器
- 开源系列1---造个图片选择器
- 聊天
- Ynote源码涉及功能解剖 推荐
- 使用libjpeg进行图片压缩(哈夫曼算法,无损压缩)
- Android 右滑退出当前Activity
- swift-仿微信弹出菜单
- 调用系统相机录像,压缩保存到相册(附仿微信视频录制demo)
- android底部导航栏+viewPager+自定义view的简单实现
- Android二维码(仿微信,轻量Zxing)
- Android类似微信详细地址选择(高德地图)
- 分享一些iOS实用Demo源码
- 微信朋友圈短视频控件的实现, TextureView的基本使用。
- IOS 仿微信聊天界面