0

我正在编写一个用于浏览文件系统的 DialogFragment,它现在非常好用。我刚遇到一个问题。

文件显示在 ListView 中,当用户选择文件时,此事件将发送到通过 OnFileSelectedListener-Interface 调用 Fragment 的 Activity。这对文件来说很好,但是将目录名称发送到活动,然后销毁并重新创建片段,当所有应该发生的事情是片段应该显示一个新目录时,感觉是错误的。它也使整个 Fragment 消失然后重新出现,这不是很流畅。

此外,每个使用 Fragment 的 Activity 都必须使用重新创建 Fragment 的逻辑,这与“不要重复自己”相去甚远。

所以,简而言之,有没有办法在 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;
        }   
    }
}
4

1 回答 1

4

这是我将 Filebrowser 作为 DialogFragment 的解决方案。事实证明,有一些方法可以将 add() remove() 和 clean() 项添加到适配器,因此最初问题的答案非常简单。棘手的部分是防止对话框在选择列表项后关闭。这个答案很有帮助: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"); 
于 2014-09-08T13:04:23.837 回答