0

目前,我正在尝试在 Android 上创建一个文件管理器应用程序,使用片段以方便以后使用。像我一样缺乏经验,我往往会遇到问题,我无法弄清楚这个最新的问题。应用程序的力量在我启动它的那一刻就关闭了。我正在运行 Galaxy Nexus,以防有人想知道。

我在这里使用了一个 Item 类,它基本上只是实例变量和 get/set 方法。

主要活动:

package tj.apps.files;

import java.io.File;
import java.util.ArrayList;

import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.widget.ImageView;

import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;

public class FilesList extends SherlockFragmentActivity implements ListFragment.listFragmentListener {

    // Constructors
    private ItemAdapter aa;
    private ArrayList<Item> array;
    private String extMountState = Environment.getExternalStorageState();
    private String rootPath; 
    private ArrayList<Item> items;
    private FragmentManager fm; 
    private FragmentTransaction ft; 
    private ListFragment listFragment; 


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


        // Set up FragmentManager and FragmentTransaction
        fm = getSupportFragmentManager();
        ft = fm.beginTransaction();

        // Comments below is code that doesn't work, as it returns false always on my Galaxy Nexus
        /*
        // Checking whether or not external storage is mounted or not
        // If it isn't mounted, then an ErrorFragment is shown, which is an
        // ImageView saying media isn't mounted and to restart app once it is.
        if (!(extMountState == (Environment.MEDIA_MOUNTED))) {
            ft.add(R.id.container_fragment_listview, new ErrorFragment());
            ft.commit();

        // If it is mounted, the files are retrieved using getFileDirectory,
        // the ListFragment is loaded and set with the ItemAdapter.
        } else {
        */


            File file = Environment.getExternalStorageDirectory();
            rootPath = file.getPath();
            listFragment = new ListFragment();
            ft.add(R.id.container_fragment_listview, listFragment);
            ft.commit();
            listFragment.getFileDir(rootPath);

        }


    @Override
    public boolean onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu) {
        MenuInflater inflater = getSupportMenuInflater();
        inflater.inflate(R.menu.files_list, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menu_search:
            return true;
        case R.id.menu_edit_mode:
            return true;
        case R.id.menu_help:
            return true;
        case R.id.menu_about:
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public void addNewFragment(String path) {
        ListFragment other = new ListFragment(); 
        ft.replace(R.id.container_fragment_listview, other);
        ft.addToBackStack(null);
        ft.commit(); 
        other.getFileDir(path);
    }

}

列表片段:

package tj.apps.files;

import java.io.File;
import java.util.ArrayList;

import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;

import com.actionbarsherlock.app.SherlockListFragment;

public class ListFragment extends SherlockListFragment {

    // constructors
    private ArrayList<Item> items;
    private ItemAdapter adapter;
    private listFragmentListener lfListener;

    // Get reference to interface in Activity
    @Override
    public void onAttach(Activity activity) {
        // TODO Auto-generated method stub
        super.onAttach(activity);
        try { 
            lfListener = (listFragmentListener) activity; 
        } catch (ClassCastException e) { 
            throw new ClassCastException (activity.toString() + "must implement listFragmentListener"); 
        }
    }

    // Inflate custom list at R.layout.fragment
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        return inflater.inflate(R.layout.list_fragment, container, false);
    }

    // Method to create ListFragment from storage path
    public void getFileDir(String path) {

        // Get the File using the 'path' parameter, then gets the directory at
        // that path, while also initializing the 'items' ArrayList
        File f = new File(path);
        File[] files = f.listFiles();
        items = new ArrayList<Item>();

        // Loops through File[], gets the File at the current position in the
        // File[], gets name/extension/path and puts them to strings,
        // Creates a new Item using those. Those are then added to the 'items'
        // ArrayList
        for (int i = 0; i < files.length; i++) {
            File file = files[i];
            String name = file.toString();
            String filePath = file.getPath();
            String extension;

            // If it's a file, then grab the file's extensions (.jpg, .txt,
            // ex.). If it's a folder, get the length of the directory.
            if (file.isFile() == true) {
                extension = name.substring(name.lastIndexOf('.') + 1);
            } else {
                extension = Integer.toString(files[i].listFiles().length)
                        + "files";
            }
            items.add(new Item(name, extension, filePath));
        }

        // initializes ItemAdapter using 'items' and the custom row layout and
        // grabbing the activity this fragment is attached to. Then sets it.
        adapter = new ItemAdapter(getActivity(), R.layout.list_item, items);
        setListAdapter(adapter);
    }

    // On list item click, we check if the file at the position is a folder or not. If it is, we call the listener. 
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        File file = new File (items.get(position).getPath());
        if (file.isDirectory()) {
            lfListener.addNewFragment(items.get(position).getPath());
        }

    }

    //Listener to communicate with Activity it is attached to. Meant to create a new Fragment. 
    public interface listFragmentListener {
        public void addNewFragment(String path);
    }

}

日志猫:

11-25 22:29:19.549: E/AndroidRuntime(12077): FATAL EXCEPTION: main
11-25 22:29:19.549: E/AndroidRuntime(12077): java.lang.RuntimeException: Unable to start activity ComponentInfo{tj.apps.files/tj.apps.files.FilesList}: java.lang.NullPointerException
11-25 22:29:19.549: E/AndroidRuntime(12077):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
11-25 22:29:19.549: E/AndroidRuntime(12077):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
11-25 22:29:19.549: E/AndroidRuntime(12077):    at android.app.ActivityThread.access$600(ActivityThread.java:130)
11-25 22:29:19.549: E/AndroidRuntime(12077):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
11-25 22:29:19.549: E/AndroidRuntime(12077):    at android.os.Handler.dispatchMessage(Handler.java:99)
11-25 22:29:19.549: E/AndroidRuntime(12077):    at android.os.Looper.loop(Looper.java:137)
11-25 22:29:19.549: E/AndroidRuntime(12077):    at android.app.ActivityThread.main(ActivityThread.java:4745)
11-25 22:29:19.549: E/AndroidRuntime(12077):    at java.lang.reflect.Method.invokeNative(Native Method)
11-25 22:29:19.549: E/AndroidRuntime(12077):    at java.lang.reflect.Method.invoke(Method.java:511)
11-25 22:29:19.549: E/AndroidRuntime(12077):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
11-25 22:29:19.549: E/AndroidRuntime(12077):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
11-25 22:29:19.549: E/AndroidRuntime(12077):    at dalvik.system.NativeStart.main(Native Method)
11-25 22:29:19.549: E/AndroidRuntime(12077): Caused by: java.lang.NullPointerException
11-25 22:29:19.549: E/AndroidRuntime(12077):    at android.widget.ArrayAdapter.init(ArrayAdapter.java:310)
11-25 22:29:19.549: E/AndroidRuntime(12077):    at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:153)
11-25 22:29:19.549: E/AndroidRuntime(12077):    at tj.apps.files.ItemAdapter.<init>(ItemAdapter.java:21)
11-25 22:29:19.549: E/AndroidRuntime(12077):    at tj.apps.files.ListFragment.getFileDir(ListFragment.java:73)
11-25 22:29:19.549: E/AndroidRuntime(12077):    at tj.apps.files.FilesList.onCreate(FilesList.java:58)
11-25 22:29:19.549: E/AndroidRuntime(12077):    at android.app.Activity.performCreate(Activity.java:5008)
11-25 22:29:19.549: E/AndroidRuntime(12077):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
11-25 22:29:19.549: E/AndroidRuntime(12077):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
11-25 22:29:19.549: E/AndroidRuntime(12077):    ... 11 more

我还在学习,我有点坚持解决这个问题。这是我正在尝试做的事情:

在 Main Activity 中,我尝试检查 SDCard 是否已安装,如果是,则会弹出 ErrorFragment。如果没有,我初始化一个 ListFragment,将它添加到 Main Activity 的 xml 中的容器中,然后在添加的 Fragment 上调用 ListFragment 方法之一。方法 getFileDir 基本上使用在 getFileDir 中用作参数的路径获取文件数组。然后,它使用 for 循环从数组中的每个文件中获取名称、扩展名和路径,创建一个新项目并将其添加到“项目”ArrayList 中。在循环之后,我使用自定义行布局(我测试为工作)初始化阵列适配器,使用'getActivity()'和'items'ArrayList 附加活动的上下文。然后我调用 setListAdapter。

编辑: Nandesh 知道了,它现在可以工作了。只是有另一个问题。我的列表项不可点击。这可能是我的 ItemAdapter 代码,如下所示:

package tj.apps.files;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class ItemAdapter extends ArrayAdapter<Item> {

int resource; 
Context context;
ArrayList<Item> items;

    public ItemAdapter(Context context, int resource, ArrayList<Item> items) {
        super(context, resource, items);
        this.resource = resource;
        this.context = context;
        this.items = items;
    }

    @Override
        public View getView(int position, View convertView, ViewGroup parent) {
        ItemHolder holder = null;

        if (convertView == null) {
            LayoutInflater inflater = ((Activity) context).getLayoutInflater();
            convertView = inflater.inflate(resource, parent, false);

            holder = new ItemHolder();

            convertView.setClickable(true);
            convertView.setFocusable(true);

            holder.text = (TextView) convertView.findViewById(R.id.item_text);
            holder.subtext= (TextView) convertView.findViewById(R.id.item_subtext);

            convertView.setTag(holder);

        } else {
            holder = (ItemHolder) convertView.getTag();
        }

        holder.text.setText(items.get(position).getName());
        holder.subtext.setText(items.get(position).getType());

        return convertView;
    }

    static class ItemHolder {
        ImageView image;
        TextView text;
        TextView subtext;
    }
}
4

1 回答 1

1

getActivity() 在您的情况下返回 null 。如果 ListFragment 尚未附加到 Activity,则它可以为 null。

所以将下面的代码移动到 OnAttach

   adapter = new ItemAdapter(getActivity(), R.layout.list_item, items);
   setListAdapter(adapter);
于 2012-11-26T06:56:55.110 回答