Android 缓慢加载带有图像和文本的ListView。如何实现loader.callbacks?
我正在建立一个短信应用程序,其中列出了联系人照片,姓名,信息,对话日期。 我正在使用自定义适配器列出它们。下面是代码Android 缓慢加载带有图像和文本的ListView。如何实现loader.callbacks?,android,android-asynctask,android-arrayadapter,loader,android-cursorloader,Android,Android Asynctask,Android Arrayadapter,Loader,Android Cursorloader,我正在建立一个短信应用程序,其中列出了联系人照片,姓名,信息,对话日期。 我正在使用自定义适配器列出它们。下面是代码 public class ConvRowAdapter extends ArrayAdapter<ConvItem> { private Context my_context; // View lookup cache private static class ViewHolder { TextView name,body,date; ImageVie
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;
}
}
为了检查加载延迟是否是由于加载图像造成的,我尝试删除所有照片设置语句并运行它。加载仍然需要相同的时间。
通过使用simplecursoradapter,我可以毫不延迟地显示正文、日期和消息。但是为了显示带有它们的照片,我尝试使用自定义适配器。
这是将所有sms返回到arraylist的函数。请检查代码的效率:
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;
}
public ArrayList getSMS(){
ArrayList conviitems=新的ArrayList();
Uri Uri=Uri.parse(“content://mms-sms/conversations?simple=true");
Cursor cur=getActivity().getContentResolver().query(urimsuri,null,null,
“日期说明”);
cur.moveToFirst();
而(!cur.isAfterLast()){
ConvItem ConvItem=新的ConvItem();
字符串地址=null,body=null,dname=null,res=null,id\u dummy=null;
长日期=空;
Uri uriphotoid=null;
//从规范地址获取地址
res=cur.getString(cur.getColumnIndex(“收件人ID”);
Uri ad=Uri.parse(“content://mms-sms/canonical-addresses/");
Cursor curad=getActivity().getContentResolver().query(ad,null,null,null);
curad.moveToFirst();
而(!curad.isAfterLast())
{
id_dummy=curad.getString(curad.getColumnIndexOrThrow(“_id”);
如果(id_虚拟等于(res))
地址=curad.getString(curad.getColumnIndexOrThrow(“地址”);
curad.moveToNext();
}
curad.close();
body=cur.getString(cur.getColumnIndexOrThrow(“代码段”);
日期=当前getLong(当前getColumnIndexOrThrow(“日期”);
Date datenew=新日期(日期);
格式化的字符串\u date=new SimpleDateFormat(“+”dd/MM/yyyy”)。格式(datenew);
thread_id=cur.getString(cur.getColumnIndexOrThrow(“_id”);
Long ContactID=获取ContactIDFromPhoneNumber(地址);
//uriphotoid=getPhotoUri(ContactID);
dname=getcontactname(地址);
conviitem.setDisplayName(dname);
ConvItem.setThreadId(线程id);
conviitem.setAddress(地址);
//conviitem.setPhotoUri(uriphotoid);
ConvItem.setDate(格式化的_日期);
conviitem.setBody(body);
conviitems.add(conviitem);
cur.moveToNext();
}
cur.close();
归还物品;
}
此函数在主活动类中的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
公共类InboxLoaderFragment扩展片段实现LoaderCallbacks{
私有静态最终整型加载器\u ID=1;//标识哪个加载器
装载机管理器lm;
简单的适应;
ListView lv;
私有LoaderManager.LoaderCallbacks McCallbacks;
公共InboxLoaderFragment(){}
@凌驾
创建视图上的公共视图(布局、充气机、视图组容器、,
Bundle savedInstanceState){
视图根视图=充气机。充气(右侧布局。箱内装载机碎片,容器,假);
lv=(ListView)rootview.findviewbyd(R.id.list);
//创建一个空适配器,用于显示加载的数据。
字符串[]uiBindFrom={“收件人ID”、“收件人ID”、“代码段”};
int[]uiBindTo={R.id.iv_photo,R.id.tv_name,R.id.tv_body};
mAdapter=new SimpleCursorAdapter(getActivity(),R.layout.conviitem,null,uiBindFrom,uiBindTo,0);
mAdapter.setViewBinder(新的SimpleCursorAdapter.ViewBinder(){
@凌驾
公共布尔setViewValue(视图、光标、int-columnIndex){
开关(view.getId())
{
案例R.id.iv_照片:
字符串res=null,地址=null;
//从规范地址获取地址
res=cursor.getString(cursor.getColumnIndex(“收件人ID”);
地址=getadd(res);
Long ContactID=获取ContactIDFromPhoneNumber(地址);
Uri uriphotoid=getPhotoUri(ContactID);
setcontactimage(uriphotoid,视图);
//使用uri设置照片
返回true;
案例R.id.tv\U名称:
字符串res1=null,地址1=null;
res1=cursor.getString(cursor.getColumnIndex(“收件人ID”);
address1=getadd(res1);//从规范地址获取地址
字符串dname=getcontactname(address1);
if(dname!=null)//联系人退出
((TextView)视图).setText(dname);//联系人存在
其他的
((文本视图)视图).setText(地址1);//设置显示名称
返回true;
案例R.id.tv\U主体:
String body=cursor.getString(cursor.getColumnIndexOrThrow(“代码段”);
((文本视图)视图).setText(正文);//设置消息正文
返回true;
违约:
返回false;
}
}
});
低压设置适配器(mAdapter);
mCallbacks=这个;
lm=getLoaderManager();
//启动加载程序
lm.initLoader(LOADER_ID,null,mCallbacks);
返回rootview;
}
@凌驾
public android.support.v4.content.Loader onCreateLoader(
int arg0,Bundle arg1){
Uri baseUri=Uri.parse(“content://mms-sms/conversations?simple=true");
返回新的游标装入器(getActivity(),baseUri,
空,空,空,“日期描述”);
}
@凌驾
已完成公共无效加载(
android.support.v4.content.Loader arg0,光标arg1){
开关(arg0.getId()){
案例加载器\u ID:
swapCursor(arg1);
打破
}
//listview现在显示查询的数据
}
@凌驾
public void onLoaderReset(android.support.v4.content.Loader arg0){
mAdapter.swapCursor(空);
}
}///主要活动
应用程序加载版本
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