Я создаю sms-приложение, в котором перечислены контакты, имя, сообщение, дата разговора. Я использую пользовательский адаптер список them.Below является кодМедленная загрузка ListView с изображением и текстом. Как реализовать loader.callbacks?
public class ConvRowAdapter extends ArrayAdapter<ConvItem> {
private Context my_context;
// View lookup cache
private static class ViewHolder {
TextView name,body,date;
ImageView img;
}
public ConvRowAdapter(Context context, ArrayList<ConvItem> ConvItems) {
super(context, R.layout.convitem, ConvItems);
my_context=context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
ConvItem ConvItem = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
ViewHolder viewHolder; // view lookup cache stored in tag
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.convitem, null);
viewHolder.img = (ImageView) convertView.findViewById(R.id.iv_photo);
viewHolder.name = (TextView) convertView.findViewById(R.id.tv_name);
viewHolder.date = (TextView) convertView.findViewById(R.id.tv_date);
viewHolder.body = (TextView) convertView.findViewById(R.id.tv_body);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
// Populate the data into the template view using the data object
if(ConvItem.getPhotoUri()!=null)
{
Bitmap bitmap=BitmapFactory.decodeStream(my_context.getContentResolver().openInputStream(ConvItem.getPhotoUri()));
viewHolder.img.setImageBitmap(bitmap);//Image is set
}
else
{
Bitmap bitmap=BitmapFactory.decodeResource(my_context.getResources(),R.drawable.contact_blue);
viewHolder.img.setImageBitmap(bitmap);
}
if(ConvItem.getDisplayName()==null)
viewHolder.name.setText(ConvItem.getAddress());//Phone number set
else
viewHolder.name.setText(ConvItem.getDisplayName());//If phone number exists in contacts display contact name
viewHolder.date.setText(ConvItem.getDate());//set date
viewHolder.body.setText(ConvItem.getBody());//setting the body of the message
// Return the completed view to render on screen
return convertView;
}
}
Это занимает 8-9 секунд, чтобы отобразить список. Есть ли способ улучшить скорость? Если да, напишите правильный способ сделать это.
Заранее спасибо :)
Edited:
Чтобы проверить, если задержка в загрузке вызвана загрузкой изображений я пытался удалить все фото настройки заявления и побежал it.Still загрузка занимает столько же времени. С помощью simplecursoradapter я мог отображать тело, дату и сообщение без задержки. Но для отображения фотографии с ними я попытался использовать пользовательский адаптер. Это функция, которая возвращает все смс в arraylist.Please проверить эффективность кода:
public ArrayList<ConvItem> getSMS(){
ArrayList<ConvItem> ConvItems = new ArrayList<ConvItem>();
Uri uriSMSURI = Uri.parse("content://mms-sms/conversations?simple=true");
Cursor cur = getActivity().getContentResolver().query(uriSMSURI, null, null, null,
"date desc");
cur.moveToFirst();
while (!cur.isAfterLast()) {
ConvItem ConvItem = new ConvItem();
String address = null, body = null, dname = null,res=null,id_dummy=null;
Long date=null;
Uri uriphotoid=null;
//to obtain address from canonical-addresses
res = cur.getString(cur.getColumnIndex("recipient_ids"));
Uri ad =Uri.parse("content://mms-sms/canonical-addresses/");
Cursor curad=getActivity().getContentResolver().query(ad, null,null, null, null);
curad.moveToFirst();
while(!curad.isAfterLast())
{
id_dummy=curad.getString(curad.getColumnIndexOrThrow("_id"));
if(id_dummy.equals(res))
address=curad.getString(curad.getColumnIndexOrThrow("address"));
curad.moveToNext();
}
curad.close();
body = cur.getString(cur.getColumnIndexOrThrow("snippet"));
date = cur.getLong(cur.getColumnIndexOrThrow("date"));
Date datenew=new Date(date);
String formatted_date=new SimpleDateFormat(" "+"dd/MM/yyyy").format(datenew);
thread_id = cur.getString(cur.getColumnIndexOrThrow("_id"));
Long ContactID = fetchContactIdFromPhoneNumber(address);
//uriphotoid = getPhotoUri(ContactID);
dname = getcontactname(address);
ConvItem.setDisplayName(dname);
ConvItem.setThreadId(thread_id);
ConvItem.setAddress(address);
//ConvItem.setPhotoUri(uriphotoid);
ConvItem.setDate(formatted_date);
ConvItem.setBody(body);
ConvItems.add(ConvItem);
cur.moveToNext();
}
cur.close();
return ConvItems;
}
Этой функция работает на моих OnCreate метод в основном классе активности.
Я использовал loader.callbacks для исправления проблемы с задержкой.
public class InboxLoaderFragment extends Fragment implements LoaderCallbacks<Cursor>{
private static final int LOADER_ID = 1;//identify which loader
LoaderManager lm;
SimpleCursorAdapter mAdapter;
ListView lv;
private LoaderManager.LoaderCallbacks<Cursor> mCallbacks;
public InboxLoaderFragment(){}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootview=inflater.inflate(R.layout.inboxloaderfragment,container,false);
lv=(ListView)rootview.findViewById(R.id.list);
// Create an empty adapter we will use to display the loaded data.
String[] uiBindFrom = {"recipient_ids","recipient_ids","snippet"};
int[] uiBindTo = {R.id.iv_photo,R.id.tv_name,R.id.tv_body};
mAdapter = new SimpleCursorAdapter(getActivity(),R.layout.convitem,null,uiBindFrom,uiBindTo, 0);
mAdapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
@Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
switch(view.getId())
{
case R.id.iv_photo:
String res=null,address=null;
//to obtain address from canonical-addresses
res = cursor.getString(cursor.getColumnIndex("recipient_ids"));
address=getadd(res);
Long ContactID = fetchContactIdFromPhoneNumber(address);
Uri uriphotoid = getPhotoUri(ContactID);
setcontactimage(uriphotoid,view);
//set photo using uri
return true;
case R.id.tv_name:
String res1=null,address1=null;
res1 = cursor.getString(cursor.getColumnIndex("recipient_ids"));
address1=getadd(res1);//to obtain address from canonical-addresses
String dname = getcontactname(address1);
if(dname!=null)//contact exits
((TextView)view).setText(dname);//contact exists
else
((TextView)view).setText(address1);//set display name
return true;
case R.id.tv_body:
String body = cursor.getString(cursor.getColumnIndexOrThrow("snippet"));
((TextView)view).setText(body);//set message body
return true;
default:
return false;
}
}
});
lv.setAdapter(mAdapter);
mCallbacks=this;
lm = getLoaderManager();
//Initiating the loader
lm.initLoader(LOADER_ID, null,mCallbacks);
return rootview;
}
@Override
public android.support.v4.content.Loader<Cursor> onCreateLoader(
int arg0, Bundle arg1) {
Uri baseUri = Uri.parse("content://mms-sms/conversations?simple=true");
return new CursorLoader(getActivity(), baseUri,
null, null, null,"date desc");
}
@Override
public void onLoadFinished(
android.support.v4.content.Loader<Cursor> arg0, Cursor arg1) {
switch (arg0.getId()) {
case LOADER_ID:
mAdapter.swapCursor(arg1);
break;
}
// The listview now displays the queried data
}
@Override
public void onLoaderReset(android.support.v4.content.Loader<Cursor> arg0) {
mAdapter.swapCursor(null);
}
}///main activity
App загружается очень быстро now.But скроллинг laggy.How реализовать viewholder шаблон проектирования внутри пользовательского simplecursoradapter или CursorAdapter?
не используют матрицу для стартеров. используйте курсорный адаптер, поскольку запрос выбора будет быстрее, чем загрузка всех «ConvItem» из db в память. – njzk2
Еще один вопрос с соответствующими ответами: [Lazy load of Images in ListView] (http://stackoverflow.com/q/541966/1590950) – indivisible
вы говорите о simplecursoradapter правильно? Но как вы можете установить фотографию для каждой строки? –