Gridview图像在滚动时更改/随机播放

时间:2014-10-25 08:37:39

标签: android gridview android-arrayadapter

我有自定义arrayadapter的gridview。 在滚动图像时随机播放。我确定适配器有问题。我错过了什么。我已经发布了适配器的代码。

公共类CustomAdapterForDealsGrid扩展了ArrayAdapter {

private  final boolean checkBoxState[] ;

private TCLruCache cache;

Context context;
int layoutResourceId;
private BtnClickListener mClickListener = null;
private OnClickListener clickListner = null;


ArrayList<Ads> data = new ArrayList<Ads>();
Map<String,Bitmap> imageMap = new HashMap<String, Bitmap>();

public CustomAdapterForDealsGrid(Context context, int resource,
        ArrayList<Ads> objects,BtnClickListener listener) {
    super(context, resource, objects);

    ActivityManager am = (ActivityManager) context.getSystemService(
            Context.ACTIVITY_SERVICE);
        int memoryClass = am.getMemoryClass() * 1024 * 1024;
        cache = new TCLruCache(memoryClass);

    this.layoutResourceId = resource;
    this.context = context;
    this.data = objects;
    checkBoxState=new boolean[this.data.size()];

    mClickListener = listener;
    //new GetImageAsync().execute();
}

 private class GetImageAsync extends AsyncTask<Void, Void, Boolean> {

    @Override
    protected Boolean doInBackground(Void... arg0) {

        setImageMap();  
        return null;
    }

 }
public void setImageMap(){
    for(Ads ads : data){
        try {
            imageMap.put("http://"+ApplicationConstant.host+ "/"+ads.getImagepath(),getImageFromUrl("http://"+ApplicationConstant.host+ "/"+ads.getImagepath()));
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

@Override
public int getCount() {
    return data.size();
}

@Override
public Ads getItem(int item) {
    return data.get(item);
}

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




@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    View row = convertView;
    DealHolder holder = null;


    if (row == null) {
        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        row = inflater.inflate(layoutResourceId, parent, false);

        holder = new DealHolder();
        holder.imageItem = (ImageView) row.findViewById(R.id.item_deal);
        holder.txtURL =(TextView) row.findViewById(R.id.item_url);
        holder.txtDesc =(TextView) row.findViewById(R.id.item_desc);
        holder.chkGrid = (CheckBox)row.findViewById(R.id.chkGrid);
        holder.txtPrice =(TextView) row.findViewById(R.id.item_price);

        holder.button = (Button) row.findViewById(R.id.btnDeal);
        holder.button.setTag(Integer.valueOf(position));
        holder.button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                if(mClickListener != null)
                    mClickListener.onBtnClick((Integer)v.getTag());                

            }
        });
        row.setTag(holder);
    } else {
        holder = (DealHolder) row.getTag();
    }

    if(holder.setFlag!=true){
    Ads ads = data.get(position);

    holder.imageItem.setImageResource(R.drawable.powerelectronics);
    holder.txtPrice.setText(ads.getPricerange());
    holder.txtURL.setText(ads.getUrl());
    holder.txtDesc.setText(ads.getDesc());
    holder.chkGrid.setChecked(checkBoxState[position]);
            holder.chkGrid.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {


                           if(((CheckBox)v).isChecked()){
                               checkBoxState[position]=true;
                               data.get(position).setChecked(true);
                           }else{
                               checkBoxState[position]=false;
                               data.get(position).setChecked(false);
                           }

                }

                }
            );

    try {
        if(cache.get("http://"+ApplicationConstant.host+ "/"+ads.getImagepath()) != null){
            holder.imageItem.setImageBitmap(cache.get("http://"+ApplicationConstant.host+ "/"+ads.getImagepath()));
        }
        else{
BitmapFactory.decodeResource(context.getResources(),        R.drawable.abs__activated_background_holo_light));
        setBitmap(holder.imageItem, "http://"+ApplicationConstant.host+ "/"+ads.getImagepath(),ads.getDesc());
        }
        holder.setFlag = true;

    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    }
    return row;

}

static class DealHolder {
    TextView txtPrice,txtURL,txtDesc;
    ImageView imageItem;
    Button button;
    CheckBox chkGrid;
    Boolean setFlag = new Boolean(false);

}


public Bitmap getImageFromUrl(String imgPath) throws Exception{
 HttpGet httpRequest = null;
 URL url = new URL(imgPath);

 httpRequest = new HttpGet(url.toURI());

 HttpClient httpclient = new DefaultHttpClient();
 HttpResponse response = (HttpResponse) httpclient
         .execute(httpRequest);

 HttpEntity entity = response.getEntity();
 BufferedHttpEntity b_entity = new BufferedHttpEntity(entity);
 InputStream input = b_entity.getContent();

 Bitmap bitmap = BitmapFactory.decodeStream(input);
 return bitmap;
}

private Bitmap methodScaledImage(int width,int height,Bitmap origBitmap) throws FileNotFoundException{

Bitmap background = Bitmap.createBitmap((int)width, (int)height, Config.ARGB_8888);
float originalWidth = origBitmap.getWidth(), originalHeight = origBitmap.getHeight();
Canvas canvas = new Canvas(background);
float scale = width/originalWidth;
float xTranslation = 0.0f, yTranslation = (height - originalHeight * scale)/2.0f;
Matrix transformation = new Matrix();
transformation.postTranslate(xTranslation, yTranslation);
transformation.preScale(scale, scale);
Paint paint = new Paint();
paint.setFilterBitmap(true);
canvas.drawBitmap(origBitmap, transformation, paint);
return background;
}



private void setBitmap(final ImageView iv, final String path,final String desc) {

new AsyncTask<Void, Void, Bitmap>() {

    @Override
    protected Bitmap doInBackground(Void... params) {

        Bitmap imageBtMP= null;
        try {
            imageBtMP = getImageFromUrl(path);
            if(imageBtMP!= null){
                cache.put(path, imageBtMP);
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return imageBtMP;
    }

    @Override
    protected void onPostExecute(Bitmap result) {
        super.onPostExecute(result);
        iv.setImageBitmap(result);

        iv.setOnClickListener(new OnClickListener() {


            public void onClick(View v) {


                LayoutInflater layoutInflater = LayoutInflater.from(getContext());
               View popupView = layoutInflater.inflate(R.layout.activity_desc_deal, null);  
                        final PopupWindow popupWindow = new PopupWindow(
                          popupView, 
                          LayoutParams.WRAP_CONTENT,  
                                LayoutParams.WRAP_CONTENT);  

                        final TextView descTextview = (TextView) popupView.findViewById(R.id.descdeal);
                        descTextview.setText(desc);


                        Button btnDismiss = (Button)popupView.findViewById(R.id.dismiss);
                        btnDismiss.setOnClickListener(new Button.OnClickListener(){

                @Override
                public void onClick(View v) {
                 // TODO Auto-generated method stub
                 popupWindow.dismiss();
                }});

                        popupWindow.showAsDropDown(v, 50, -30);


            }
        });

    }
}.execute();
}
private class TCLruCache extends LruCache<String, Bitmap> {


public TCLruCache(int maxSize) {
    super(maxSize);
}
}

}

1 个答案:

答案 0 :(得分:1)

问题与您的setBitmap()方法有关。在整个异步期间,绝对不能保证您传入的ImageViewBitmap中的onPostExecute()相同。这是由于适配器的View回收所致。此外,您必须将ImageView存储为WeakReference。否则你冒险泄漏它。

你的异步应该更像这样:

private class ExampleAsync extends AsyncTask<Void, Void, Bitmap> {
    private WeakReference<ImageView> mImageViewRef;
    private String mPath;
    private String mDesc;

    public ExampleAsync(ImageView iv, String path, String desc) {
        iv.setTag(path);    //Records which path the ImageView represents
        mImageViewRef = new WeakReference<ImageView>(iv);
        mPath = path;
        mDesc = desc;
    }

    @Override
    protected Bitmap doInBackground(Void... params) {
        ImageView iv = mImageViewRef.get();
        if (iv == null || !mPath.equals(iv.getTag())) {
            return null;
        }

        //Retrieve bitmap logic. Return results or null if it fails
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        ImageView iv = mImageViewRef.get();
        if (iv == null || bitmap == null || !mPath.equals(iv.getTag())) {
            //In an invalid state or results had error. Ignore everything and just exit Async.
            return;
        }

        //Received valid results and in good state. Set ImageView and do all your other logic
    }
}

这只是一个粗略的草图,但应该得到重点。这将处理使用适配器和/或在用户滚动期间呈现视图的不同结果。当ImageView被回收并用于其他位置时,记录ImageView标记内的路径。存储在WeakReference中可确保实际销毁ImageView被销毁。否则,您将保留引用并继续加载并在其中放置Bitmap。您始终无效检查引用以确保View未被销毁。使用时,您总是暂时存储在局部变量中以防止它被GC。