我在listview中设置图片时遇到问题。 所有图像都被加载,但是它们不是逐个设置的,例如,当加载一个图像时,它将被加载到列表中的所有视图中,而不仅仅是在所需的位置。
图像比我更好,但我没有足够的声誉。
我的代码在这里:
public class Sightsee{
private String sightseeName;
private String sightseeInfo;
private double sightseeLatitude;
private double sightseeLongitude;
private String sightseeImageUri;
private String sightseeCity;
private double sightseeDistance;
private static Bitmap image;
private SightseeAdapter ssa;
private DownloadableBitmap downloadableBitmap;
public Sightsee( String sightseeName, String sightseeInfo,double d,double e, String sightseeImageUri,String sightseeCity,double sightseeDistance){
this.sightseeName =sightseeName;
this.sightseeInfo =sightseeInfo;
this.sightseeLatitude = d;
this.sightseeLongitude=e;
this.sightseeCity=sightseeCity;
this.sightseeDistance=sightseeDistance;
this.sightseeImageUri=sightseeImageUri;
this.downloadableBitmap = new DownloadableBitmap();
this.downloadableBitmap.setImageUri(sightseeImageUri);
this.image=null;
}
public Bitmap getImage(){
return image;
}
public void setImage(Bitmap bm){
this.image=bm;
}
public SightseeAdapter getAdapter(){
return ssa;
}
public void setAdapter(SightseeAdapter ssa){
this.ssa=ssa;
}
public void loadImage(SightseeAdapter ssa){
this.ssa=ssa;
if(sightseeImageUri!=null ){
new ImageLoadTask().execute(sightseeImageUri);
}
}
public String getSightseeName() {
return sightseeName;
}
public void setsightseeName(String sightseeName) {
this.sightseeName = sightseeName;
}
public String getSightseeInfo() {
return sightseeInfo;
}
public void setsightseeInfo(String sightseeInfo) {
this.sightseeInfo = sightseeInfo;
}
public double getSightseeLatitude() {
return sightseeLatitude;
}
public void setsightseeLatitude(double sightseeLatitude) {
this.sightseeLatitude = sightseeLatitude;
}
public double getSightseeLongitude() {
return sightseeLongitude;
}
public void setsightseeLongitude(double sightseeLongitude) {
this.sightseeLongitude = sightseeLongitude;
}
public DownloadableBitmap getDownloadableBitmap() {
return downloadableBitmap;
}
public void setDownloadableBitmap(DownloadableBitmap downloadableBitmap) {
this.downloadableBitmap = downloadableBitmap;
}
public String getSightseeCity() {
return sightseeCity;
}
public void setsightseeCity(String sightseeCity) {
this.sightseeCity = sightseeCity;
}
public double getSightseeDistance() {
return sightseeDistance;
}
public void setSightseeDistance(double sightseeDistance) {
this.sightseeDistance = sightseeDistance;
}
public String getPictureLocation(){
return sightseeImageUri;
}
public void setsightseePictureLocation(String sightseeImageUri) {
this.sightseeImageUri = sightseeImageUri;
}
// ASYNC TASK TO AVOID CHOKING UP UI THREAD
private class ImageLoadTask extends AsyncTask<String, String, Bitmap> {
// PARAM[0] IS IMG URL
protected Bitmap doInBackground(String... param) {
CommonFunctions.infoLog("ImageLoadTask", "Attempting to load image URL: " + param[0]);
Bitmap b = ImageDownloader.downloadImage(param[0]);
return b;
}
protected void onProgressUpdate(String... progress) {
// NO OP
}
protected void onPostExecute(Bitmap ret) {
if (ret != null) {
CommonFunctions.infoLog("ImageLoadTask", "Successfully loaded image");
image = ret;
if (ssa != null) {
// WHEN IMAGE IS LOADED NOTIFY THE ADAPTER
ssa.notifyDataSetChanged();
}
} else {
CommonFunctions.infoLog("ImageLoadTask", "Failed to load ");
}
}
}
}
private class SightseeLoaderTask extends AsyncTask<String, Void, ArrayList<Sightsee>>{
ProgressDialog dialog;
public SightseeLoaderTask(){
dialog = new ProgressDialog(DiscoverAround.this);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
dialog.setMessage(getResources().getString(R.string.ProgressBar_Loading_Message));
dialog.setCancelable(true);
dialog.setOnCancelListener(new OnCancelListener()
{
@Override
public void onCancel(DialogInterface dialog)
{
SightseeLoaderTask.this.cancel(true);
}
});
dialog.show();
}
@Override
protected ArrayList<Sightsee> doInBackground(String... params) {
ArrayList<Sightsee> SightseeList = new ArrayList<Sightsee>();
if(CommonFunctions.isConnectedToInternet(DiscoverAround.this)){
try {
String ret = getUrlString(params[0]);
ret = ret.trim();
JSONObject jsonObj = new JSONObject(ret);
CommonFunctions.infoLog("jObj",jsonObj.toString());
int success = jsonObj.getInt("success");
if(success == 1){
JSONArray Sightsees = jsonObj.getJSONArray("Location");
JSONObject tmp;
for(int i=0; i<Sightsees.length(); i++){
tmp = Sightsees.getJSONObject(i);
Sightsee _Sightsee = new Sightsee(
tmp.getString("locationName"),
tmp.getString("locationInfo"),
tmp.getDouble("locationLatitude"),
tmp.getDouble("locationLongitude"),
tmp.getString("locationPic"),
tmp.getString("city"),
tmp.getDouble("distance")
);
SightseeList.add(_Sightsee);
}
}
} catch (SocketTimeoutException e) {
//CommonFunctions.getAlertDialog(DiscoverAround.this, Constants.ALERTDIALOG_TYPE_SOCKET_TIMEOUT_ERROR, "", Constants.ALERTDIALOG_BUTTON_CLICKMODE_DISMISS).show();
CommonFunctions.exceptionLog(e);
return null;
} catch (MalformedURLException e) {
CommonFunctions.getAlertDialog(DiscoverAround.this, Constants.ALERTDIALOG_TYPE_SERVER_ERROR, "", Constants.ALERTDIALOG_BUTTON_CLICKMODE_DISMISS).show();
CommonFunctions.exceptionLog(e);
return null;
} catch (IOException e) {
CommonFunctions.getAlertDialog(DiscoverAround.this, Constants.ALERTDIALOG_TYPE_SERVER_ERROR, "", Constants.ALERTDIALOG_BUTTON_CLICKMODE_DISMISS).show();
CommonFunctions.exceptionLog(e);
return null;
} catch (JSONException e) {
//CommonFunctions.getAlertDialog(DiscoverAround.this, Constants.ALERTDIALOG_TYPE_SERVER_ERROR, "", Constants.ALERTDIALOG_BUTTON_CLICKMODE_DISMISS).show();
CommonFunctions.exceptionLog(e); //json exception
return null;
}
}
else {
CommonFunctions.getAlertDialog(DiscoverAround.this, Constants.ALERTDIALOG_TYPE_CONNECTIONERROR, "", Constants.ALERTDIALOG_BUTTON_CLICKMODE_DISMISS).show();
}
return SightseeList;
}
@Override
protected void onPostExecute( ArrayList<Sightsee>result) {
super.onPostExecute(result);
if(dialog != null && dialog.isShowing()) {
dialog.dismiss();
if( result!=null ){
SightseeList = (ListView) findViewById(R.id.list);
//asdfglllhf
adapter = new SightseeAdapter(DiscoverAround.this, result);
// SET AS CURRENT LIST
SightseeList.setAdapter(adapter);
int i=0;
for (Sightsee s : result) {
// START LOADING IMAGES FOR EACH ITEM
s.loadImage(adapter);
}
//asdfglllhf
}
else {
CommonFunctions.infoLog("sightseeList","empty");
CommonFunctions.getAlertDialog(DiscoverAround.this, Constants.ALERTDIALOG_TYPE_NOTFOUND_ERROR, "", Constants.ALERTDIALOG_BUTTON_CLICKMODE_DISMISS).show();
}
}
}
}
static class ViewHolder {
ImageView image;
TextView name;
TextView distance;
Button btn;
int pos;
}
public class SightseeAdapter extends BaseAdapter{
private LayoutInflater mInflater;
private ArrayList<Sightsee> objectsList;
public SightseeAdapter(Context context,
ArrayList<Sightsee> objects) {
this.objectsList=objects;
}
public int getCount() {
return objectsList.size();
}
public Sightsee getItem(int position){
return objectsList.get(position);
}
public long getItemId(int position){
return position;
}
private Sightsee Sightsee;
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Sightsee s =objectsList.get(position);
Sightsee =objectsList.get(position);
ViewHolder holder;
// ViewHolder holder = new ViewHolder();
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// SightseeImage = (ImageView) convertView.findViewById(R.id.place_image);
View row = convertView;
if (row == null) {
row = vi.inflate(R.layout.customcomponent_list, null);
holder=new ViewHolder();
holder.image = (ImageView) row.findViewById(R.id.place_image);
row.setTag(holder);
//SightseeImage = (ImageView) convertView.findViewById(R.id.place_image);
} else {
holder=(ViewHolder) row.getTag();
}
if (Sightsee.getImage() != null) {
holder.image.setImageBitmap(Sightsee.getImage());
} else {
// MY DEFAULT IMAGE
holder.image.setImageResource(R.drawable.arrow);
}
Sightsee = getItem(position);
holder.name = (TextView) row.findViewById(R.id.place_name);
holder.distance = (TextView)row.findViewById(R.id.place_distance);
convertView.findViewById(R.id.show_button);
holder.name.setText(Sightsee.getSightseeName());
double value = Sightsee.getSightseeDistance();
holder.distance.setText( String.valueOf((float) (long) (value * 100) / 100.0) +" km");
![enter image description here][2]
}
答案 0 :(得分:0)
您可以将ImageView发送到任务构造函数,并在那里保留对图像路径的引用。现在在onPostExecute中,检查ImageView的当前标记是否与您开始使用的标记相同。如果是,则设置图像。如果不是,请不要做任何事情。
但是,这意味着无论如何都会下载图像。你不会在视图上设置错误的图像。
编辑:首先将ImageView传递给任务构造函数:
new LoadImage(imageView).execute()
然后在LoadImage构造函数中保存对ImageView和图像路径的引用。在构造函数中而不是在doInBackground中保存路径非常重要,以确保我们不会遇到多线程问题。然后在onPostExecute我们检查当前路径。
class LoadImage extends AsyncTask<Object, Void, Bitmap>{
private ImageView imv;
private String path;
public LoadImage(ImageView imv) {
this.imv = imv;
this.path = imv.getTag().toString();
}
@Override
protected Bitmap doInBackground(Object... params) {
Bitmap bitmap = null;
File file = new File(
Environment.getExternalStorageDirectory().getAbsolutePath() + path);
if(file.exists()){
bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
}
return bitmap;
}
@Override
protected void onPostExecute(Bitmap result) {
if (!imv.getTag().toString().equals(path)) {
/* The path is not same. This means that this
image view is handled by some other async task.
We don't do anything and return. */
return;
}
if(result != null && imv != null){
imv.setVisibility(View.VISIBLE);
imv.setImageBitmap(result);
}else{
imv.setVisibility(View.GONE);
}
}
}
您可能会遇到错误放置图像的问题,因此您可以使用以下解决方案。
@Override
protected void onPostExecute(Bitmap result) {
if (!imv.getTag().toString().equals(rec_id)) {
return;
}
if(result != null && imv != null){
int index = id.indexOf(imv.getTag().toString());
if(list.getFirstVisiblePosition()<=index && index<=list.getLastVisiblePosition())
{
imv.setVisibility(View.VISIBLE);
imv.setImageBitmap(result);
}
}else{
imv.setImageBitmap(icon);
imv.setVisibility(View.GONE);
}
}
此处列表是listview的对象。只需将列表视图对象传递给适配器并粘贴此函数,而不是onPostExecute函数。