1

I have done extensive reading of a variety of answers on S/O in the search for a solution to my problem, but now seem to be going round and round in circles as there's doesn't appear to be any consistent approach to DialogFragment (DF) creation and handling which I've been able to use to solve my problem.

I am running a single activity with many ordinary fragments. I have created a DF to handle a list of files from which I want the user to pick one, which will then be imported (into the SQLite database file). I am creating the DF from my MainActivity by the following code (instigated by a button click in an ordinary fragment) :-

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");
}

Within 'NewFileChooser' the DF is created within the OnCreateView method :-

@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;
 }

The 'fill(currentDir)' method shown below uses 2 additional classes, employing an ArrayAdapter means of getting the files from the sdcard /backup directory and displaying this sorted list in the list area of the DF.
This part works fine, the DF is created and displays the list, and if you click any of the files on the list, the background lightens, indicating you're starting the event, but that’s as far as I can get.

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);
}

The code is largely extracted from the 'ticked' answer File Chooser inside DialogFragment (re-using code)

I have amended this to suit my circumstances and it works, but only as far as I mentioned above. From reading many of the existing answers on S/O I'm not sure whether I've dug myself into a hole. Many of the answers have buttons employed with listeners associated with them, which I do not have and so haven't been able to use their code (particularly on listeners) to solve my problem, others start the DF off using the
-- AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); -- code construct which I'm not using. (I did try to use this method but the .setItems verb didn't like my dynamically built file list, it just wanted a fixed array, and I couldn't get it to work) .

Clearly I need to use a listener interface as a means to get the file name back to the MainActivity but I don't know how to get this working. I've tried using the NewFileChooser implementing AdapterView.OnItemSelectedListener which forced me to implement the method below

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

}

But I couldn't get this to work either. I'm using Android studio and even with the code completion helper I seem to be pretty stuck.

I'm afraid this looks like a case of …when you know you're in a hole stop digging…! So any assistance would be very gratefully received

Community
  • 1
  • 1

1 Answers1

1

Use onActivityResult in your parent(caller) fragment.

do this steps: Change create DF like this (sent this to setTargetFragment):

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

Add this method to caller fragment

@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 must be inherit AdapterView.OnItemClickListener and implement method like this

@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();
    }
}

finally override onActivityCreated in DF

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

targetFragment.onActivityResult call the onActivityResult in parent fragment.

Fred
  • 3,365
  • 4
  • 36
  • 57
  • The problem I have is up stream from your solution Fred, I can't get the user choice without a listener on the Listview, most answers use the builder Class within an onCreateDialog method to create the DF and attach their listeners there, I've used onCreateView, and I can't see a way to attach a listener to the listview to capture the user's click . – Martin Clifford Dec 28 '15 at 19:56
  • I edit my response,add onItemClick and onActivityCreated sections – Fred Dec 28 '15 at 20:45
  • I think we're nearly there, I've implemented your amendments/changes, its picking up the chosen file name, but when it falls through the bundle creation & out via the dismiss its not finding its way back to the 'onActivityResult' method in my MainActivity activity which started it off. – Martin Clifford Dec 29 '15 at 19:44
  • A couple of points here which may be relevant, you refer to my parent (caller) as a fragment, well its actually an activity (MainActivity), and in your first code box covering the 'create DF' statements, in line 2 newFileChooser.setTargetFragment (this, FILE_CHOOSER); it won't accept the use of 'this' and will only accept newFileChooser as an allowable parameter. I get the feeling its returning after the dismiss() , but can't find the correct object's onActivityResult method ? – Martin Clifford Dec 29 '15 at 19:44
  • My answer to your question is work fine for me. but if you want to result back to your activity you can use this links: http://stackoverflow.com/questions/15121373/returning-string-from-dialog-fragment-back-to-activity http://stackoverflow.com/questions/12622742/get-value-from-dialogfragment – Fred Dec 29 '15 at 20:52
  • First parameter of setTargetFragment identify the target fragment that getTargetFragment() in DF get it, when you call targetFragment.onActivityResult, actually call onActivityResult in caller fragment. If you sent newFileChooser to setTargetFragment, argetFragment.onActivityResult call onActivityResult in DF fragment!! – Fred Dec 29 '15 at 21:00
  • Thank you Fred for your assistance in my problem. I now understand thus area a great deal more. Indeed I put an onActivityResult in my DF and sure enough that’s where the callback went to! So I've implemented as per your suggestion, an interface as in answer /15121373 and now my code is doing what I wanted it to do. I've learnt a lot about activities & fragments and how they do & don't communicate so I'm very grateful to you for that. – Martin Clifford Dec 30 '15 at 21:00