beerBear
beerBear

Reputation: 979

Custom List View with Imageview, TextView & a Button as Items

So..I am onto creating a list view in which each row has an Imageview (for previewing an image), a textView and a button (for deleting the image).

Problem:

On click of the item & on button click I am generating a toast which displays the item no.#.

But sometimes the code works correctly and sometimes it just displays the wrong item number.

Update:

I forgot to add that the value shown in the textview is: "flag: #" where # is the current count number of the item. Which I cannot understand always comes correct but not the toast messages which I get :s

Background Working:

There is a button on top of the page through which the user can click photos and when he returns back from camera app the listview gets updated

Code:

public class PicMgr extends ListActivity {

    public String storeID;

    public String date;

    TextView picMsg;

    DBAdapter dbEngine = new DBAdapter(this);

    ProgressDialog PDpicTasker;
    private static final String DATASUBDIRECTORY = "pics";
    private static int TAKE_PICTURE = 1;
    public String fIMGname;
    public static String outletpicpathIO;
    private Uri outputFileUri;
    public String fnameIMG;

    public static String[] imgs;
    public static String[] comments;

    private EfficientAdapter adap;

    public static String[] dataLV;

private void TakePhoto() {


        fIMGname = storeID + "_"+ date;

        dbEngine.open();
        //String fIMGname;
                        int countExistingPics = 0;
                        countExistingPics = dbEngine.getExistingPicNos(storeID);
                        countExistingPics = countExistingPics + 1;
                        fIMGname = fIMGname + "_" +countExistingPics;
                        dbEngine.close();

        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

        File dirORIGimg = new File(Environment.getExternalStorageDirectory(),DATASUBDIRECTORY);
        if (!dirORIGimg.exists()) {
            dirORIGimg.mkdirs();
        }

        //newfilename = "newfilename123";
        File file = new File(dirORIGimg, fIMGname + ".jpg");

        //Toast.makeText(getApplicationContext(), "inside TakePhoto(): "+newfilename, Toast.LENGTH_SHORT).show();

        outputFileUri = Uri.fromFile(file);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
        startActivityForResult(intent, TAKE_PICTURE);

    }

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    System.out.println("GetPic- onActivityResult - resultCode: "+resultCode);

    if (requestCode == TAKE_PICTURE && resultCode == Activity.RESULT_OK) {
        // ShowMessage(outputFileUri.toString());
        //if (data != null) {
            Toast.makeText(getApplicationContext(),outputFileUri.toString(), Toast.LENGTH_SHORT).show();
            System.out.println("outputFileUri.toStr: "+outputFileUri.toString());

            outletpicpathIO = outputFileUri.toString().trim();

            if(!outletpicpathIO.isEmpty()){
                try {
                    new GetCompressedPic().execute().get();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }


        //}
    }

}

    private class GetPicPath extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            Log.i("GetPicPathTasker", "Ready to get start -GetCompressedPic-");

        }

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

            try {
            runOnUiThread(new Runnable() {
                    public void run() {
                        try {
                            TakePhoto(); // get pic
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });




            } catch (Exception e) {
                Log.i("GetPicPathTasker", "GetCompressedPic Failed!", e);
            }

            finally {

                Log.i("GetPicPathTasker", "GetCompressedPic Completed...");
            }
            return null;
        }

        @Override
        protected void onCancelled() {
            Log.i("GetPicPathTasker", "GetCompressedPic Cancelled");
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            Log.i("GetPicPathTasker", "GetCompressedPic cycle completed");

        }
    }

    private class GetCompressedPic extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            Log.i("PicBGtasker", "Ready to get start -GetCompressedPic-");

            PDpicTasker = ProgressDialog.show(PicMgr.this, null, null);
            //PDpicTasker.setContentView(R.layout.loader);
            PDpicTasker.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
        }

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

            try {
                Options opts = new BitmapFactory.Options();
                opts.inSampleSize = 2;   // for 1/2 the image to be loaded
                //Bitmap finalBitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeFile(outletpicpathIO, opts), 640, 480, false);
                System.out.println("outletpicpathIO: "+outletpicpathIO);

                fnameIMG = new File(outletpicpathIO).getAbsolutePath();
                fnameIMG = fnameIMG.replace("/file:", "");
                fnameIMG = fnameIMG.trim();
                System.out.println("fnameIMG: "+fnameIMG);


                Bitmap finalBitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeFile(fnameIMG), 640, 480, false);
                //Bitmap finalBitmap = BitmapFactory.decodeFile(outletpicpathIO);

                dbEngine.open();

                dbEngine.savePicPath(storeID, fnameIMG);
                dbEngine.close();

                ByteArrayOutputStream streamIMG = new ByteArrayOutputStream();
                File dir = new File(Environment.getExternalStorageDirectory(),DATASUBDIRECTORY);
                if (!dir.exists()) {
                    dir.mkdirs();
                }


                String exportFileName = fIMGname+".jpg"; 
                File fileIMG = new File(dir, exportFileName);
                fileIMG.createNewFile();

                finalBitmap.compress(Bitmap.CompressFormat.JPEG, 50, streamIMG);

                FileOutputStream fo = new FileOutputStream(fileIMG);
                fo.write(streamIMG.toByteArray());
                fo.close();

            } catch (Exception e) {
                Log.i("PicBGtasker", "GetCompressedPic Failed!", e);
            }

            finally {

                Log.i("PicBGtasker", "GetCompressedPic Completed...");
            }
            return null;
        }

        @Override
        protected void onCancelled() {
            Log.i("PicBGtasker", "GetCompressedPic Cancelled");
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            Log.i("PicBGtasker", "GetCompressedPic cycle completed");
            PDpicTasker.dismiss();
        }
    }
    // ><

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


        Intent StoreData = getIntent();

        storeID = StoreData.getStringExtra("storeID");

        date = StoreData.getStringExtra("date");

        System.out.println("storeID >> "+storeID);

        picMsg = (TextView)findViewById(R.id.textView1_PicMsg);


        Button outletPic = (Button) findViewById(R.id.Button01_outletpic);
        outletPic.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v2) {

                //TakePhoto(); // get pic

                //async(S)
                try {
                    new GetPicPath().execute().get();
                } catch (InterruptedException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                } catch (ExecutionException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }

            }
        });

        Button saveNcont = (Button) findViewById(R.id.picMgr_saveNcont);
        saveNcont.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v2) {

                /*dbEngine.open();
                dbEngine.savePicPath(storeID, fnameIMG);
                dbEngine.close();*/

                // save comments

            }
        });

         Button backk = (Button) findViewById(R.id.picMgr_back);
         backk.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v2) {

                    finish();

                }
            });


    }

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();

        //

        picMsg.setText("Please Click on \"Take Photograph\" button to start taking Pictures");

        dbEngine.open();
        int maxLIMIT = dbEngine.getExistingPicNos(storeID);

        System.out.println("maxLIMIT existing pics count: "+maxLIMIT);

        if(maxLIMIT > 0){

            imgs = dbEngine.getImgsPath(storeID);
            comments = dbEngine.getImgsComment(storeID);


            dataLV=new String[maxLIMIT];
            for(int limitx = 0; limitx < maxLIMIT; limitx++){

                dataLV[limitx]=""+limitx;
            }


            System.out.println("dataLV:"+dataLV.toString());

            picMsg.setText("Please \"Delete\" non-required Photographs shown below \nor Click on \"Take Photograph\" button to start taking more Pictures");


            adap = new EfficientAdapter(this);
            setListAdapter(adap);

        }


        //
        dbEngine.close();
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        // TODO Auto-generated method stub
        super.onListItemClick(l, v, position, id);
        Toast.makeText(this, "Click-" + String.valueOf(position),
                Toast.LENGTH_SHORT).show();
    }

    public static class EfficientAdapter extends BaseAdapter implements
            Filterable {
        private LayoutInflater mInflater;
        private Bitmap mIcon1;
        private Context context;

        public EfficientAdapter(Context context) {
            // Cache the LayoutInflate to avoid asking for a new one each time.
            mInflater = LayoutInflater.from(context);
            this.context = context;
        }

        /**
         * Make a view to hold each row.
         * 
         * @see android.widget.ListAdapter#getView(int, android.view.View,
         *      android.view.ViewGroup)
         */
        public View getView(final int position, View convertView,
                ViewGroup parent) {
            // A ViewHolder keeps references to children views to avoid
            // unneccessary calls
            // to findViewById() on each row.
            ViewHolder holder;
            // When convertView is not null, we can reuse it directly, there is
            // no need
            // to reinflate it. We only inflate a new View when the convertView
            // supplied
            // by ListView is null.
            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.listview_layout, null);
                // Creates a ViewHolder and store references to the two children
                // views
                // we want to bind data to.
                holder = new ViewHolder();
                holder.textLine = (TextView) convertView
                        .findViewById(R.id.textLine);
                holder.iconLine = (ImageView) convertView
                        .findViewById(R.id.iconLine);

                holder.txt = (EditText) convertView.findViewById(R.id.txt);

                holder.buttonLine = (Button) convertView
                        .findViewById(R.id.buttonLine);

                convertView.setOnClickListener(new OnClickListener() {
                    private int pos = position;

                    @Override
                    public void onClick(View v) {
                        Toast.makeText(context, "Click-" + String.valueOf(pos),
                                Toast.LENGTH_SHORT).show();
                    }
                });
                holder.buttonLine.setOnClickListener(new OnClickListener() {
                    private int pos = position;

                    @Override
                    public void onClick(View v) {
                        Toast.makeText(context,
                                "Delete-" + String.valueOf(pos),
                                Toast.LENGTH_SHORT).show();
                    }
                });

                convertView.setTag(holder);
            } else {
                // Get the ViewHolder back to get fast access to the TextView
                // and the ImageView.
                holder = (ViewHolder) convertView.getTag();
            }
            // Get flag name and id
            String filename = "flag_" + String.valueOf(position);
            /*
             * int id = context.getResources().getIdentifier(filename,
             * "drawable", context.getString(R.string.package_str));
             */

            mIcon1 = BitmapFactory.decodeFile(imgs[position]);

            // Bind the data efficiently with the holder.
            holder.iconLine.setImageBitmap(mIcon1);
            holder.textLine.setText("flag " + String.valueOf(position));

            holder.txt.setText(comments[position]);
            return convertView;
        }

        static class ViewHolder {
            TextView textLine;
            ImageView iconLine;
            EditText txt;
            Button buttonLine;
        }

        @Override
        public Filter getFilter() {
            // TODO Auto-generated method stub
            return null;
        }

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

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

        @Override
        public Object getItem(int position) {
            // TODO Auto-generated method stub
            //String sendBack = PicMgr.dataLV[position];
            return dataLV[position];
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_pic_mgr, menu);
        return true;
    }

}

Any comments/suggestions appreciated..

Upvotes: 0

Views: 215

Answers (2)

bogdan
bogdan

Reputation: 782

  1. The ListView has a method setOnItemClickListener(), you don't have to do convertView.setOnClickListener if you want a listener for the rows.
  2. You are setting listener on that button only when the convert view is null. That means that you won't change the listener when the convertView gets recycled (that is why it's not working well). You should do something like this:

public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = mInflater.inflate(R.layout.listview_layout, null); holder = new ViewHolder(); holder.textLine = (TextView) convertView .findViewById(R.id.textLine); holder.iconLine = (ImageView) convertView .findViewById(R.id.iconLine);

    holder.txt = (EditText) convertView.findViewById(R.id.txt);

    holder.buttonLine = (Button) convertView
            .findViewById(R.id.buttonLine);

    holder.buttonLine.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            Toast.makeText(context,
                    "Delete-" + v.getTag().toString(),
                    Toast.LENGTH_SHORT).show();
        }
    });

    convertView.setTag(holder);
} else {
    // Get the ViewHolder back to get fast access to the TextView
    // and the ImageView.
    holder = (ViewHolder) convertView.getTag();
}
holder.buttonLine.setTag(position);
//rest of the method
return convertView;

}

Upvotes: 1

Muhammad Aamir Ali
Muhammad Aamir Ali

Reputation: 21097

holder.buttonLine.setTag(position);
holder.buttonLine.setOnClickListener(new OnClickListener() {
            private int pos = position;

            @Override
            public void onClick(View v) {
                Toast.makeText(context,"Delete-" + String.valueOf(holder.buttonLine.getTag().toString()),
                Toast.LENGTH_SHORT).show();
            }
       });

Upvotes: 1

Related Questions