如何从 DialogFragment 列表中获取用户对文件的选择

How to get the user's choice of File, back from a DialogFragment list

我已经广泛阅读了 S/O 上的各种答案以寻找解决我的问题的方法,但现在似乎在兜圈子,因为似乎没有我已经能够用来解决我的问题的任何一致的 DialogFragment (DF) 创建和处理方法。

我是运行单身activity,有很多普通片段。我创建了一个 DF 来处理我希望用户从中选择一个文件的列表,然后将其导入(到 SQLite 数据库文件中)。 我正在通过以下代码从我的 MainActivity 创建 DF(通过在普通片段中单击按钮发起):-

public void importdb(View view) {



    NewFileChooser newFileChooser = new NewFileChooser();
    newFileChooser.setTargetFragment(newFileChooser, FILE_CHOOSER);
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    ft.addToBackStack(null);
    newFileChooser.show(ft, "Diag");
}

在 'NewFileChooser' 中,DF 在 OnCreateView 方法中创建:-

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.new_layout, container, false);
    list = (ListView)view.findViewById(R.id.file_list);
    Context c = getActivity();
    currentDir = new File("/sdcard/PH100-Backup");
    fill(currentDir);
    Dialog mydialog = getDialog();
    mydialog.setTitle("Choose a database File to Import");

    //list.setOnClickListener(???????????); // position to set listener ??

    return view;
 }

下面显示的'fill(currentDir)'方法使用了2个额外的类,使用ArrayAdapter方式从sdcard/backup目录中获取文件并在DF的列表区域中显示这个排序列表。
这部分工作正常,DF 已创建并显示列表,如果您单击列表中的任何文件,背景会变亮,表明您正在开始事件,但这是我所能得到的。

private void fill(File f) {
    File[] dirs = f.listFiles();
    getDialog().setTitle("Current Dir: " + f.getName());
    List<Option> dir = new ArrayList<Option>();
    List<Option> fls = new ArrayList<Option>();
    try {
        for (File ff : dirs) {
            if (ff.isDirectory())
            dir.add(new Option(ff.getName(), "Folder", ff.getAbsolutePath()));
            else {
                fls.add(new Option(ff.getName(), "File Size: " + ff.length(), ff.getAbsolutePath()));
            }
        }
    } catch (Exception e) {

    }
    Collections.sort(dir);
    Collections.sort(fls);
    dir.addAll(fls);
    if (!f.getName().equalsIgnoreCase("sdcard"))
    adapter = new FileArrayAdapter(getActivity(), R.layout.file_view, dir);
    list.setAdapter(adapter);
}

代码主要摘自 'ticked' 答案 File Chooser inside DialogFragment (re-using code)

我已经根据我的情况修改了它并且它有效,但仅限于我上面提到的。 通过阅读 S/O 上的许多现有答案,我不确定自己是否已陷入困境。许多答案都有与它们相关联的听众使用的按钮,我没有这些按钮,因此无法使用他们的代码(特别是在听众上)来解决我的问题,其他人使用 [=33= 启动 DF ] -- AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); -- 我没有使用的代码结构。 (我确实尝试过使用这种方法,但是 .setItems 动词不喜欢我动态构建的文件列表,它只需要一个固定的数组,但我无法让它工作)。

显然我需要使用侦听器接口作为将文件名返回给 MainActivity 的方法,但我不知道如何让它工作。 我尝试使用 NewFileChooser 实现 AdapterView.OnItemSelectedListener,这迫使我实现下面的方法

@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

}

但我也无法让它工作。我正在使用 Android studio,即使使用代码完成助手,我似乎也被卡住了。

恐怕这看起来像是……当您知道自己身处坑中时,请停止挖掘……!因此,非常感谢收到任何帮助

在您的父(调用者)片段中使用 onActivityResult。

执行以下步骤: 像这样更改创建 DF(将其发送到 setTargetFragment):

NewFileChooser newFileChooser = new NewFileChooser();
newFileChooser.setTargetFragment(this, FILE_CHOOSER);
FragmentTransaction ft = getFragmentManager().beginTransaction();
newFileChooser.show(ft, "Diag");

将此方法添加到调用者片段

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
    if (requestCode == FILE_CHOOSER && resultCode == Activity.RESULT_OK)
    {
      Bundle b = data.getExtras();
      String fileName= b.getString("FileName");
      //Code
    }
}

DF 必须继承 AdapterView.OnItemClickListener 并实现这样的方法

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
    Fragment targetFragment = getTargetFragment();

    if (targetFragment != null)
    {
       Intent intent = new Intent();
       Bundle bundle = new Bundle();
       bundle.putString("FileName", /*Selected File Name*/);
       intent.putExtras(bundle);

       targetFragment.onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, intent);
      this.dismiss();
    }
}

终于覆盖了 DF 中的 onActivityCreated

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState)
{
    super.onActivityCreated(savedInstanceState);
    list.setOnItemClickListener(this);
}

targetFragment.onActivityResult 在父片段中调用 onActivityResult。