首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用回调异步加载listview中的图片

使用回调异步加载listview中的图片
EN

Stack Overflow用户
提问于 2014-01-22 20:18:33
回答 2查看 373关注 0票数 0

我在我的应用程序中使用了Parse,为了加载我的“个人资料”图像,我需要检索一个所谓的Parsefile。当Parsefile下载完成时,它使用一个回调来通知完成。这通常是一种很好的方法,但在使用Listview和使用Asynctask下载图像时,我遇到了一个问题。

问题如下:

在我的ListView适配器中的getView方法中,我创建了一个AsyncTask并执行它,这个AsyncTask启动retrieveProfileImage(callBack)函数。在我的回调中,我只是在UI线程上启动一个Runnable,用新的(检索到的图像)更新视图中的ImageView。然而,问题似乎是,只要我启动我的AsyncTask,视图就会返回。因此,我无法将其他图像设置为正确的行。我希望我的代码能更清楚地说明我的问题。

ListAdapter:

代码语言:javascript
运行
复制
public class FriendListAdapter extends ArrayAdapter<Profile> {

private int resource;
private Context context;
private List<Profile> friends;
private Profile fProfile;
private Bitmap profileImageBitmap;
private ProgressBar friendImageProgressBar;


//ui
private ImageView friendImage;

public FriendListAdapter(Context context, int resource,
        List<Profile> objects) {
    super(context, resource, objects);
    this.context = context;
    this.resource = resource;
    this.friends = objects;
}



@Override
public View getView(int position, View convertView, ViewGroup parent) {

    TextView  friendName = null;
    friendImage = null;
    View rowView = convertView;
    if (rowView == null) {
      LayoutInflater inflater = ((Activity) context).getLayoutInflater();
      rowView = inflater.inflate(R.layout.friendslist_row, null);
      friendName = (TextView) rowView.findViewById(R.id.fName);
      friendImage = (ImageView) rowView
          .findViewById(R.id.fImage);
      friendImageProgressBar = (ProgressBar) rowView.findViewById(R.id.friendImageProgressBar);
    } else {
        friendName = (TextView) convertView.findViewById(R.id.fName);
        friendImage = (ImageView) convertView.findViewById(R.id.fImage);
        friendImageProgressBar = (ProgressBar) convertView.findViewById(R.id.friendImageProgressBar);
    }

    fProfile = friends.get(position);

    DownloadProfileImage dImg = new DownloadProfileImage();
    dImg.execute();

    friendName.setText(fProfile.getName());

    return rowView;

}

private class DownloadProfileImage extends AsyncTask<Void, Integer, String> {

    @Override
    protected String doInBackground(Void... arg0) {
        Log.d("logpp", "Starting download image for " + fProfile.getName());
        fProfile.retrieveProfileImage(new ProfileImageCallback());
        return null;
    }

}

private class ProfileImageCallback extends GetDataCallback {

    @Override
    public void done(byte[] bytearray, ParseException e) {
        if (e == null) {
            Log.d("logpp", "Done downloading image for " + fProfile.getName() + ". Setting bitmap to:" +
         " " + friendImage.getId());
            profileImageBitmap = BitmapManager
                    .getBitmapFromByteArray(bytearray);
            ((Activity) context).runOnUiThread(new UpdateUi());
        }
    }
}

private class UpdateUi implements Runnable {

    @Override
    public void run() {
        friendImage.setImageBitmap(profileImageBitmap);
        friendImage.setVisibility(View.VISIBLE);
        friendImageProgressBar.setVisibility(View.INVISIBLE);
    }

}

}

retrieveProfileImage方法:

代码语言:javascript
运行
复制
public void retrieveProfileImage(GetDataCallback callBack) {
    this.image.getDataInBackground(callBack);
}

我希望有人能帮我解决这个问题。

致以敬意,

时间

EN

回答 2

Stack Overflow用户

发布于 2015-12-29 20:35:57

我通过下面的代码解决了这个问题

代码语言:javascript
运行
复制
public View getView(int position, View convertView, ViewGroup parent) {
    try {
        if (inflater == null)
            inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if (convertView == null)
            convertView = inflater.inflate(R.layout.answer_item, null);

        TextView name = (TextView) convertView.findViewById(R.id.textView_ans_user_name);
        TextView body = (TextView) convertView.findViewById(R.id.textView_ans_user_body);
        TextView timestamp = (TextView) convertView.findViewById(R.id.textView_ans_user_timestamp);
        final CircularImageView thumbnail = (CircularImageView) convertView.findViewById(R.id.imageView_ans_user);
        Parse_answer_model ans = answers.get(position);
        name.setText(ans.getAns_by());
        body.setText(ans.getAns_body());
        SimpleDateFormat sdfAmerica = new SimpleDateFormat("dd-M-yyyy hh:mm:ss a");
        sdfAmerica.setTimeZone(TimeZone.getDefault());
        String sDateInAmerica = sdfAmerica.format(ans.getCreatedAt());
        timestamp.setText(sDateInAmerica);
        ParseQuery<User> query = ParseQuery.getQuery("_User");
        query.whereEqualTo("username", ans.getAns_by());
        query.getFirstInBackground(new GetCallback<User>() {

            public void done(User user, ParseException e) {
                // TODO Auto-generated method stub
                if (e == null) {

                    img.DisplayImage(user.getprofile_pic_url(), thumbnail, false);
                } else {
                }
            }
        });
    } catch (Exception e) {
        e.printStackTrace();

    }

把你的图像视图作为最终的,不要使它是全局的,你可以从geturl()方法中得到图像url,它是由parse定义的,你可以使用下面的例子

代码语言:javascript
运行
复制
ParseFile fileObject = (ParseFile) object.get("image_file");
                User user = new User();
                user = (User) ParseUser.getCurrentUser();
                user.setProfile_pic_url(fileObject.getUrl().toString());
                user.saveInBackground();

更新

上一天我找到了新的解决方案,你可以通过以下代码获取与解析对象相关的用户数据,并对模型类进行了一些更改。

代码语言:javascript
运行
复制
 void getchats() {
        pd.show();
        ParseQuery<Parse_chat_dialogs> query =    ParseQuery.getQuery("chat_dialogs");
        query.addDescendingOrder("updatedAt");
        query.whereContains("users",  ParseUser.getCurrentUser().getUsername());
        query.findInBackground(new FindCallback<Parse_chat_dialogs>() {
        public void done(List<Parse_chat_dialogs> dilogs, ParseException e) {
            if (e == null) {
                pd.hide();
                dialoglist = (ArrayList<Parse_chat_dialogs>) dilogs;
                adp = new ChatDialogAdapter(Chat_list.this, dialoglist);
                list.setAdapter(adp);
                for (int i = 0; i < dialoglist.size(); i++) {
                    ParseQuery<User> query = ParseQuery.getQuery("_User");
                    query.whereEqualTo("username", dialoglist.get(i).getUsers().trim()
                            .replace(ParseUser.getCurrentUser().getUsername(), "").replace(",", ""));
                    User user = new User();
                    try {
                        user = query.getFirst();
                        dialoglist.get(i).setFirstname(user.getFirstname());
                        dialoglist.get(i).setLastname(user.getLastname());
                        dialoglist.get(i).setProfileurl(user.getprofile_pic_url());
                        adp.notifyDataSetChanged();
                    } catch (ParseException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                }

            } else {
                Toast.makeText(Chat_list.this, e.getMessage(), Toast.LENGTH_SHORT).show();
            }
        }
    });
}

和上面的例子一样,我在parseobejct模型类中添加了三个新的参数,用于存储用户的名字、姓氏和个人资料url的值。我还分享了模型类,以获得更多的想法

代码语言:javascript
运行
复制
@ParseClassName("chat_dialogs")
public class Parse_chat_dialogs extends ParseObject {

private String firstname;
private String lastname;
private String profileurl;

public String getFirstname() {
    return firstname;
}

public void setFirstname(String firstname) {
    this.firstname = firstname;
}

public String getLastname() {
    return lastname;
}

public void setLastname(String lastname) {
    this.lastname = lastname;
}

public String getProfileurl() {
    return profileurl;
}

public void setProfileurl(String profileurl) {
    this.profileurl = profileurl;
}

/////////////////////////////////////////////////////////////////////////////
public String getLast_message() {
    return getString("last_message");
}

public void setLast_message(String value) {
    put("last_message", value);
}

public String getUsers() {
    return getString("users");
}

public void setUsers(String value) {
    put("users", value);
}
}
票数 1
EN

Stack Overflow用户

发布于 2014-01-23 02:01:47

这个怎么样!

在为列表视图设置适配器的MainActivity中使用它,而不是在适配器类中使用它。在完成的方法中,在回调或postExecute中,更新对象并调用notifyDataSetChanged()。

因此,基本上您可以在适配器类中使用update方法,例如,如下所示,

代码语言:javascript
运行
复制
public void updateObject(int pos, byte[] byteArray){
     //Assuming your Profile Object has some member to store this image data
     friends.get(pos).setImageData(byteArray); //friends is the list in adapter class and setImageData may be the setter in your Profile object class
     notifyDataSetChanged();
    }

在getView()中,您可以这样做

代码语言:javascript
运行
复制
profileImageBitmap = BitmapManager
                    .getBitmapFromByteArray(friends.get(pos).getImageData);
friendImage.setImageBitmap(profileImageBitmap);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21282763

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档