0

I was trying to add an icon to the left of each item in a ListView by using the setCompoundDrawablesWithIntrinsicBounds function but keep getting a NullPointerException. I've seen other ways of doing this but was wondering I keep getting this error when trying in this way.

Here is my XML file for each row in the ListView (mediaitems.xml):

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mediatext"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="20sp"
>

Here is the code for browsing the directory of an SD card:

public class SDCardExplorer extends ListActivity {

private String mediapath = new String(Environment.getExternalStorageDirectory().getAbsolutePath());

private List<String> item = null;
private List<String> path = null;

private TextView mypath;
private TextView mediatext;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.medialist);

    mypath = (TextView) findViewById(R.id.mypath);
    mediatext = (TextView) findViewById(R.id.mediatext);

    LoadDirectory(mediapath);
}

// class to limit the choices shown when browsing to SD card to media files
public class AudioFilter implements FileFilter {

    // only want to see the following audio file types
    private String[] extension = {".aac", ".mp3", ".wav", ".ogg", ".midi", ".3gp", ".mp4", ".m4a", ".amr", ".flac"};

    @Override
    public boolean accept(File pathname) {

        // if we are looking at a directory that's not hidden we want to see it so return TRUE           
        if (pathname.isDirectory() && !pathname.isHidden()) {
            return true;
        }

        // loops through and determines the extension of all files in the directory
        // returns TRUE to only show the audio files defined in the String[] extension array
        for (String ext : extension) {
            if (pathname.getName().toLowerCase().endsWith(ext)) {
                return true;
            }
        }

        return false;
    }      
}

private void LoadDirectory(String dirPath) {      

    mypath.setText("Location: " + dirPath);

    item = new ArrayList<String>();
    path = new ArrayList<String>();

    File f = new File(dirPath);
    File[] files = f.listFiles(new AudioFilter());

    // If we aren't in the SD card root directory, add "Up" to go back to previous folder
    if(!dirPath.equals(mediapath)) {

        item.add("Up");
        path.add(f.getParent());
        mediatext.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_upicon, 0, 0, 0);
        //mediatext.setCompoundDrawables(getResources().getDrawable(R.drawable.ic_upicon), null, null, null);
    }

    // Loops through the files and lists them
    for (int i = 0; i < files.length; i++) {
        File file = files[i];
        path.add(file.getPath());

        // Add "/" to indicate you are looking at a folder
        if(file.isDirectory()) {
          item.add(file.getName() + "/");
          mediatext.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_foldericon, 0, 0, 0);
        }
        else {
          item.add(file.getName());
          mediatext.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_audioicon, 0, 0, 0);
        }  
    }

    // Displays the directory list on the screen
    setListAdapter(new ArrayAdapter<String>(this, R.layout.mediaitems, item));
}

Here is the LogCat error:

02-03 13:00:48.295: E/ACRA(8231): iSleep fatal error : Unable to start activity ComponentInfo{com.bromancelabs.isleep/com.bromancelabs.isleep.SDCardExplorer}: java.lang.NullPointerException
02-03 13:00:48.295: E/ACRA(8231): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.bromancelabs.isleep/com.bromancelabs.isleep.SDCardExplorer}: java.lang.NullPointerException
02-03 13:00:48.295: E/ACRA(8231):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
02-03 13:00:48.295: E/ACRA(8231):   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
02-03 13:00:48.295: E/ACRA(8231):   at android.app.ActivityThread.access$2300(ActivityThread.java:125)
02-03 13:00:48.295: E/ACRA(8231):   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
02-03 13:00:48.295: E/ACRA(8231):   at android.os.Handler.dispatchMessage(Handler.java:99)
02-03 13:00:48.295: E/ACRA(8231):   at android.os.Looper.loop(Looper.java:123)
02-03 13:00:48.295: E/ACRA(8231):   at android.app.ActivityThread.main(ActivityThread.java:4627)
02-03 13:00:48.295: E/ACRA(8231):   at java.lang.reflect.Method.invokeNative(Native Method)
02-03 13:00:48.295: E/ACRA(8231):   at java.lang.reflect.Method.invoke(Method.java:521)
02-03 13:00:48.295: E/ACRA(8231):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
02-03 13:00:48.295: E/ACRA(8231):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
02-03 13:00:48.295: E/ACRA(8231):   at dalvik.system.NativeStart.main(Native Method)
02-03 13:00:48.295: E/ACRA(8231): Caused by: java.lang.NullPointerException
02-03 13:00:48.295: E/ACRA(8231):   at com.bromancelabs.isleep.SDCardExplorer.LoadDirectory(SDCardExplorer.java:116)
02-03 13:00:48.295: E/ACRA(8231):   at com.bromancelabs.isleep.SDCardExplorer.onCreate(SDCardExplorer.java:60)
02-03 13:00:48.295: E/ACRA(8231):   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
02-03 13:00:48.295: E/ACRA(8231):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
02-03 13:00:48.295: E/ACRA(8231):   ... 11 more

Thanks for any help anyone can provide.

joelreeves
  • 1,955
  • 1
  • 18
  • 24

2 Answers2

1

Turn the resource into a drawable .... setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.ic_folder_icon), null, null, null);

UPDATE With one possible correct answer:

public class FileListingActivity extends ListActivity {

    private String mediapath = new String(Environment
            .getExternalStorageDirectory().getAbsolutePath());;

    private List<String> item = null;
    private List<String> path = null;

    private TextView mypath;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.medialist);

        mypath = (TextView) findViewById(R.id.mypath);

        LoadDirectory(mediapath);
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        if (new File(path.get(position)).isDirectory()){
            LoadDirectory(path.get(position));
        }
        super.onListItemClick(l, v, position, id);
    }

    // class to limit the choices shown when browsing to SD card to media files
    public class AudioFilter implements FileFilter {

        // only want to see the following audio file types
        private String[] extension = { ".aac", ".mp3", ".wav", ".ogg", ".midi",
                ".3gp", ".mp4", ".m4a", ".amr", ".flac" };

        @Override
        public boolean accept(File pathname) {

            // if we are looking at a directory that's not hidden we want to see
            // it so return TRUE
            if (pathname.isDirectory() && !pathname.isHidden()) {
                return true;
            }

            // loops through and determines the extension of all files in the
            // directory
            // returns TRUE to only show the audio files defined in the String[]
            // extension array
            for (String ext : extension) {
                if (pathname.getName().toLowerCase().endsWith(ext)) {
                    return true;
                }
            }

            return false;
        }
    }

    private void LoadDirectory(String dirPath) {

        mypath.setText("Location: " + dirPath);
        item = new ArrayList<String>();
        path = new ArrayList<String>();

        File f = new File(dirPath);
        File[] files = f.listFiles(new AudioFilter());

        // If we aren't in the SD card root directory, add "Up" to go back to
        // previous folder
        if (!dirPath.equals(mediapath)) {

            item.add("Up");
            path.add(f.getParent());
//          mediatext.setCompoundDrawablesWithIntrinsicBounds(
//                  R.drawable.ic_upicon, 0, 0, 0);
            // mediatext.setCompoundDrawables(getResources().getDrawable(R.drawable.ic_upicon),
            // null, null, null);
        }

        // Loops through the files and lists them
        for (int i = 0; i < files.length; i++) {
            File file = files[i];
            path.add(file.getPath());

            // Add "/" to indicate you are looking at a folder
            if (file.isDirectory()) {
                item.add(file.getName() + "/");
//              mediatext.setCompoundDrawablesWithIntrinsicBounds(
//                      R.drawable.ic_foldericon, 0, 0, 0);
            } else {
                item.add(file.getName());
//              mediatext.setCompoundDrawablesWithIntrinsicBounds(
//                      R.drawable.ic_audioicon, 0, 0, 0);
            }
        }

        // Displays the directory list on the screen
        setListAdapter(new ArrayAdapter<String>(this, R.layout.custom_row_view, item){

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                TextView textView;
                if (convertView == null) {  // if it's not recycled, initialize some  
                    textView = new TextView(FileListingActivity.this);
                } else {
                    textView = (TextView) convertView;
                }
                textView.setText(item.get(position));

                if (item.get(position).equals("Up")){
                    textView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_upicon, 0, 0, 0);
                }else if (new File(path.get(position)).isDirectory()){
                    textView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_foldericon, 0, 0, 0);
                } else {
                    textView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_audioicon, 0, 0, 0);
                }
                return textView;
            }

        });
    }
}
eyespyus
  • 1,576
  • 19
  • 20
  • I still get a NullPointerException. I declared 3 Drawables de fefined them like: Drawable folder. Then in onCreate() defined it as folder = getResources().getDrawable(R.drawable.ic_foldericon); Then tried doing mediatext.setCompoundDrawablesWithIntrinsicBounds(folder, null, null, null); – joelreeves Feb 03 '12 at 23:59
  • actually, it looks like mediatext is null. post the xml file for your list. – eyespyus Feb 04 '12 at 05:23
  • it's posted above. the first block of code i posted. the mediaitems.xml file. – joelreeves Feb 04 '12 at 12:31
  • ok thanks, I did look into this. Anytime that you are changing any aspect of the view inside of the arrayAdapter, the getView() method must be overridden and changes made there. See this note from documentation: "To use something other than TextViews for the array display, for instance, ImageViews, or to have some of data besides toString() results fill the views, override getView(int, View, ViewGroup) to return the type of view you want." start there and look for other answers on what to do inside this method. – eyespyus Feb 04 '12 at 12:58
  • Ah ok. I figured I couldn't do it this way. I'll use the getView method. Thanks. – joelreeves Feb 04 '12 at 13:18
  • This [link](http://androidgenuine.com/?tag=file-browser-android) helped me out a lot. thanks a lot for helping. If I could up-vote I would. :o) – joelreeves Feb 04 '12 at 18:13
0

I ended up using the below code:

My rowlayout.xml for each row in the ListView:

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" >

    <ImageView
        android:id="@+id/icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dip"
        android:layout_marginRight="10dip"
        android:layout_marginTop="5dip"
        android:padding="2dip" >
    </ImageView>

    <TextView
        android:id="@+id/label"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="25sp" >
    </TextView>

</LinearLayout>

Here's my code for the listview:

    public class SDCardExplorer extends ListActivity {

    private String mediapath = new String(Environment.getExternalStorageDirectory().getAbsolutePath());
    private String[] items;

    private List<String> item = null;
    private List<String> path = null;

    private TextView mypath;

    private AlertDialog.Builder alert;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.medialist);

        mypath = (TextView) findViewById(R.id.mypath);

        LoadDirectory(mediapath);
    }

    // class to limit the choices shown when browsing to SD card to media files
    public class AudioFilter implements FileFilter {

        // only want to see the following audio file types
        private String[] extension = {".aac", ".mp3", ".wav", ".ogg", ".midi", ".3gp", ".mp4", ".m4a", ".amr", ".flac"};

        @Override
        public boolean accept(File pathname) {

            // if we are looking at a directory that's not hidden we want to see it so return TRUE           
            if (pathname.isDirectory() && !pathname.isHidden()) {
                return true;
            }

            // loops through and determines the extension of all files in the directory
            // returns TRUE to only show the audio files defined in the String[] extension array
            for (String ext : extension) {
                if (pathname.getName().toLowerCase().endsWith(ext)) {
                    return true;
                }
            }

            return false;
        }      
    }

    // Creates items in the ListView view based on the rowlayout.xml file
    class IconicList extends ArrayAdapter {

        public IconicList() {
            super(SDCardExplorer.this, R.layout.rowlayout, items);
        }

        public View getView(int position, View convertView, ViewGroup parent) {

            View row = convertView;

            // If the convertView is null, run the code below to create a new View
            if (row == null) {
                LayoutInflater inflater = getLayoutInflater();
                row = inflater.inflate(R.layout.rowlayout, parent, false);
            }

            TextView label = (TextView)row.findViewById(R.id.label); 
            ImageView icon = (ImageView)row.findViewById(R.id.icon);

            label.setText(items[position]);

            String s = items[position];

            // Get the file according the position
            File f = new File(path.get(position)); 

            // If looking at a directory
            if (f.isDirectory()) { 
                // If it's the "Home" folder, add the home icon
                if (s.contains("Home")) {
                    icon.setImageResource(R.drawable.ic_sdrooticon);
                }
                // If it's the "Up" folder, add the up icon
                else if (s.contains("Up")) {
                    icon.setImageResource(R.drawable.ic_upicon);
                }
                // Else just add the folder icon
                else {
                    icon.setImageResource(R.drawable.ic_foldericon);
                }
            }
            // Else you're looking at an audio icon, so add the audio icon
            else {
                icon.setImageResource(R.drawable.ic_audioicon);
            }

            return(row);
        }   
    }

    // Loads directory from SD card represented by the String variable dirPath
    private void LoadDirectory(String dirPath) {      

        mypath.setText("Location: " + dirPath);

        item = new ArrayList<String>();
        path = new ArrayList<String>();

        File f = new File(dirPath);
        File[] files = f.listFiles(new AudioFilter());

        // If we aren't in the SD card root directory
        // Add "Home" to go back to the root of the SD card
        // Add "Up" to go back to previous folder
        if(!dirPath.equals(mediapath)) {

            item.add("Home");
            path.add(mediapath);

            item.add("Up");
            path.add(f.getParent());
        }

        // Loops through the files and lists them
        for (int i = 0; i < files.length; i++) {
            File file = files[i];
            path.add(file.getPath());

            // Add "/" to indicate you are looking at a folder
            if(file.isDirectory()) {
              item.add(file.getName() + "/");
            }
            else {
              item.add(file.getName());
            }  
        }

        //declare array with specific number off item
        items = new String[item.size()]; 
        //send data arraylist(item) to array(items)
        item.toArray(items); 
        //sets the list with icon
        setListAdapter(new IconicList()); 
    } 
}
joelreeves
  • 1,955
  • 1
  • 18
  • 24