0

長名稱的道歉。Android - 從getView函數中設置ImageView適配器內的ImageView的源代碼無法正常工作

我正在構建一個活動包含自定義listView的Android應用程序。在我的自定義listView的佈局中,我有一個圖像視圖和三個textView。我正在從數據庫中提取數據,因爲它們是準確的,所以我對行數據沒有任何問題。但是,我有顯示ImageViews的問題。

我做什麼來填充imageView是我從數據庫中獲取imagePath,解析該URL(僅限本地服務器),然後設置ImageViews位圖。

在我的customListView類的getView函數期間,我創建了一個處理數據庫中的url的線程,然後解析它,然後將其設置爲ImageView的位圖。

這裏是我的getView功能:

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

    if (convertView == null) { 

     convertView = layoutInflater.inflate(R.layout.nominees_list_layout, null); 
     holder = new ViewHolder(); 

     holder.firstName = (TextView) convertView.findViewById(R.id.nomineesListFirstName); 
     holder.middleName = (TextView) convertView.findViewById(R.id.nomineesListMiddleName); 
     holder.lastName = (TextView) convertView.findViewById(R.id.nomineesListLastName); 
     holder.photo = (ImageView) convertView.findViewById(R.id.nomineesListCandidatePhoto); 


     convertView.setTag(holder); 
    } 
    else { 
     holder = (ViewHolder) convertView.getTag(); 
    } 

    holder.firstName.setText(listData.get(position).getFirst_name()); 
    holder.middleName.setText(listData.get(position).getMiddle_name()); 
    holder.lastName.setText(listData.get(position).getLast_name()); 

    new setDisplayPhoto().execute(listData.get(position).getPicture_path()); 

    return convertView; 
} 

正如你所看到的,我初始化視圖組件然後根據從數據庫中獲取的listData設置它們的值。顯示的數據都是正確的。然後,我爲imageView所做的工作是創建一個AsyncTask並在那裏提供數據。

這裏是我的AsyncTask:

private class setDisplayPhoto extends AsyncTask<String, Void, String> { 
    String toastMessage = "Downloading nominees photo finished."; 

    Bitmap mIcon_val; 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
    } 

    @Override 
    protected String doInBackground(String... params) { 

     Log.d("","doInBackGround Started"); 

     String photo_url_str = "http://192.168.0.10:8888/server/path/here/" 
       + params[0]; 

     try { 
      Log.d("","photo_url_str = " + photo_url_str); 
      newurl = new URL(photo_url_str); 
     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } 
     try { 

      mIcon_val = BitmapFactory.decodeStream(newurl.openConnection().getInputStream()); 

      holder.photo.setImageBitmap(mIcon_val); 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } 


     return "Executed!"; 
    } 

    @Override 
    protected void onPostExecute(String result) { 
     super.onPostExecute(result); 
     Toast.makeText(context, toastMessage, Toast.LENGTH_LONG).show(); 
    } 

然而,這些照片不會出現,如果他們這樣做,有時這些照片是混亂的。

有人可以幫助我如何正確設置imageView的圖像源期間customViewView適配器的getView函數從本地服務器獲取源時?感謝您的任何幫助。

+0

網絡操作始終在輔助線程運行....所以,如果你給一個URL路徑,並嘗試下載它會下載一些其他線程,因此,最好是有自己的AsyncTask嘗試下載圖像在下載它之後回到你的適配器。取決於位置的可視性顯示圖像。 –

+0

我試圖取消實際下載文件,因爲我希望系統能夠通過從服務器獲取文件而無需下載它而變得靈活。 – Razgriz

+0

在你的情況下,保持listitems的位置是非常重要的...原因listview是基於回收的概念..所以,如果你通過imageview對象,無論哪個位置是可見的,你的線程將嘗試將圖像設置爲該圖像視圖 –

回答

2

它不工作的原因是因爲處理圖像下載,緩存和查看回收比你的代碼處理更復雜。

我可以指出來的幾件事情,我可以看到它從你的代碼錯了,但肯定還有更多:

  • 沒有RAM緩存,這意味着當下用戶滾動視圖出來,如果視圖然後回到視圖中,圖像將再次從服務器下載。
  • 沒有磁盤緩存,這意味着如果用戶在列表中滾動得太遠,或者如果他/她離開應用幾分鐘以後再回來,則會從服務器再次下載映像
  • 在這條線上holder.photo.setImageBitmap您正試圖在後臺線程中更改View
  • AsyncTask(從某些API開始)是一個單線程類,這意味着所有的下載都將在一個接一個地發生,因此用戶在看到任何東西之前可能會盯着一個空白屏幕。
  • 您並未取消任務,因此在回收期間,致電setImageBitmap可能發生在錯誤的項目上。

更換行:

new setDisplayPhoto().execute(listData.get(position).getPicture_path()); 

有:

Picasso.with(convertView.getContext()) 
    .load("http://192.168.0.10:8888/server/path/here/" + 
         listData.get(position).getPicture_path()) 
    .into(holder.photo); 

對於工作,你就需要一個額外的libary,你可以通過添加在你的清單中添加以下行:

compile 'com.squareup.picasso:picasso:2.5.2' 

圖書館的更多信息查詢此:http://square.github.io/picasso/

+0

我需要在AsyncTask中做到這一點嗎? – Razgriz

+0

不!直接替換'getView'中的代碼,就可以拋棄AsyncTask代碼。畢加索圖書館處理有關線索的所有問題。 – Budius

+0

噢,我的好主,聽起來真的真的很好。我會盡快檢查並儘快給出反饋意見。 – Razgriz

0
package com.example.jojo.gridview; 
import android.app.Activity; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.os.AsyncTask; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.BaseAdapter; 
import android.widget.ImageView; 
import android.widget.TextView; 
import java.io.BufferedInputStream; 
import java.io.BufferedOutputStream; 
import java.io.InputStream; 
import java.net.URL; 
import java.util.ArrayList; 

public class GirdViewAdapter extends BaseAdapter { 
    private Activity activity; 
    private ArrayList<String> ar; 
    private LayoutInflater inflater; 

    public GirdViewAdapter(ArrayList<String> ar, Activity con) 
    { 
     activity = con; 
     this.ar=ar; 
     inflater = (LayoutInflater) activity 
       .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 

    private class ViewHolder { 
     public TextView textView; 
     public ImageView imageView; 
    } 

    @Override 
    public int getCount() { 
     // TODO Auto-generated method stub 
     return ar.size(); 
    } 

    @Override 
    public Object getItem(int arg0) { 
     // TODO Auto-generated method stub 
     return null; 
    } 

    @Override 
    public long getItemId(int arg0) { 
     // TODO Auto-generated method stub 
     return 0; 
    } 

    @Override 
    public View getView(int position, View arg1, ViewGroup arg2) { 
     // TODO Auto-generated method stub 
     View rowView = arg1; 
     ViewHolder viewHolder; 
     if (arg1 == null) { 
      rowView = inflater.inflate(R.layout.style_view, null); 
      viewHolder = new ViewHolder(); 
      viewHolder.textView = (TextView) rowView.findViewById(R.id.textView); 
      viewHolder.imageView = (ImageView) rowView.findViewById(R.id.imageView); 
      rowView.setTag(viewHolder); 
     } else 
      viewHolder = (ViewHolder) rowView.getTag(); 
     String rowData[] = this.ar.get(position).split("\\|"); 
     viewHolder.textView.setText(rowData[0]); 
     setImageView(viewHolder.imageView, rowData[1]); 
     return rowView; 
    } 

    private void setImageView(ImageView imageView, String url) { 
     class ImageDownloadHelper extends AsyncTask<String, String, Bitmap> { 
      @Override 
      protected Bitmap doInBackground(String... params) { 
       // TODO Auto-generated method stub 
       URL url; 
       String _url = params[0]; 
       Log.e("url",_url); 

       BufferedOutputStream out; 
       InputStream in; 
       BufferedInputStream buf; 

       try { 
        url = new URL(_url); 
        in = url.openStream(); 
        buf = new BufferedInputStream(in); 

        Bitmap bMap = BitmapFactory.decodeStream(buf); 
        if (in != null) { 
         in.close(); 
        } 
        if (buf != null) { 
         buf.close(); 
        } 
        return bMap; 
       } catch (Exception e) { 
        Log.e("Error reading file", e.toString()); 
       } 
       return null; 
      } 
     } 

     ImageDownloadHelper downloadHelper = new ImageDownloadHelper(); 
     downloadHelper.execute(url); 
     try { 
      imageView.setImageBitmap(downloadHelper.get()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 
相關問題