customAdapter无法正常工作与异步图像下载
问题描述:
嘿家伙我试图创建一个自定义列表视图与图像来自一个URL的文本和图像。我正试图与我的列表项异步显示它们。但是当我向下滚动列表时,列表项中的图像发生更改,并且列表项中显示错误的图像。下面是我的代码片段:customAdapter无法正常工作与异步图像下载
CustomList.java, 它implimenting我底座适配器
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);
}
}
}
}
}
ListItem.java那就是为listView中的每一行生成我的数据
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>
答
这是一个常见的错误。您的listView可以回收视图,所以不会为listView中的100个项目创建视图,而只是创建足够的空间来填充屏幕。
当你向下滚动,这是用于位置#1 ImageView的,是现在被用于位置#11相同的ImageView和#21,等等...
的修复需要跟踪什么当前正在向用户显示位置,并且仅为这些位置设置图像,并且当它从屏幕上脱落时清除相关联的图像视图(或取消未决下载)。
您可以计算出您的imageView被重新分配的时间,因为它将在getView中被再次调用,并且从那里您可以确定是否有需要取消的挂起下载。
考虑使用现有的解决方案之一,或只是检查其他人如何完成一个完整的示例。 https://github.com/nostra13/Android-Universal-Image-Loader
y是否使用BaseAdapter使用ArrayAdapter
您正在使用哪个图像下载你可以尝试滑翔或毕加索非常轻的重量和工作正常 – sector11