Comments (5)
我项目里面也遇到类似的,我是recyclerview嵌套了recyclerview,其中嵌套的那层RecyclerView用于显示微博图片,与你的情况应该很类似。我给你以下解决方案,应该能很好的解决这个问题
- 根据内容预先计算好GridView的高度,然后给GridView设置固定的高度,这样ListView在快速滑动的时候就不需要再去动态的计算高度了
//获取gridview的宽高参数
mParams = (LinearLayout.LayoutParams) ViewHolder.gridview.getLayoutParams();
/根据数据集mImageDatas的数量,计算展示这些数据集需要多少行,然后再乘以单个item的布局高度,得到总的gridview高度
mParams.height = (DensityUtil.dp2px(mContext, 110f)) * getImgLineCount(mImageDatas) +
(DensityUtil.dp2px(mContext, 5f)) * getImgLineCount(mImageDatas);
//同上,根据数据集的内容,来计算一共需要多少列,如果是定值直接写常量即可,再乘以单个item的布局宽度,得到总的gridview的宽度
mParams.width = (DensityUtil.dp2px(mContext, 110f)) * 3 + (DensityUtil.dp2px(mContext, 5f)) * 2;
//设定参数
ViewHolder.gridview.setLayoutParams(mParams);
- 监听外层的ListView的滑动操作,在停止滑动的时候,才去加载图片
- 使用ImageLoader来统一管理每一个ImageView,尽可能的把缓存机制利用起来
from weibo.
@wenmingvs 你的解决方法应该有一定的效果,但是比如如果gridview里面的item的count 是300个,虽然一次性计算出来了高度,但是每一个item显示的时候都是new 出来的,没有复用viewholder,这样造成滑动的时候会出现ANR的情况吧(我自己用300个做过实验)
from weibo.
你好,每一个item并不会new出来,而是会去复用,new出来的是只是bitmap而已。你可以好好读一下这篇博客http://blog.csdn.net/guolin_blog/article/details/45586553
另外你说会出现ANR问题,能否发相关的Demo的github地址发我看看呢?我推测是你在listview内并没有做很好的复用,并且图片也没有做适当的裁剪,才会引起ANR问题的
from weibo.
@wenmingvs 刚去查阅了郭神的博客结合看了下源码,不管ListView或者是GridView的高度固定或者是不固定,RecyclerBin的机制会一直都有,这算是自己的理解误区。
由于代码是在公司的项目里面,我自己不太好抽离出来,我贴下我的核心代码。
首先是ListView的Adapter代码:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.layout_dynamic_list_item,
parent, false);
}
// 省略代码...
NoScrollGridView gridView = ViewHolder.get(convertView, R.id.gridview);
// 省略代码...
// 图片
DynamicGridItemAdapter gridItemAdapter = null;
if (!TextUtils.isEmpty(imageUrl)) {
gridView.setVisibility(View.VISIBLE);
gridView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
handleGridItemClick(bean);
}
});
if (gridView.getAdapter() != null) {
gridItemAdapter = (DynamicGridItemAdapter) gridView
.getAdapter();
gridItemAdapter.setUrlArray(new String[] { imageUrl });
} else {
gridItemAdapter = new DynamicGridItemAdapter();
gridView.setAdapter(gridItemAdapter);
gridItemAdapter.setUrlArray(new String[] { imageUrl });
}
// 很重要,让listview的onItemClick有效果
GridViewUtils.updateGridViewLayoutParams(gridView, 3);
} else {
gridView.setVisibility(View.GONE);
}
// 省略代码...
return convertView;
}
ViewHolder的代码:
public class ViewHolder {
/**
* <T extends View> 泛型的声明 , T 表示方法的返回值
*
* @param view
* @param id
* @return
*/
public static <T extends View> T get(View view, int id) {
SparseArray<View> viewHolder = (SparseArray<View>) view.getTag();
if (viewHolder == null) {
viewHolder = new SparseArray<View>();
view.setTag(viewHolder);
}
View childView = viewHolder.get(id);
if (childView == null) {
childView = view.findViewById(id);
viewHolder.put(id, childView);
}
return (T) childView;
}
}
GridView的DynamicGridItemAdapter里面的代码为:
public class DynamicGridItemAdapter extends BaseAdapter {
private ArrayList<String> urlList;
String url = "http://pic.sc.chinaz.com/files/pic/pic9/201509/apic14886.jpg";
public DynamicGridItemAdapter() {
urlList = new ArrayList<String>();
}
public void setUrlArray(String[] urlArray) {
urlList.clear();
for (int i = 0; i < urlArray.length; i++) {
urlList.add(urlArray[i]);
}
notifyDataSetChanged();
}
@Override
public int getCount() {
return urlList != null ? urlList.size() : 0;
}
@Override
public Object getItem(int position) {
return urlList.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) parent.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(
R.layout.layout_dynamic_list_grid_item, parent, false);
}
// DebugToolUtils.printTest("getView", "position===="+position+"$$$$$convertView====="+convertView);
ImageView imageView = ViewHolder
.get(convertView, R.id.iv_gridview_item);
// ImageLoaderUtils.displayImage(url, imageView);
ImageLoaderUtils.displayImage(urlList.get(position), imageView);
return convertView;
}
}
图片加载用的UIL(内存缓存和硬盘缓存都已经设置了),具体ImageLoaderUtils.displayImage代码:
/**
* 加载图片
*
* @param uri
* 图片地址
* @param imageView
* 图片控件
*/
public static void displayImage(String uri, ImageView imageView) {
ImageAware imageAware = new ImageViewAware(imageView, false);
ImageLoader.getInstance().displayImage(uri, imageAware,
getCustomOptions());
}
图片scaleType,我设置的是center
from weibo.
你好,我细看了adapter的代码,暂时没有发现不对的地方,根据你反馈的原因,引起崩溃的是ANR而不是OOM,所以我推测的原因有2点
- ListView在快速滑动时需要动态计算GridView的高度,大量的计算引起了UI线程的阻塞,所以会出现ANR问题
- 快速滑动的时候,加载图片又马上缓存图片,导致了频繁的GC操作,引起了内存抖动,加重了CPU的负担,也进一步推动了ANR问题的出现。
能否先尝试我以下2个方法,看看是否还会有ANR问题?
- 手动设置GridView的高度与宽度
- 监听ListView的滑动事件,滑动的时候不做图片的加载,只有在停止滑动了再去加载图片
如果添加这2个方法后,仍然出现ANR问题,再联系我
from weibo.
Related Issues (20)
- 微博详情页转发评论悬浮 HOT 2
- 评论失败
- 大神怎么不继续维护这个项目了? HOT 2
- 关于下拉刷新与上拉加载更多 HOT 1
- 大神,关于recyclerview置顶以及取消置顶有没有好的方案,百度谷歌找遍了,自己实现的时候问题颇多 HOT 2
- 运行一直卡住在 gradle:resolve dependencies ':multiwindow:_debugPublish' HOT 1
- 关于微博图片浏览器区别加载普通图片、长图、gif HOT 1
- 无法登陆 HOT 1
- 这个客户端的微博授权过期了,大佬,无法登陆了 HOT 1
- Saving image error.
- 强烈建议加入抢沙发功能
- 点击图片 程序退出
- 点击登录的时候Weico授权失效了
- 啊
- 无法登陆? HOT 1
- 无法登陆?
- 无法登陆:对第三方应用授权时出现错误
- 用我自己的微博授权点击登录后显示是空白
- 在网盘下载的无法注册账号
- 网盘链接炸了
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from weibo.