customAdapter与异步映像下载无法正常工作

时间:2016-01-23 11:34:27

标签: android

嘿伙计们我正在尝试使用文本和图像创建自定义列表视图,其中图像来自网址。我试图与我的列表项异步显示它们。但是当我向下滚动列表时,列表项中的图像会发生变化,而错误的图像会显示在列表项中。以下是我的代码段:

CustomList.java 下, 这是我的基础适配器

public class CustomList extends BaseAdapter {

    //private ArrayList listData;
    private LayoutInflater layoutInflater;
    private ArrayList<ListItem> listData;

    public CustomList(Context context,ArrayList<ListItem> listData)
    {

        //Toast.makeText(History.this,"hey",Toast.LENGTH_LONG).show();
        this.listData = listData;
        layoutInflater = LayoutInflater.from(context);
    }




    @Override
    public int getCount() {
        Log.e("mysize",String.valueOf(listData.size()));
        return listData.size();
    }

    @Override
    public Object getItem(int position) {
        return listData.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }


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

        ViewHolder holder;
        if(convertView == null)
        {
            convertView = layoutInflater.inflate(R.layout.history_row,null);
            holder = new ViewHolder();
            holder.so = (TextView)convertView.findViewById(R.id.SO);
            holder.name = (TextView)convertView.findViewById(R.id.Name);
            holder.process = (ImageView)convertView.findViewById(R.id.Process);
            holder.cloth = (ImageView)convertView.findViewById(R.id.Cloth);
            convertView.setTag(holder);

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

        ListItem data = (ListItem)listData.get(position);

        holder.so.setText(data.getSo());

        if(data.getProcess().equals("0"))
        {
            holder.process.setImageResource(R.drawable.tick);
        }
        else
        holder.process.setImageResource(android.R.drawable.ic_delete);
        if(holder.cloth !=null)
        {
            holder.name.setText(data.getName());
            Log.e("urlsss",data.getUrl()+ data.getName());
            new ImageDownload(holder.cloth).execute(data.getUrl());
        }

        return convertView;


    }

    static class ViewHolder
    {
        TextView so;
        TextView name;
        ImageView process;
        ImageView cloth;
    }


}
用于下载图片的

ImageDownload.class

public class ImageDownload extends AsyncTask<String,Void,Bitmap> {
    private final WeakReference<ImageView> imageViewReference;

    public ImageDownload(ImageView imageView)
    {
        imageViewReference = new WeakReference<ImageView>(imageView);
    }

    protected Bitmap doInBackground(String... params)
    {
        RequestHandler rh = new RequestHandler();
        return rh.downloadBitmap(params[0]);

    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (isCancelled()) {
            bitmap = null;
        }

        if (imageViewReference != null) {
            ImageView imageView = imageViewReference.get();
            if (imageView != null) {
                if (bitmap != null) {
                    imageView.setImageBitmap(bitmap);
                } else {
                    Drawable placeholder = imageView.getContext().getResources().getDrawable(android.R.drawable.star_on);
                    imageView.setImageDrawable(placeholder);
                }
            }
        }
    }
}
为listView中的每一行生成数据的

ListItem.java

public class ListItem {

    private String so,name,process,imgUrl;

    public void setSo(String so)
    {
        this.so = so;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public void setProcess(String process)
    {
        this.process = process;
    }

    public void setUrl(String url)
    {
        this.imgUrl = url;
    }

    public String getSo()
    {
        return so;
    }

    public String getName()
    {
        return name;
    }

    public String getProcess()
    {
        return process;
    }

    public String getUrl()
    {
        return imgUrl;    }
}

这是我调用自定义适配器的主要活动

public class History extends AppCompatActivity {

    //url to fetch data from
    public static final String URL_HISTORY = "http://192.168.1.233/vendor/history.php";

    //Json tags
    public static final String TAG_JSON_ARRAY="result";
    public static final String TAG_SO = "SO";
    public static final String TAG_NAME = "CustomerName";
    public static final String TAG_DESC = "ClothDescription";
    public static final String TAG_DATE = "DeliveryDate";
    public static final String TAG_PRODUCT_TYPE = "ProductType";
    public static final String TAG_PRODUCT_DESC = "ProductDescription";
    public static final String TAG_IMAGE_URL = "ImageUrl";
    public static final String TAG_PROCESS = "Process";



   HashMap<String,String> data = new HashMap<>();
    ArrayList<ListItem> detail_list;
    ListView listView;


    //key to put in hashmap
    public static final String VENDOR_NAME = "Username";


    //to store fetched data
    String[] so;
    String[] customerName;
    String[] clothesDesc;
    String[] delivDate;
    String[] prodType;
    String[] prodDesc;
    String[] imgUrl;
    String[] process;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_history);

        listView =(ListView)findViewById(R.id.listView);
        detail_list = new ArrayList<ListItem>();

        //to get vendorname
        SharedPreferences sharedPref = getSharedPreferences("vendorInfo", Context.MODE_PRIVATE);
        String vendor_name =sharedPref.getString("username", "");
        data.put(VENDOR_NAME, vendor_name);

        fetchHistory();


    }


    public void fetchHistory()
    {
        class FetchHistory extends AsyncTask<Void,Void,String>
        {
            ProgressDialog loading;
            protected void onPreExecute()
            {
                super.onPreExecute();
                loading = ProgressDialog.show(History.this,"Fetching...","Wait",false,false);
            }
            protected String doInBackground(Void...params)
            {
                RequestHandler rh = new RequestHandler();
                String result = rh.sendPostRequest(URL_HISTORY, data);
                return result;
            }

            protected void onPostExecute(String s)
            {
                super.onPostExecute(s);
                loading.dismiss();
                Log.e("myjson",s);
                showHistory(s);
            }
        }

        FetchHistory fh = new FetchHistory();
        fh.execute();
    }

    public void showHistory(String json)

    {


        try {
            JSONObject jsonObject = new JSONObject(json);
            JSONArray result = jsonObject.getJSONArray(TAG_JSON_ARRAY);
            int length = result.length();
            so = new String[length];
            customerName = new String[length];
            clothesDesc = new String[length];
            delivDate = new String[length];
            prodType = new String[length];
            prodDesc = new String[length];
            imgUrl = new String[length];
            process = new String[length];
            for (int i = 0; i < result.length(); i++) {
                JSONObject c = result.getJSONObject(i);
                so[i] = c.getString(TAG_SO);
                customerName[i] = c.getString(TAG_NAME);
                clothesDesc[i] = c.getString(TAG_DESC);
                delivDate[i] = c.getString(TAG_DATE);
                prodType[i] = c.getString(TAG_PRODUCT_TYPE);
                prodDesc[i] = c.getString(TAG_PRODUCT_DESC);
                imgUrl[i] = c.getString(TAG_IMAGE_URL);
                process[i] = c.getString(TAG_PROCESS);

            }
        }
            catch(JSONException e)
            {
                Log.e("myexception",e.toString());
            }


            for(int i =0;i<customerName.length;i++)
            {
                //storing all value in hashmap
                ListItem values = new ListItem();
                values.setSo(so[i]);
                values.setName(customerName[i]);
                values.setUrl(imgUrl[i]);
                Log.e("myurl", imgUrl[i]);
                values.setProcess(process[i]);

                detail_list.add(values);
            }




                Toast.makeText(this,"hey",Toast.LENGTH_LONG).show();
                Log.e("hey", "hey00");


        CustomList customList = new CustomList(this,detail_list);
        listView.setAdapter(customList);
        Toast.makeText(this,"you",Toast.LENGTH_LONG).show();
        Log.e("you", "you00");
    }


}

每行的布局文件是

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:id="@+id/linear">

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:id="@+id/SO"
            android:layout_marginRight="10dp"
            android:layout_weight="2" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:id="@+id/Name"
            android:layout_marginRight="10dp"
            android:layout_weight="2" />

        <ImageView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:id="@+id/Process"
            android:layout_weight="1" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">


        <ImageView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:id="@+id/Cloth"
            android:layout_weight="1"
            android:scaleType="fitXY" />
    </LinearLayout>
</LinearLayout>

1 个答案:

答案 0 :(得分:0)

这是一个常见的错误。您的listView会回收视图,因此不会为listView中的100个项目创建视图,而是创建足够的视图来填充屏幕。

向下滚动时,用于位置#1的ImageView现在与用于位置#11和#21的ImageView相同,依此类推......

此修复程序需要跟踪当前正在向用户显示的位置,并且仅设置这些位置的图像,并在其从屏幕上掉落时清除关联的图像视图(或取消挂起的下载)。

你可以弄清楚你的imageView何时被重新分配,因为它将再次在getView中被调用,你可以从中找出是否有需要取消的待处理下载。

考虑使用其中一个现有解决方案,或者只是查看其他人如何完成它的完整示例。 https://github.com/nostra13/Android-Universal-Image-Loader