0

I have an existing ListView from a SQLite database. I want that user can add pictures from their gallery to the listview. These pictures get saved in the internal storage as "*.jpg" where * is the specific row id if a new account gets created.

example: A new entry in the SQLite database gets created with the table (id) number 8. Then if the user has chosen a pictures this gets saved in the internal storage with the name "8.jpg"

My Problem is how I can show that picture in the exact position in the listView... This is my code so far:

edit: (updated code)

private void fillData() {

    mNotesCursor = helper.fetchAllData();

    String[] from = new String[] { MySQLiteHelper.NAME, MySQLiteHelper.PASSWORD,
            MySQLiteHelper.CB_GETREIDE, MySQLiteHelper.CB_FASTENTAG,
            MySQLiteHelper.CB_WOCHENPLAN, MySQLiteHelper.CB_DIET,
            MySQLiteHelper.SP_ART, MySQLiteHelper.PHOTO  };

    int[] to = new int[] { R.id.label, R.id.gewicht, 
            R.id.getreide,
            R.id.fastentag, 
            R.id.wochenplan, 
            R.id.diet, 
            R.id.spinner,
            R.id.imageButton1};


    adapter = new SimpleCursorAdapter(getActivity(),
            R.layout.hundeliste_item, mNotesCursor, from, to, 0);

    mMyListView.setAdapter(adapter);

    adapter.setViewBinder(new SimpleCursorAdapter.ViewBinder(){

           public boolean setViewValue(View view, Cursor cursor, int columnIndex){

               final int id = mNotesCursor.getInt(mNotesCursor.getColumnIndex(MySQLiteHelper.UID));
               LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
               view = inflater.inflate(R.layout.hundeliste_item, null);

               File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
                        + "/Android/data/"
                        + getActivity().getPackageName()
                        + "/Files"); 

               Uri uri = Uri.parse(mediaStorageDir.getPath() + File.separator + id +".jpg");

               Log.v("TEST COMPARISON", "columnIndex=" + columnIndex + "  ID = " + id + "  URI = " + uri); 


// I think here comes my mistake, but I don't know another solution                

if(columnIndex == cursor.getColumnIndex(MySQLiteHelper.PHOTO)) {


                      ((ImageView)view.findViewById(R.id.imageView1)).setImageDrawable(Drawable.createFromPath(uri.toString()));
                      Log.v("Test", "... this Log don't show up, cause columnIndex =/= id");  

                      return true;

               }



                       return false; 
                 }
                }); 

Any help is welcome. Getting crazy with this.. sitting here for a week without solution

edit: (LogOutput)

03-11 12:55:36.784: V/TEST COMPARISON(22456): columnIndex=1  ID = 1  URI = /storage/emulated/0/Android/data/com.example.android.navigationdrawerexample/Files/1.jpg
    03-11 12:55:36.794: V/TEST COMPARISON(22456): columnIndex=2  ID = 1  URI = /storage/emulated/0/Android/data/com.example.android.navigationdrawerexample/Files/1.jpg
    03-11 12:55:36.804: V/TEST COMPARISON(22456): columnIndex=7  ID = 1  URI = /storage/emulated/0/Android/data/com.example.android.navigationdrawerexample/Files/1.jpg
    03-11 12:55:36.814: V/TEST COMPARISON(22456): columnIndex=1  ID = 2  URI = /storage/emulated/0/Android/data/com.example.android.navigationdrawerexample/Files/2.jpg
    03-11 12:55:36.824: V/TEST COMPARISON(22456): columnIndex=2  ID = 2  URI = /storage/emulated/0/Android/data/com.example.android.navigationdrawerexample/Files/2.jpg
    03-11 12:55:36.834: V/TEST COMPARISON(22456): columnIndex=7  ID = 2  URI = /storage/emulated/0/Android/data/com.example.android.navigationdrawerexample/Files/2.jpg
    03-11 12:55:36.844: V/TEST COMPARISON(22456): columnIndex=1  ID = 3  URI = /storage/emulated/0/Android/data/com.example.android.navigationdrawerexample/Files/3.jpg
    03-11 12:55:36.844: V/TEST COMPARISON(22456): columnIndex=2  ID = 3  URI = /storage/emulated/0/Android/data/com.example.android.navigationdrawerexample/Files/3.jpg
    03-11 12:55:36.854: V/TEST COMPARISON(22456): columnIndex=7  ID = 3  URI = /storage/emulated/0/Android/data/com.example.android.navigationdrawerexample/Files/3.jpg
Kroenig
  • 644
  • 7
  • 16
  • Where exactly does your image show up in the ListView? Wrong column or row? – super-qua Mar 11 '14 at 10:59
  • It doesn't show up anywhere. example: https://www.dropbox.com/s/aflski1zg8huq2g/Screenshot_2014-03-10-21-13-43.png – Kroenig Mar 11 '14 at 11:07
  • It might not solve your issue fully, but you have to return `true` to signal the `SimpleCursorAdapter` that your code handled the `setViewValue` – super-qua Mar 11 '14 at 11:11
  • If i return true the listview is empty :/ example: https://www.dropbox.com/s/m8bz8900br51fj1/Screenshot_2014-03-11-12-21-01.png – Kroenig Mar 11 '14 at 11:22
  • 1
    Yes, that is because you're not setting the other content in `setViewValue`. So if you return true for every column, the Adapter thinks the values have already been set, and it doesn't have to do anything. So, first try to sort out the code so you are only handling the `setViewValue` yourself if the `columnIndex` corresponds to your Image (returning `true`), and returning `false` otherwise – super-qua Mar 11 '14 at 11:27
  • Yes I think that's exactly what I'm looking for. Do you have an idea for a code? S.th like `if (..id for every row..) { //code return true }` – Kroenig Mar 11 '14 at 11:34
  • Should be something like `if(columnIndex == cursor.getColumnIndex(MySQLiteHelper.PHOTO)) // do your image processing and return true`. And just return false for the other columns. Again, this might not solve your problem, but it helps us to narrow it down – super-qua Mar 11 '14 at 11:37
  • Thanks for your help! My Log says that the columnIndex is everytime 1, 2 or 7. The ID's (`cursor.getColumnIndex(MySQLiteHelper.PHOTO)`) are good (1,2,3,4 ... ) – Kroenig Mar 11 '14 at 11:43
  • Can you please edit your post with the updated code? Do the other columns show up as expected? – super-qua Mar 11 '14 at 11:44
  • I updated the code. The normal data shows up again but I think this is cause the `if(columnIndex == id)` is false so it goes to return false... – Kroenig Mar 11 '14 at 11:50
  • ok, please also add the log output – super-qua Mar 11 '14 at 11:56
  • Oh ok, I think I got you wrong. So the filename is not stored in the database, but you just load it by using the id of the entry? – super-qua Mar 11 '14 at 12:12
  • yes, that's it. Would it be easier to safe it in the database? I think in the end it doesn't matter? – Kroenig Mar 11 '14 at 12:20

1 Answers1

0

Ok so in your case it would be better to override getView I think, since setViewValue gets called for the columns that are in the cursor, which your image isn't (this way you would override the image with every column, having bad performance).

Here is an example of how to create your view in getView:

EDIT changed to bindView and newView

private void fillData() {

    mNotesCursor = helper.fetchAllData();

    String[] from = new String[] { MySQLiteHelper.NAME, MySQLiteHelper.PASSWORD,
        MySQLiteHelper.CB_GETREIDE, MySQLiteHelper.CB_FASTENTAG,
        MySQLiteHelper.CB_WOCHENPLAN, MySQLiteHelper.CB_DIET,
        MySQLiteHelper.SP_ART, MySQLiteHelper.PHOTO  };

    int[] to = new int[] { R.id.label, R.id.gewicht, 
        R.id.getreide,
        R.id.fastentag, 
        R.id.wochenplan, 
        R.id.diet, 
        R.id.spinner,
        R.id.imageButton1};


    adapter = new MyAdapter(getActivity(),
        R.layout.hundeliste_item, mNotesCursor, from, to, 0);

    mMyListView.setAdapter(adapter);

}


 private class MyAdapter extends SimpleCursorAdapter{

        private Context mContext;
        private int layout;
        private Cursor cursor;
        private final LayoutInflater inflater;

        public MyAdapter(Context context,int layout, Cursor cursor, String[] from, int[] to) {
            super(context,layout,cursor,from,to);
            this.layout=layout;
            this.mContext = context;
            this.inflater=LayoutInflater.from(context);
            this.cursor=cursor;
        }

        @Override
        public View newView (Context context, Cursor cursor, ViewGroup parent) {
                return inflater.inflate(layout, null);
        }

        @Override
        public void bindView(View view, Context context, Cursor cursor) {

            super.bindView(view, context, cursor);

            // Set textviews analogue to this
            TextView name = (TextView) view.findViewById(R.id.label);
            name.setText(cursor.getString(cursor.getColumnIndex(MySQLiteHelper.NAME)));

            // Set the values for other data elements
            // ....

            // Create the imageView
            final int id = cursor.getInt(cursor.getColumnIndex(MySQLiteHelper.UID));
            ImageView imageView = (ImageView) view.findViewById(R.id.imageButton1);

            // load the image from the storage location
            // (a check if the image exists would be nice)
            String mediaStorageFilePath = Environment.getExternalStorageDirectory()
                    + File.separator +"Android"
                    + File.separator +"data"
                    + File.separator + getActivity().getPackageName()
                    + File.separator + "Files"
                    + File.separator + id +".jpg";

            // load the image as a bitmap and set it to the image view
            Bitmap bmp = BitmapFactory.decodeFile(mediaStorageFilePath);
            imageView.setImageBitmap(bmp);

        }
    }
}

I hope this helps.

super-qua
  • 3,148
  • 1
  • 23
  • 30
  • Thanks again for your time. But I have still a problem. the override doesn't work (The annotation @Override is disallowed for this location). I used exactly the code from you. Is this possible because I use `extend Fragments`? Maybe it's a silly question but I'm pretty new to Android and I just started to study IT – Kroenig Mar 11 '14 at 13:42
  • Yes you're right, my mistake. SimpleCursorAdapter is working with `bindView` and `newView`. I edited my post. You can use the `MyAdapter` inner class, which extends the `SimpleCursorAdapter` now. – super-qua Mar 11 '14 at 13:59
  • I changed `c` to `cursor` and removed the `return view;` because of errors. edit: looks good! I have an error while decompiling the pictures from the internal storage – Kroenig Mar 11 '14 at 14:13
  • Sorry, made a stupid mistake when creating the path. It is supposed to be `File.separator`, like in the edited post now. I tried it quickly on a sample project and it worked for me – super-qua Mar 11 '14 at 14:37
  • It works! Awesome! I'm so damn happy right now :D Thanks so much! – Kroenig Mar 11 '14 at 15:15