1

I am creating an app using PHP & Mysql that is displaying custom list view with image, title, description and price in tab fragment.

To achieve this, I have created a ProductTabs class with ItemList AsyncTask inner class this is being used to fetch item details except image download.

ProductTabs Class :

public class ProductTabs extends Fragment {

    HttpHandler httpHandler = new HttpHandler();
    JSONArray items = null;
    ArrayList<HashMap<String,String>> list;
    ProgressDialog progressDialog = null;
    private static String url_products = "";
    private static final String TAG_SUCCESS = "success";
    private static final String TAG_PRODUCTS = "products";
    private static String JSON_PRODUCT_ID = "product_id";
    private static String JSON_PRODUCT_NAME = "product_name";
    private static String JSON_PRODUCT_PRICE = "product_price";
    private static String JSON_PRODUCT_DESC = "product_desc";
    private static String JSON_PRODUCT_URL = "url";
    private static String JSON_PRODUCT_IMAGE = "product_image";

    ListView productList;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View v = inflater.inflate(R.layout.product_tabs, container, false);
        productList = (ListView) v.findViewById(R.id.productList);

        if(this.getTag() == "Popular") {
            url_products = "http://kamalevent.com/cakeshop/products.php";
        } else {
            url_products = "http://kamalevent.com/cakeshop/products.php?sort_by=product_price";
        }

        list = new ArrayList<HashMap<String, String>>();

        new ItemList().execute();
        return v;
    }

    class ItemList extends AsyncTask<String, String, String> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            progressDialog = new ProgressDialog(getActivity());
            progressDialog.setMessage("Fetching Cakelist...");
            progressDialog.setIndeterminate(false);
            progressDialog.setCancelable(false);
            progressDialog.show();
        }

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

            String json = httpHandler.makeHttpRequest(url_products, "GET");
            Log.d("Response :", json);

            if(json != null) {
                try {
                    JSONObject jsonObject = new JSONObject(json);
                    items = jsonObject.getJSONArray(TAG_PRODUCTS);

                    for(int i=0; i < items.length(); i++) {
                        JSONObject product = items.getJSONObject(i);

                        String id = product.getString(JSON_PRODUCT_ID);
                        String name = product.getString(JSON_PRODUCT_NAME);
                        String price = product.getString(JSON_PRODUCT_PRICE);
                        String desc = product.getString(JSON_PRODUCT_DESC);
                        String url = product.getString(JSON_PRODUCT_URL);

                        HashMap<String,String> products = new HashMap<String,String>();
                        products.put(JSON_PRODUCT_ID, id);
                        products.put(JSON_PRODUCT_NAME, name);
                        products.put(JSON_PRODUCT_DESC, desc);
                        products.put(JSON_PRODUCT_PRICE, price);
                        products.put(JSON_PRODUCT_URL, url);

                        list.add(products);

                    }

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

            return null;
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            progressDialog.dismiss();

            ProductAdapter productAdapter = new ProductAdapter(getActivity(), R.layout.item_list, list);
            productList.setAdapter(productAdapter);
            productAdapter.notifyDataSetChanged();
        }
    }



}

Now here is code of custom ProductAdapter that is being to used to create custom list and in this adapter I have created a new inner GetImage AsyncTask class to download image from url.

ProductAdapter Class :

public class ProductAdapter extends ArrayAdapter<HashMap<String, String>> {

    private ArrayList<HashMap<String,String>> products;
    private Context context;
    private View view;
    private int resource;
    private HashMap<String,String> hashMap;

    public ProductAdapter(Context context, int resource, ArrayList<HashMap<String, String>> products) {
        super(context, resource, products);
        this.context = context;
        this.resource = resource;
        this.products = products;
    }

    public class ValueHolder {
        TextView name, desc, price;
        ImageView image;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = layoutInflater.inflate(resource, parent, false);

        ValueHolder valueHolder = new ValueHolder();
        valueHolder.name = (TextView) view.findViewById(R.id.item_title);
        valueHolder.desc = (TextView) view.findViewById(R.id.item_desc);
        valueHolder.price = (TextView) view.findViewById(R.id.item_price);
        valueHolder.image = (ImageView) view.findViewById(R.id.itemImage);

        hashMap = products.get(position);

        valueHolder.name.setText(hashMap.get("product_name"));
        valueHolder.desc.setText(hashMap.get("product_desc"));
        valueHolder.price.setText("Rs. " + hashMap.get("product_price"));
        if(valueHolder.image != null) {
            new GetImage(valueHolder.image).execute(hashMap.get("url"));
        }

        return view;
    }

    class GetImage extends AsyncTask<String, Void, Bitmap> {
        private final WeakReference<ImageView> imageViewWeakReference;

        public GetImage(ImageView imageView) {
            imageViewWeakReference = new WeakReference<ImageView>(imageView);
        }

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

        @Override
        protected Bitmap doInBackground(String... args) {
            URL url = null;
            Bitmap image = null;

            String urlToImage = args[0];

            try {
                Log.d("Image :", urlToImage);
                url = new URL(urlToImage);
                image = BitmapFactory.decodeStream(url.openConnection().getInputStream());
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return image;
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
            if(imageViewWeakReference != null) {
                ImageView imageView = imageViewWeakReference.get();
                if(imageView != null) {
                    if(bitmap != null) {
                        Log.d("Image :", "Image found");
                        imageView.setImageBitmap(bitmap);
                    }
                }
            }
        }
    }

}

Now when I run this app, custom adapter display item list successfully and after some time it shows 3-4 downloaded images not whole images and when I scroll list view, above downloaded images also got disappeared and in logcat GetImage AsyncTask keeps running like infinite process.

So if anyone can suggest me better solution or can tell me what I am doing wrong here would be very helpful for me.

Thanks in Advance.

Ankit
  • 627
  • 1
  • 9
  • 22

1 Answers1

0

Please use Android-Universal-Image-Loader instead of asynctasks for loading images from url.

show below link for that: https://github.com/nostra13/Android-Universal-Image-Loader

Alpha
  • 522
  • 1
  • 5
  • 10