我正在编写一个用于浏览文件系统的DialogFragment,它现在非常好用。我刚遇到一个问题。
文件显示在ListView中,当用户选择文件时,此事件将发送到通过OnFileSelectedListener-Interface调用片段的Activity。这对于文件来说很好,但是将目录名称发送到活动,然后销毁并重新创建片段会感觉不对,当所有应该发生的事情是片段应该显示新的目录时。它也使整个Fragement消失,然后重新开始,这不是很好,也很顺利。
此外,使用Fragment的每个Activity都必须使用逻辑来重新创建Fragment,这远非“不要重复自己”。
那么,简而言之,有没有办法在片段中更改Listview?不止一次地调用AlertDialog.Builder是不行的。
继承我的DialogFragment。我希望发布完整的内容是可以的:
package de.fusionsystems.firmenlaufmonitor;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class FileChooserFragment extends DialogFragment {
private OnFileSelectedListener mCallback;
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return createDialog();
}
private AlertDialog createDialog(){
// Create the AlertDialog object and return it
SharedPreferences options = PreferenceManager.getDefaultSharedPreferences(getActivity());
ArrayList<File> files = getFilesInDir(options.getString("BaseDir", ""));
ArrayList<ListEntry> fileEntries = new ArrayList<ListEntry>();
if (!isBaseDir(options.getString("BaseDir", ""))){
fileEntries.add(new ListEntry("..", getResources().getDrawable( R.drawable.ic_folder)));
}
for (File file : files){
if (file.isDirectory()){
fileEntries.add(new ListEntry(file.getName(),getResources().getDrawable(R.drawable.ic_folder)));
}else{
if (file.getName().endsWith(".kml")){
fileEntries.add(new ListEntry(file.getName(),getResources().getDrawable( R.drawable.ic_file)));
}
}
}
final FileAdapter adapter = new FileAdapter(getActivity(), fileEntries);
OnClickListener clickListener = new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String path;
SharedPreferences options = PreferenceManager.getDefaultSharedPreferences(getActivity());
if (adapter.getItem(which).name.equals("..")){
//navigate back
path = options.getString("BaseDir", "/");
path=path.substring(0, path.length());
path=path.substring(0,path.lastIndexOf("/"));
path = !path.equals("")?path:("/");
}else {
path = options.getString("BaseDir", "");
path += ((path.equals("/"))?(""):("/"))+adapter.getItem(which).name;
}
Log.d("Path", path);
Editor editor = options.edit();
File dirTest = new File(path);
if (dirTest.isDirectory()){
editor.putString("BaseDir", path);
editor.commit();
//mCallback.onFileSelected("");
//createDialog();
//*******************DO THE RIGHT THING HERE***********************
}else{
mCallback.onFileSelected(path);
}
}
};
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setAdapter(adapter, clickListener)
.setNegativeButton("Abbrechen", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dismiss();
}
});
builder.setTitle("Datei wählen");
return builder.create();
}
private ArrayList<File> getFilesInDir(String dir) {
File folder = new File(dir);
if (!folder.exists()){
folder = new File("/");
if (!folder.exists()){
Log.e("FileBrowser","Something's really fishy");
}
}
ArrayList<File> fileList = new ArrayList<File>(Arrays.asList(folder.listFiles()));
return fileList;
}
private boolean isBaseDir(String dir) {
File folder = new File(dir);
if (!folder.exists()){
folder = new File("/");
if (!folder.exists()){
Log.e("FileBrowser","Something's really fishy");
}
}
File baseDir = new File("/");
if (folder.equals(baseDir)){
return true;
}else{
return false;
}
}
// Container Activity must implement this interface
public interface OnFileSelectedListener {
public void onFileSelected(String file);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (OnFileSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
class ListEntry {
public String name;
public Drawable item ;
public ListEntry(String name, Drawable item) {
this.name = name;
this.item = item;
}
}
class FileAdapter extends ArrayAdapter<ListEntry>{
public FileAdapter(Context context, ArrayList<ListEntry> fileEntry) {
super(context, R.layout.filechooser_list_item,fileEntry);
}
@Override
public View getView(int position, View convertView, ViewGroup parent){
ListEntry entry = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.filechooser_list_item, parent, false);
}
// Lookup view for data population
TextView filechooserEntry = (TextView) convertView.findViewById(R.id.filechooser_entry);
// Populate the data into the template view using the data object
filechooserEntry.setText(entry.name);
filechooserEntry.setCompoundDrawablesWithIntrinsicBounds(entry.item, null, null, null);
// Return the completed view to render on screen
return convertView;
}
}
}
答案 0 :(得分:4)
这是我将Filebrowser作为DialogFragment的解决方案。事实证明,有一些方法可以将()remove()和clean()项添加到适配器,因此初始问题的答案非常简单。棘手的部分是在选择List项后阻止Dialog关闭。这个答案有很多帮助:https://stackoverflow.com/a/15619098/3960095。这是我未来访问者的工作代码:
package de.yourCompany.yourProject;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class FileChooserFragment extends DialogFragment{
private OnFileSelectedListener mCallback;
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Create the AlertDialog object and return it
final FileAdapter adapter = new FileAdapter(getActivity(), new ArrayList<ListEntry>());
adapter.getFiles();
OnClickListener clickListener = new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//do nothing here to prevent dismiss after click
}
};
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setAdapter(adapter, clickListener)
.setNegativeButton("Abbrechen", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
builder.setTitle("Datei wählen");
final AlertDialog theDialog = builder.show();
theDialog.getListView().setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String path;
SharedPreferences options = PreferenceManager.getDefaultSharedPreferences(getActivity());
if (adapter.getItem(position).name.equals("..")){
//navigate back
path = options.getString("BaseDir", "/");
path=path.substring(0, path.length());
path=path.substring(0,path.lastIndexOf("/"));
path = !path.equals("")?path:("/");
}else {
//get the Slashes right and navigate forward
path = options.getString("BaseDir", "");
path += ((path.equals("/"))?(""):("/"))+adapter.getItem(position).name;
}
Editor editor = options.edit();
File dirTest = new File(path);
if (dirTest.isDirectory()){
editor.putString("BaseDir", path);
editor.commit();
adapter.clear();
adapter.getFiles();
}else{
mCallback.onFileSelected(path);
theDialog.dismiss();
}
}
});
return theDialog;
}
private boolean isBaseDir(String dir) {
File folder = new File(dir);
if (!folder.exists()){
folder = new File("/");
if (!folder.exists()){
Log.wtf("FileBrowser","Something's really fishy");
}
}
File baseDir = new File("/");
if (folder.equals(baseDir)){
return true;
}else{
return false;
}
}
// Container Activity must implement this interface
public interface OnFileSelectedListener {
public void onFileSelected(String file);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (OnFileSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
class ListEntry {
public String name;
public Drawable item ;
public ListEntry(String name, Drawable item) {
this.name = name;
this.item = item;
}
}
class FileAdapter extends ArrayAdapter<ListEntry>{
//show only files with the suffix FILE_SUFFIX, use "*" to show all files;
private static final String FILE_SUFFIX = ".kml";
public FileAdapter(Context context, ArrayList<ListEntry> fileEntry) {
super(context, R.layout.filechooser_list_item,fileEntry);
}
@Override
public View getView(int position, View convertView, ViewGroup parent){
ListEntry entry = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.filechooser_list_item, parent, false);
}
// Lookup view for data population
TextView filechooserEntry = (TextView) convertView.findViewById(R.id.filechooser_entry);
// Populate the data into the template view using the data object
filechooserEntry.setText(entry.name);
filechooserEntry.setCompoundDrawablesWithIntrinsicBounds(entry.item, null, null, null);
// Return the completed view to render on screen
return convertView;
}
private FileAdapter getFiles() {
SharedPreferences options = PreferenceManager.getDefaultSharedPreferences(getActivity());
ArrayList<File> files = getFilesInDir(options.getString("BaseDir", ""));
if (!isBaseDir(options.getString("BaseDir", ""))){
this.add(new ListEntry("..", getResources().getDrawable( R.drawable.ic_folder)));
}
for (File file : files){
if (file.isDirectory()){
this.add(new ListEntry(file.getName(),getResources().getDrawable(R.drawable.ic_folder)));
}else{
if (file.getName().endsWith(FILE_SUFFIX)||FILE_SUFFIX.equals("*")){
this.add(new ListEntry(file.getName(),getResources().getDrawable(R.drawable.ic_file)));
}
}
}
return this;
}
private ArrayList<File> getFilesInDir(String dir) {
File folder = new File(dir);
if (!folder.exists()){
folder = new File("/");
if (!folder.exists()){
Log.wtf("FileBrowser","Something's really fishy");
}
}
ArrayList<File> fileList;
if (folder.listFiles()!=null){
fileList = new ArrayList<File>(Arrays.asList(folder.listFiles()));
}else{
fileList = new ArrayList<File>();
}
return fileList;
}
}
}
并在您的活动中:
public class YourActivity extends Activity implements FileChooserFragment.OnFileSelectedListener{
@Override
public void onFileSelected(String file) {
//Do whatever you want to do with the files
}
// And whereever you want to start the Fragment:
FileChooserFragment fileFragment = new FileChooserFragment();
fileFragment.show(getFragmentManager(), "fileChooser");