Question

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.

Was it helpful?

Solution 2

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()); 
    } 
}

OTHER TIPS

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;
            }

        });
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top