現在、後で便利なようにフラグメントを使用して、Androidでファイルマネージャーアプリを作成しようとしています。私は経験が浅いので、問題にぶつかる傾向があり、この最新のものを理解することはできません。アプリフォースは、起動した瞬間に閉じます。誰かが知りたがっている場合に備えて、私はGalaxyNexusを実行しています。
ここで使用している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);
}
}
ListFragment:
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);
}
}
Logcat:
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
私はまだ学んでいます、そして私はこれを修正することにちょっと立ち往生しています。これが私がやろうとしていることです:
メインアクティビティでは、SDカードがマウントされているかどうかを確認しようとしています。マウントされている場合は、ErrorFragmentがポップアップします。そうでない場合は、ListFragmentを初期化し、それをMain Activityのxmlのコンテナーに追加してから、追加されたFragmentでListFragmentメソッドの1つを呼び出します。メソッドgetFileDirは、基本的に、getFileDirで引数として使用されたパスを使用してファイルの配列を取得します。次に、forループを使用して配列内の各ファイルから名前、拡張子、パスを取得し、新しいアイテムを作成して「items」ArrayListに追加します。ループの後、カスタム行レイアウト(動作しているとテストした)を使用して配列アダプターを初期化し、「getActivity()」を使用してアタッチされたアクティビティのコンテキストを初期化し、「items」ArrayListを使用します。次に、setListAdapterを呼び出します。
編集: ナンデシュはそれを手に入れました、それは今働きます。別の問題があります。私のリストアイテムはクリックできません。これはおそらく私の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;
}
}