Android 如何改进ListView';什么时候加载速度更快?
我使用从Android 如何改进ListView';什么时候加载速度更快?,android,Android,我使用从ArrayAdapter扩展的自定义适配器实现了我的ListView。 我的问题是,有时ListView加载缓慢。这意味着首先加载一个空白的活动,而不使用ListView,然后出现ListView。在最坏的情况下,系统会提示我“强制关闭或等待”。我喜欢改进这种缓慢的加载,因为这对用户来说很烦人 但有时,加载速度很快,几乎是即时的 但是我想确保我的ListView设计是正确的,并且设计不会因为加载太慢而出现任何问题。因此,本次讨论将对其他面临与我相同问题的人有用 我的ListView设计如
ArrayAdapter
扩展的自定义适配器实现了我的ListView
。
我的问题是,有时ListView
加载缓慢。这意味着首先加载一个空白的活动,而不使用ListView
,然后出现ListView
。在最坏的情况下,系统会提示我“强制关闭或等待”。我喜欢改进这种缓慢的加载,因为这对用户来说很烦人
但有时,加载速度很快,几乎是即时的
但是我想确保我的ListView
设计是正确的,并且设计不会因为加载太慢而出现任何问题。因此,本次讨论将对其他面临与我相同问题的人有用
我的ListView设计如下
每个ListItem有三个组件:缩略图、ID文本和箭头图像,如附图所示
在列表视图的加载过程中,(1)从数据库中检索所有ID文本,并将其填充到列表数组列表ID
public class MyListFragment extends ListFragment implements OnItemClickListener {
dbHelper = new TrackerDBAdapter(getActivity());
dbHelpLatLong = new LatLogDBAdapter(getActivity());
dbHelpNotification = new NotificationDatabaseAdapter(getActivity());
dbHelper.open();
Cursor cursor = dbHelper.fetchAllTrackerInTheList();
listIDs = new ArrayList<String>();
activationStatus = new ArrayList<String>();
thisListFragmentContext = getActivity();
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
listIDs.add(cursor.getString(1));
}
dbHelper.close();
(2)Then my custom list adapter is called.
adapter = new customList_Adaptor(thisListFragmentContext,
R.layout.list_row, listIDs, this);
}
That is the loading process inside my `ListFragment`.
我做了一些事情来加快应用程序的加载速度。
我不确定哪一个是解决方案。
(1) 我使用AsyncTask
从sql数据库加载所有数据,包括文本和缩略图。
(2) 我将缩略图格式从png更改为jpg。
(3) 然后我手动清除缓存。
该应用程序看起来加载速度更快,但有时仍然很慢。大多数时候,它比以前快。
我仍在改进我的应用程序。
谢谢我使用数据库保存ListItem的所有内容。因此,从数据库检索数据是加载过程中的缓慢响应。因此,我尝试使用AsyncTask检索ListItem内容。但问题是,如果在调用自定义适配器时后台进程仍在运行,则不会出现ListView。现在问题已经解决,可以非常快速地加载ListView。现在我在程序onDestroy()中编写了清除缓存的代码。
public class customList_Adaptor extends ArrayAdapter<String>{
protected static final int CAMERA_REQUEST = 0;
private TrackerDBAdapter dbHelper;
private Context context;
private List<String> listIDs = new ArrayList<String>();
private List<String> activationState = new ArrayList<String>();
public MyListFragment mMyListFragment;
public customList_Adaptor(Context context, int textViewResourceId,
List<String> objects, List<String> activationStatus, MyListFragment mMyListFragment) {
super(context, textViewResourceId, objects);
this.setContext(context);
this.listIDs = objects;
this.activationState = activationStatus;
this.mMyListFragment= mMyListFragment;
dbHelper = new TrackerDBAdapter(context);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
if(listIDs != null)
return listIDs.size();
else
return 0;
}
@Override
public String getItem(int arg0) {
// TODO Auto-generated method stub
if(listIDs != null)
return listIDs.get(arg0);
else
return null;
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return arg0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
ViewHolder viewHolder=new ViewHolder();
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if(vi==null){
vi = inflater.inflate(R.layout.list_row, parent, false);
viewHolder.id=(TextView)vi.findViewById(R.id.title);
viewHolder.thumbnailImage=(ImageView)vi.findViewById(R.id.list_image);
viewHolder.activationStatus = (TextView)vi.findViewById(R.id.activated);
//lazy load image
BitmapWorkerTask task = new BitmapWorkerTask(viewHolder.thumbnailImage);
task.execute(position);
viewHolder.arrow=(ImageView)vi.findViewById(R.id.list_arrow);
vi.setTag(viewHolder);
}
else
viewHolder=(ViewHolder) vi.getTag();
viewHolder.thumbnailImage.setOnClickListener(new onMyClick(position));
// Setting all values in listview
viewHolder.id.setText(listIDs.get(position));
if(activationState.get(position).equals("Not activated yet")){
viewHolder.activationStatus.setText(activationState.get(position));
viewHolder.activationStatus.setTextColor(android.graphics.Color.GRAY);
}
else if(activationState.get(position).equals("Activated"))
viewHolder.activationStatus.setText("");
return vi;
}
public class onMyClick implements OnClickListener {
private final int pos;
public onMyClick(int pos) {
this.pos = pos;
}
@Override
public void onClick(View v) {
MyListFragment.clickedimageView = (ImageView) v.findViewById(R.id.list_image);
mMyListFragment.imagepos(pos);
}
}
public Context getContext() {
return context;
}
public void setContext(Context context) {
this.context = context;
}
//Lazy image update
class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private int data = 0;
public BitmapWorkerTask(ImageView imageView) {
// Use a WeakReference to ensure the ImageView can be garbage collected
imageViewReference = new WeakReference<ImageView>(imageView);
}
// Decode image in background.
@Override
protected Bitmap doInBackground(Integer... params) {
setData(params[0]);
Bitmap bitmap = null;
dbHelper.open();
Cursor mCursor = dbHelper.getImagebyIDnumber(getData());
byte[] img_bytes = mCursor.getBlob(13);
bitmap = BitmapFactory.decodeByteArray(img_bytes, 0, img_bytes.length);
dbHelper.close();
return bitmap;
}
// Once complete, see if ImageView is still around and set bitmap.
@Override
protected void onPostExecute(Bitmap bitmap) {
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
}
}
public class ViewHolder {
TextView id;
TextView activationStatus;
ImageView thumbnailImage;
ImageView arrow;
}