Wednesday, July 11, 2012

Sort directory/file in alphabetical order ignore case

Last exercise of "File Explorer" list file/directory without order. We can implement Comparator<? super File> to sort the directory/file in alphabetical order. We can also convert the file name to lower case before comparing, such that the array will be sorted in alphabetical order ignore case.

Sort directory/file in alphabetical order ignore case


Modify MainActivity.java from last exercise "File Explorer".
package com.example.androidexplorer;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

import android.os.Bundle;
import android.os.Environment;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends ListActivity {
 
 private List<String> item = null;
 private List<String> path = null;
 private String root;
 private TextView myPath;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myPath = (TextView)findViewById(R.id.path);
        
        root = Environment.getExternalStorageDirectory().getPath();
        
        getDir(root);
    }
    
    private void getDir(String dirPath)
    {
     myPath.setText("Location: " + dirPath);
     item = new ArrayList<String>();
     path = new ArrayList<String>();
     File f = new File(dirPath);
     File[] files = f.listFiles();
     
     if(!dirPath.equals(root))
     {
      item.add(root);
      path.add(root);
      item.add("../");
      path.add(f.getParent()); 
     }
     
     Arrays.sort(files, filecomparator);
     
     for(int i=0; i < files.length; i++)
     {
      File file = files[i];
      
      if(!file.isHidden() && file.canRead()){
       path.add(file.getPath());
          if(file.isDirectory()){
           item.add(file.getName() + "/");
          }else{
           item.add(file.getName());
          }
      } 
     }

     ArrayAdapter<String> fileList =
       new ArrayAdapter<String>(this, R.layout.row, item);
     setListAdapter(fileList); 
    }
    
    Comparator<? super File> filecomparator = new Comparator<File>(){
  
  public int compare(File file1, File file2) {

   if(file1.isDirectory()){
    if (file2.isDirectory()){
     return String.valueOf(file1.getName().toLowerCase()).compareTo(file2.getName().toLowerCase());
    }else{
     return -1;
    }
   }else {
    if (file2.isDirectory()){
     return 1;
    }else{
     return String.valueOf(file1.getName().toLowerCase()).compareTo(file2.getName().toLowerCase());
    }
   }
    
  }  
 };

 @Override
 protected void onListItemClick(ListView l, View v, int position, long id) {
  // TODO Auto-generated method stub
  File file = new File(path.get(position));
  
  if (file.isDirectory())
  {
   if(file.canRead()){
    getDir(path.get(position));
   }else{
    new AlertDialog.Builder(this)
     .setIcon(R.drawable.ic_launcher)
     .setTitle("[" + file.getName() + "] folder can't be read!")
     .setPositiveButton("OK", null).show(); 
   } 
  }else {
   new AlertDialog.Builder(this)
     .setIcon(R.drawable.ic_launcher)
     .setTitle("[" + file.getName() + "]")
     .setPositiveButton("OK", null).show();

    }
 }

}


Download the files.

Next:
- Sort directory/file in order of lastModified time


4 comments:

Anonymous said...

Thank you. It was really helpful :)

Anonymous said...

When I do the comparator part and type the return String.valueOf , the compiler errors on the fact that the return is not an integer. As the public int compare method requires a return value of an integer.

How did you get this to work?

thanks

Erik said...

hello,

Please check your parentheses, the return statement become String.compareTo(String), it's int.

TCS said...

Thanks for that , looks like I was not paying attention when I was viewing your example.

TCS