Android-图像滚动不平滑的ListView
我正在尝试显示商品的列表视图Goods是一个包含标题、计数和图像(BLOB)的SQLite表。所以我的ListView不是平滑的 我试过什么:Android-图像滚动不平滑的ListView,android,image,listview,Android,Image,Listview,我正在尝试显示商品的列表视图Goods是一个包含标题、计数和图像(BLOB)的SQLite表。所以我的ListView不是平滑的 我试过什么: 打开相机意图、拍摄、获取额外信息并插入SQLite。所以我只使用了一个位图。这种方法在货物数量少于50件之前效果良好 我走了另一条路: 打开相机意图,捕获并保存到文件 检查ExifInterface并根据需要旋转图像 使用缩放至300x300大小并移动到“我的文件夹”。此图像文件用于全屏显示 现在我需要一个缩略图,以便将来将其放入ListView。因此,
ExifInterface
并根据需要旋转图像setPic()
方法将文件(3)缩放到缩略图大小(例如60x60)
并将这个小拇指保存到SQLite数据库货物表中public class GoodsCursorAdapter extends SimpleCursorAdapter {
public GoodsCursorAdapter(Context context) {
super(context, R.layout.cell_goods, null,
new String[] { "title", "countAvail" },
new int[] { R.id.lbTitle, R.id.lbCount }, 0);
}
private class ViewHolder {
ImageView imageView;
TextView lbTitle, lbCount;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null){
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.cell_goods, parent, false);
viewHolder = new ViewHolder();
viewHolder.imageView = (ImageView) convertView.findViewById(R.id.ivThumb);
viewHolder.lbTitle = (TextView) convertView.findViewById(R.id.lbTitle);
viewHolder.lbCount = (TextView) convertView.findViewById(R.id.lbCount);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
mainCursor.moveToPosition(position);
byte[] byteArray = mainCursor.getBlob(mainCursor.getColumnIndex("photo"));
if (byteArray != null) {
Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
Log.d("INFO", mainCursor.getString(mainCursor.getColumnIndex("title"))+": "+String.valueOf(bitmap.getWidth())+"x"+String.valueOf(bitmap.getHeight())+"("+String.valueOf(bitmap.getByteCount()/1024)+"Kb)");
viewHolder.imageView.setImageBitmap(bitmap);
} else {
viewHolder.imageView.setImageResource(R.drawable.ic_action_picture);
}
viewHolder.lbTitle.setText(mainCursor.getString(mainCursor.getColumnIndex("title")));
viewHolder.lbCount.setText(String.format(getString(R.string.lbCount), mainCursor.getString(mainCursor.getColumnIndex("countAvail"))));
return convertView;
}
在构造函数或适配器外部加载getview()之外的所有位图,然后将其分配给适配器。每次创建视图时从数据库加载图像可能会减慢滚动速度 如果在预编辑图像时遇到任何内存问题,请尝试在内存中缓存它们
尝试使用异步任务从UI线程加载图像,而不是保存到数据库 像这样的东西(取自)
使用惰性列表在listview中下载图像。
参考链接:使用分页..获取5/10行并加载位图使用 也可以异步加载位图 编辑
mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == 1) {
isUserScroll = true;
} else {
isUserScroll = false;
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (isUserScroll) {
int lastInScreen = firstVisibleItem + visibleItemCount;
if (!isDataLoading && (lastInScreen == totalItemCount)) {
//load data
isDataLoading = true;
}
}
}
});
好了,伙计们,我已经尝试了你们建议的几乎所有方法。这是我的报告:
inSampleSize
选项(从BitmapFactory.Options
)。方法比在SQLite中存储小缩略图更好(正如我第一次做的),但对于超过200个带有图像的列表项,它变得不平滑另外,对不起我的英语:)检查一下:@Hareshchelana:我已经使用这种方法进行缩放,请看我的问题:)可能我可以在我的
getView()
中使用它?是的,尝试在getView()中使用。再试一件事在构造函数或适配器外部加载getView()之外的所有位图,然后将其分配给适配器。创建视图时,每次从数据库加载图像都可能会减慢滚动速度。@user4153589,如果最初加载的所有位图,则可能会导致内存不足异常。感谢您的回复,但图像数量可能约为1-2千)然后不要保存在数据库缓存中,只将URL保存到数据库ooh。。并将从web下载
功能替换为my从SD和scale下载
功能。对吗?是的,对。懒惰列表下载只不过是一个异步任务,根据优先级来完成繁重的工作。好的,谢谢,我会尝试并回复)mm。。不了解如何将onPostExecute
改编为LitView项目。。您能给出更详细的解释吗?@Zain您还想增加线程池的大小(另一方面,由于Executor在Android 4或3上默认只有一个线程,因此图像解码会出现延迟。此外,还需要进行检查以防止由于视图回收而出现问题。我已将上面的代码修改为您现在可以使用的代码。@Amit对这两个帐户都是正确的,但目前,如果Romowski可以让它工作,并且更平滑,他可以n查看线程池大小和单元重用。我考虑过分页,但没有找到一些关于..以及如何在ListView中可视化分页的文章?您可以添加逻辑以在ListView的OnScroll上加载下一批。谢谢,我将尝试此方法
if (byteArray != null) {
BitmapWorkerTask task = new BitmapWorkerTask(imageView);
task.execute(mainCursor);
}else{......}
mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == 1) {
isUserScroll = true;
} else {
isUserScroll = false;
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (isUserScroll) {
int lastInScreen = firstVisibleItem + visibleItemCount;
if (!isDataLoading && (lastInScreen == totalItemCount)) {
//load data
isDataLoading = true;
}
}
}
});