laobie / ninegridimageview Goto Github PK
View Code? Open in Web Editor NEWA custom widget for Android, which used for showing grid pictures.
Home Page: http://t.cn/RGH3uNF
License: Apache License 2.0
A custom widget for Android, which used for showing grid pictures.
Home Page: http://t.cn/RGH3uNF
License: Apache License 2.0
使用的时候,在三星note4手机,展示6张图片。其中有2张图片会重复加载,图片加载用imageloader。现象是,图片被加载出来就重新再次加载。发生的概率比较小。怀疑是图片展示的回调接口重复调用。
这是为什么?
如果图片地址错误,设置一个错误显示的位图,会导致onDisplayImage
不停重复调用。
把Demo中的加载图片的这段
Picasso.with(context).load(s).placeholder(R.drawable.ic_default_image).into(imageView);
改成
Picasso.with(context).load(s).error(R.drawable.ic_default_image).into(imageView);
再把图片地址换成一个错误的,就能复现了。
Picasso 和 Glide 都有这种问题。
水平有限不知道什么原因,还希望作者看看
现在有三张图片,显示成二行。能显示成一行吗?需要 怎样修改呢?
考虑当图片没有的时候,recyclerView会出现错乱,这个算是一个改进建议吧~作为ViewGroup,在bind的时候因为是动态添加子view的,首先调用removeAllViews或者判断一下list的size是否妥当写些?
int oldShowCount = getNeedShowCount(mImgDataList.size());
if (oldShowCount > newShowCount) {
removeViews(newShowCount, oldShowCount - newShowCount);
} else if (oldShowCount < newShowCount) {
for (int i = oldShowCount; i < newShowCount; i++) {
ImageView iv = getImageView(i);
if (iv == null) {
return;
}
addView(iv, generateDefaultLayoutParams());
}
}
这段代码不会执行,造成崩溃
protected void onItemImageClick(Context context, int index, List<String> list)
这里的list,目前是返回了显示在屏幕上的list,不应该是原始list吗
比如我的lis是12个元素,但是我默认只显示9个,点击之后才跳到新页面来显示所有的元素
或者说回调多一个参数呢,比如变成
protected void onItemImageClick(Context context, int index, List<String> list,List<String> initList)
这种情况只在外边包裹一层或多层view group时发生,on measure没有调用,但是父布局的是调用了的,只能forcelayout暂时解决。复现场景是,在demo中添加一个edittext位于recyclerview下边,activity修改为adjustresize,键盘弹起,窗口resize,奇数次,这时候该控件不会重新布局
'public open.setImagesData(list: Mutable)List<T!>!在com.jaeger.ninegridimageview.NineGridImageView中
一般控件的监听不应该是类似 listview.setOnItemClickListener()么,是通过控件来设置item监听的。这个库是放在adapter中的,为什么这么做呢?
是不是应该控件内List使用addAll形式添加
public class HealthAdapter extends BaseQuickAdapter<HealthInfo, BaseViewHolder> {
public HealthAdapter(@LayoutRes int layoutResId, @Nullable ArrayList<HealthInfo> data) {
super(layoutResId, data);
}
NineGridImageViewAdapter<String> mAdapter = new NineGridImageViewAdapter<String>() {
@Override
protected void onDisplayImage(Context context, ImageView imageView, String s) {
Glide.with(mContext)
.load(s)
.placeholder(R.mipmap.load_logo)
.error(R.mipmap.load_logo)
.dontAnimate()
.into(imageView);
}
@Override
protected ImageView generateImageView(Context context) {
return super.generateImageView(context);
}
@Override
protected void onItemImageClick(Context context, ImageView imageView, int index, List<String> list) {
}
};
@Override
protected void convert(BaseViewHolder helper, HealthInfo item) {
List<String> url=new ArrayList<>();
url.add("http://ac-QYgvX1CC.clouddn.com/ad99de83e1e3f7d4.jpg");
url.add("http://ac-QYgvX1CC.clouddn.com/ad99de83e1e3f7d4.jpg");
url.add("http://ac-QYgvX1CC.clouddn.com/ad99de83e1e3f7d4.jpg");
url.add("http://ac-QYgvX1CC.clouddn.com/ad99de83e1e3f7d4.jpg");
TextView tvTime=helper.getView(R.id.tv_time);
TextView tvKind=helper.getView(R.id.tv_kind);
TextView tvHospital=helper.getView(R.id.tv_hospital);
NineGridImageView<String> mNglContent =helper.getView(R.id.ngl_images);
mNglContent.setAdapter(mAdapter);
mNglContent.setImagesData(url);
String date=item.getPre_date().substring(0,10);
tvTime.setText(date);
tvKind.setText(item.getMedical_type().equals("0")?"11111":"22222");
tvHospital.setText("机构:"+item.getOrg_name());
}
您好:请问添加或者删除图片的时候怎么处理?
打了几行日志:
public void setImagesData(List lists) {
try {
if (lists == null || lists.isEmpty()) {
LogUtil.d(TAG, "setImagesData debug, New List = NULL");
this.setVisibility(GONE);
return;
} else {
LogUtil.d(TAG, "setImagesData debug, New List != NULL, Size = " + lists.size());
this.setVisibility(VISIBLE);
}
LogUtil.d(TAG, "setImagesData debug, Max Size = " + mMaxSize);
if (mMaxSize > 0 && lists.size() > mMaxSize) {
lists = lists.subList(0, mMaxSize);
}
LogUtil.d(TAG, "setImagesData debug, Show Style = " + mShowStyle);
int[] gridParam = calculateGridParam(lists.size(), mShowStyle);
mRowCount = gridParam[0];
mColumnCount = gridParam[1];
LogUtil.d(TAG, "setImagesData debug, Row Count = " + mRowCount);
LogUtil.d(TAG, "setImagesData debug, Column Count = " + mColumnCount);
if (mImgDataList == null) {
LogUtil.d(TAG, "setImagesData debug, Old List = NULL");
int i = 0;
while (i < lists.size()) {
GFImageView iv = getImageView(i);
if (iv == null) {
return;
}
addView(iv, generateDefaultLayoutParams());
i++;
}
} else {
LogUtil.d(TAG, "setImagesData debug, Old List != NULL");
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++) {
GFImageView iv = getImageView(i);
if (iv == null) {
return;
}
addView(iv, generateDefaultLayoutParams());
}
}
}
mImgDataList = lists;
requestLayout();
} catch (Exception e) {
LogUtil.e(TAG, "setImagesData error", e);
}
}
日志输出如下:
04-18 20:56:51.837 19831-19831/NineGridImageView: setImagesData debug, New List != NULL, Size = 6
04-18 20:56:51.837 19831-19831/NineGridImageView: setImagesData debug, Max Size = 9
04-18 20:56:51.837 19831-19831/NineGridImageView: setImagesData debug, Show Style = 1
04-18 20:56:51.837 19831-19831/NineGridImageView: setImagesData debug, Row Count = 2
04-18 20:56:51.837 19831-19831/NineGridImageView: setImagesData debug, Column Count = 3
04-18 20:56:51.837 19831-19831/NineGridImageView: setImagesData debug, Old List != NULL
04-18 20:56:51.838 19831-19831/NineGridImageView: setImagesData error
java.lang.IllegalStateException: **The specified child already has a parent. You must call removeView() on the child's parent first.**
at android.view.ViewGroup.addViewInner(ViewGroup.java:4315)
at android.view.ViewGroup.addView(ViewGroup.java:4151)
at android.view.ViewGroup.addView(ViewGroup.java:4123)
at com.way.heard.ui.views.NineGridImageView.setImagesData(NineGridImageView.java:155)
at com.way.heard.ui.activities.WritingActivity$7.onHanlderSuccess(WritingActivity.java:286)
at cn.finalteam.galleryfinal.PhotoBaseActivity.resultData(PhotoBaseActivity.java:186)
at cn.finalteam.galleryfinal.PhotoSelectActivity.onClick(PhotoSelectActivity.java:390)
at android.view.View.performClick(View.java:5226)
at android.view.View$PerformClick.run(View.java:21265)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:168)
at android.app.ActivityThread.main(ActivityThread.java:5845)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)
等我解决了过来Comment一下。
来了,mImgDataList的值会莫名其妙的丢失,导致
mImgDataList.size() = 0;
好在博主方法里也没用到mImgDataList里的数据,只用到了size(),用一个静态变量保存一下**size()**的值即可。
能否不限制图片上限,我在NineGridImageView中把下面的注释了就好了,因为如果做一个时间轴的demo,不能保证每一个item最多9张图,或者超过了9张提供接口控制。
if (lists.size() > 9) {
lists = lists.subList(0, 9);
}
另外图片的点击背景效果最好可以提供接口修改。
1.单张图片希望支持自定义宽高,或者宽高比;
单张图片希望可以支持自定义的宽高,而不是固定的正方形
2.九宫格支持自定义布局
现在只能添加一个Imageview,但是我的需求是在图片上有其他的icon,用于点击购买
在使用的过程中,看到日志中不停的打印出requestLayout,我想问一下这样产生的原因是什么,对性能会不会有很大的影响?
一直显示占位图,退出再进去才正常显示。弱弱的问下,这个项目作者还更新么。看到好多问题都很久了。。。 (ಥ﹏ಥ)
需要做点击图片查看详情的时候,有个放大缩小的功能,那就要获取到当前的ImageView,onItemImageClick能返回这个View吗
您好,看了项目代码,好像没有动态删除功能,这个可否加上?
我把picasso替换为fresco之后,listview在滚动的时候出现明显卡顿,暂时还没有找到原因
onItemImageClick 这个方法中,最好是能再多传一个View参数出来,这样自定义性更高,可以让开发者自己去实现转场动画
NineGridImageNewView.java.zip
我加了两个方法,加上了7张图 和8张图 显示图片的效果
@OverRide
protected void onLayout(boolean changed, int l, int t, int r, int b) {
Log.i("loadSquareSmallWallpaperData", "changed=" + changed + ",isonDetachedFromWindow=" + isDetachedFromWindow);
if (changed || isReDraw) {
isReDraw = false;
layoutChildrenView();
}
}
boolean isDetachedFromWindow = false;
boolean isReDraw = false;
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
isDetachedFromWindow = true;
Log.i("loadSquareSmallWallpaperData", "onDetachedFromWindow");
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (isDetachedFromWindow) {
isDetachedFromWindow = false;
isReDraw = true;
}
Log.i("loadSquareSmallWallpaperData", "onAttachedToWindow");
}
Glide不是会自带一个crossfade效果吗...
用了NineGridImageView 就没有这个效果了...
不知道有人碰到过类似的问题吗...@laobie 能帮忙解决一下吗 谢谢~
你的日志怎么关闭了,一直在打印
在RecyclerView中重新setImagesData后图片闪烁
// Picasso.with(context)
// .load(o.getUrl())
// .placeholder(R.mipmap.default_no_order)
// .into(imageView);
GlideApp.with(context)
.load(o.getUrl())
.transition(new DrawableTransitionOptions().dontTransition())
.apply(getRequestOptions())
.into(imageView);
singleImgSize的大小最好有个判断
当xml中定义的大小超过屏幕尺寸的时候,用屏幕尺寸大小
不然的话xml中定义非常大的时候,显示是不合理的
Сделайте что бы когда картинка одна, то она была по центру и большая
有九张图片的时候一直报这个错误
首先还是感谢作者提供的开源项目!因为我的图片需要实现的图片不是正方形,而作者的图片都是正方形的。所以,修改了一下,支持可以使用宽高比例图片。大家如果有同样的需求,可以按照这样的方式处理。。也期待作者下个版本上能支持吧!
直接看代码修改吧
` private int[] mGridSize = new int[2]; // 宫格大小,即图片大小,表示宽高值
private float mRatio = 1.0f; //图片宽高比例,默认1:1.为正方形
@OverRide
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
......
if (mImgDataList.size() == 1 && mSingleImgSize != -1) {
mGridSize[0] = mSingleImgSize > totalWidth ? totalWidth : mSingleImgSize;
mGridSize[1] = calculateRatio(mGridSize[0]);
} else {
mImageViewList.get(0).setScaleType(ImageView.ScaleType.CENTER_CROP);
mGridSize[0] = (totalWidth - mGap * (mColumnCount - 1)) / mColumnCount;
mGridSize[1] = calculateRatio(mGridSize[0]);
}
.......
}
/**
根据比例,通过宽的值,计算高
**/
private int calculateRatio(int width) {
return (int) (width * mRatio);
}
/***
设置宽高比例,如宽高3/4。则传入0.75f即可
*/
public void setImageSizeRatio(float ratio) {
this.mRatio = ratio;
}
//然后修改每一个用到宽高的地方代码,如下:
private void layoutForNoSpanChildrenView(int childrenCount) {
if (childrenCount <= 0) return;
int row, column, left, top, right, bottom;
for (int i = 0; i < childrenCount; i++) {
ImageView childrenView = (ImageView) getChildAt(i);
row = i / mColumnCount;
column = i % mColumnCount;
left = (mGridSize[0] + mGap) * column + getPaddingLeft();//用到宽的地方值
top = (mGridSize[1] + mGap) * row + getPaddingTop();//用到高的地方值
right = left + mGridSize[0];//用到宽的地方值
bottom = top + mGridSize[1];//用到高的地方值
childrenView.layout(left, top, right, bottom);
if (mAdapter != null) {
mAdapter.onDisplayImage(getContext(), childrenView, mImgDataList.get(i));
}
}
}
`
说明:源码中是以前是用mGridSize表示图片宽和高的,现在宽高不一样,用一个数组表示。即可。。
目前已经在源码上修改实现了功能。期待作者下版本能加上此功能。。
开源是伟大的。。希望大家都能贡献一点力量。。。
Glide最新的4.0 apply(baseOptions)后很多图片不能加载出来,不设置则没有问题,具体代码如下。
public class PostViewHolder extends RecyclerView.ViewHolder {
private NineGridImageView mNglContent;
private TextView mTvContent;
private RequestOptions baseOptions;
private NineGridImageViewAdapter<String> mAdapter = new NineGridImageViewAdapter<String>() {
@Override
protected void onDisplayImage(Context context, ImageView imageView, String s) {
Glide.with(context).load(s).apply(baseOptions).into(imageView);
// Picasso.with(context).load(s).placeholder(R.drawable.ic_default_image).into(imageView);
}
@Override
protected ImageView generateImageView(Context context) {
return super.generateImageView(context);
}
@Override
protected void onItemImageClick(Context context, ImageView imageView, int index, List<String> list) {
Toast.makeText(context, "image position is " + index, Toast.LENGTH_SHORT).show();
}
};
public PostViewHolder(View itemView) {
super(itemView);
baseOptions = new RequestOptions()
.dontAnimate()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.centerCrop()
.circleCrop()
.placeholder(R.drawable.ic_default_image)
.error(R.drawable.ic_default_image);
mTvContent = (TextView) itemView.findViewById(R.id.tv_content);
mNglContent = (NineGridImageView<String>) itemView.findViewById(R.id.ngl_images);
mNglContent.setAdapter(mAdapter);
mNglContent.setItemImageClickListener(new ItemImageClickListener<String>() {
@Override
public void onItemImageClick(Context context, ImageView imageView, int index, List<String> list) {
Log.d("onItemImageClick", list.get(index));
}
});
}
public void bind(Post post) {
mNglContent.setImagesData(post.getImgUrlList(), post.getmSpanType());
mTvContent.setText(post.getContent());
Log.d("jaeger", "九宫格高度: " + mNglContent.getMeasuredHeight());
Log.d("jaeger", "item 高度: " + itemView.getMeasuredHeight());
}
}
一行能不能显示4张图?怎么修改
NineGridImageView类中setImagesData(List lists)方法中mImgDataList = lists;这样导致mImgDataList 与传入的参数的内存地址一致,会使oldShowCount与newShowCount的判断永远相等,使第二次调用setImagesData(List lists)报错崩溃。
应该将mImgDataList = lists;修改为mImgDataList = new ArrayList<>(lists);,这样保证了原本作者的意图。
在recyclerView 为 23.2.0的 情况下,显示的高度不正确
希望迁移到maven,jcenter已跑路
请问能设置成圆角图片吗?我用glide设置圆角没反应
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.