2014-01-22 145 views
0

我在我的應用中使用了Parse,爲了加載我的'profile'圖像,我需要檢索所謂的Parsefile。當Parsefile被下載時,它使用回調來通知它何時完成。現在,這通常是一種很好的做事方式,但在使用Listview並使用Asynctask下載圖像時遇到了問題。在回調中異步加載圖像

的問題如下:

getView方法我的ListView適配器,我創建的AsyncTask並執行它,這樣的AsyncTask開始retrieveProfileImage(callBack)功能。在我的回調中,我只需在UI線程上啓動一個Runnable,以使用新的(檢索的圖像)更新View中的ImageView。不過,看起來問題是,只要我啓動AsyncTask,視圖就會返回。所以我無法將其他圖像設置爲正確的行。我希望我的代碼更清楚地表明我的問題。

的ListAdapter:

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方法:

public void retrieveProfileImage(GetDataCallback callBack) { 
    this.image.getDataInBackground(callBack); 
} 

我希望有人能幫助我這一個。

問候,

+0

使用延遲加載與像通用圖像裝載機和畢加索庫。使用UIL http://stackoverflow.com/questions/16789676/caching-images-and-displaying – Raghunandan

+0

@Raghunandan事情是,我不能使用網址。我沒有圖像網址,我可以通過使用回調來檢索圖像(位圖)。解析庫限制了我的使用。 –

回答

0

這個怎麼樣!

不是在適配器類中使用AsyncTask,而是在MainActivity中使用它來設置listview的適配器。並且在你完成的方法中,在回調或postExecute中更新對象/對象並調用notifyDataSetChanged()。

所以,基本上你可以有一個更新的方法在你的適配器類,比方說,像這樣,

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(),你可以做這樣的事情

profileImageBitmap = BitmapManager 
        .getBitmapFromByteArray(friends.get(pos).getImageData); 
friendImage.setImageBitmap(profileImageBitmap); 
1

我解決了這個問題,通過下面的代碼

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(); 

    } 

把你的ImageView作爲最終不要讓它全球,你會得到IM通過getURL()方法歲的URL,它被解析爲定義的,你可以用下面的例子

ParseFile fileObject = (ParseFile) object.get("image_file"); 
       User user = new User(); 
       user = (User) ParseUser.getCurrentUser(); 
       user.setProfile_pic_url(fileObject.getUrl().toString()); 
       user.saveInBackground(); 

更新

最後一天,我找到了新的解決方案,你可以得到通過解析對象,相關的用戶數據下面的代碼,並在模型類中進行了一些更改。

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(); 
      } 
     } 
    }); 
} 

如在上面實施例I中加入parseobejct模型類三個新PARAM,用於存儲用戶的名字,姓氏和簡檔URL的值。 我也分享模型類獲得更多的想法

@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); 
} 
}