2013-07-10 6 views
0

J'essaie de comprendre la meilleure façon de transmettre des données entre mon fragment et un DialogFragment. (Communication bidirectionnelle)Meilleure façon de transmettre des données de Fragment à DialogFragment

D'abord j'ai un fragment de dialogue qui permet à l'utilisateur de choisir les conducteurs/véhicules utilisés pour le voyage. L'utilisateur peut choisir plusieurs conducteurs et véhicules. Voici un extrait de classe DialogFragment:

public class DriverVehiclePickersDialogFragment extends DialogFragment implements OnClickListener, LoaderManager.LoaderCallbacks<Cursor> { 

    private static final int DRIVERS_LOADER = 0; 
    private static final int VEHICLES_LOADER = 1; 

    // Parent view for all rows and the add button. 
    private LinearLayout mContainerView; 

    // These are the Contacts rows that we will retrieve. 
    static final String[] DRIVERS_SUMMARY_PROJECTION = new String[] { BaseColumns._ID, ConsoleContract.Drivers.DRIVER_NUMBER, ConsoleContract.Drivers.DRIVER_NAME }; 
    static final String[] VEHICLES_SUMMARY_PROJECTION = new String[] { BaseColumns._ID, ConsoleContract.Vehicles.VEHICLE_NUMBER, ConsoleContract.Vehicles.VEHICLE_VIN }; 

    public interface DriverVehicleDialogListener { 
     public void onDialogPositiveClick(????????); 
    } 

    @Override 
    public void onClick(View v) { 
     if (v.equals(mSet)) { 
      if (checkDriversVehiclesValidity()) { 
       mListener.onDialogPositiveClick(???????????); 
       this.dismiss(); 
      } 
     } else if (v.equals(mCancel)) { 
      this.dismiss(); 
     } else if (v.equals(mAddNew)) { 
      inflateEditRow(); 
     } else if (v instanceof ImageButton) { 
      mContainerView.removeView((View) v.getParent()); 
     } 
    } 

    // Helper for inflating a row 
    private void inflateEditRow() { 

     Bundle args = getArguments(); 
     DialogType dialogType = (DialogType) args.getSerializable(ARG_DIALOG_TYPE); 
     final View rowView = getActivity().getLayoutInflater().inflate(R.layout.driver_vehicle_row, null); 
     CustomAutoCompleteTextView driversField, vehiclesField; 

     if ((dialogType == DialogType.DRIVER_SPINNER) || (dialogType == DialogType.DRIVER_VEHICLE_SPINNER)) { 
      driversField = (CustomAutoCompleteTextView) rowView.findViewById(R.id.drivers_field); 
      driversField.setThreshold(0); 
      driversField.setAdapter(mDriversAdapter); 
      driversField.setVisibility(View.VISIBLE); 
     } 

     if ((dialogType == DialogType.VEHICLE_SPINNER) || (dialogType == DialogType.DRIVER_VEHICLE_SPINNER)) { 
      vehiclesField = (CustomAutoCompleteTextView) rowView.findViewById(R.id.vehicles_field); 
      vehiclesField.setThreshold(0); 
      vehiclesField.setAdapter(mVehiclesAdapter); 
      vehiclesField.setVisibility(View.VISIBLE); 
     } 

     ImageButton mDelete = (ImageButton) rowView.findViewById(R.id.buttonDelete); 
     mDelete.setOnClickListener(this); 

     // Inflate at the end of all rows but before the "Add new" button 
     mContainerView.addView(rowView, mContainerView.getChildCount() - 1); 
    } 
} 

Voici ma classe Véhicules:

public static final class Vehicles implements VehicleColumns, BaseColumns { 

    public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath(PATH_VEHICLES).build(); 
    public static final String CONTENT_TYPE = "vnd.android.cursor.dir/com.test.console.vehicles"; 
    public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.console.vehicles"; 

    private int vehicle_id, vehicle_number; 
    private String vehicle_vin; 

    public Vehicles() { 
    } 

    public Vehicles(int vehicleID, int vehicleNumber, String vehicleVin) { 
     setVehicleID(vehicleID); 
     setVehicleNumber(vehicleNumber); 
     setVehicleVin(vehicleVin); 
    } 

    public int getVehicleID() { 
     return vehicle_id; 
    } 

    public void setVehicleID(int mVehicleID) { 
     this.vehicle_id = mVehicleID; 
    } 

    public int getVehicleNumber() { 
     return vehicle_number; 
    } 

    public void setVehicleNumber(int mVehicleNumber) { 
     this.vehicle_number = mVehicleNumber; 
    } 

    public String getVehicleVin() { 
     return vehicle_vin; 
    } 

    public void setVehicleVin(String mVehicleVin) { 
     this.vehicle_vin = mVehicleVin; 
    } 

    public static Uri buildVehicleUri(String vehicleID) { 
     return CONTENT_URI.buildUpon().appendPath(vehicleID).build(); 
    } 
} 

Voici mon Pilotes Classe:

public static final class Drivers implements DriverColumns, BaseColumns { 

    public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath(PATH_DRIVERS).build(); 
    public static final String CONTENT_TYPE = "vnd.android.cursor.dir/com.test.console.drivers"; 
    public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.console.drivers"; 

    private int driver_id, driver_number; 
    private String driver_name; 

    public Drivers() { 
    } 

    public Drivers(int driverID, int driverNumber, String driverName) { 
     this.setDriverID(driverID); 
     this.setDriverNumber(driverNumber); 
     this.setDriverName(driverName); 
    } 

    public static Uri buildDriverUri(String driverID) { 
     return CONTENT_URI.buildUpon().appendPath(driverID).build(); 
    } 

    public int getDriverID() { 
     return driver_id; 
    } 

    public void setDriverID(int driver_id) { 
     this.driver_id = driver_id; 
    } 

    public int getDriverNumber() { 
     return driver_number; 
    } 

    public void setDriverNumber(int driver_number) { 
     this.driver_number = driver_number; 
    } 

    public String getDriverName() { 
     return driver_name; 
    } 

    public void setDriverName(String driver_name) { 
     this.driver_name = driver_name; 
    } 
} 

et Voici mon Fragment qui appelle le dialogfragment pour obtenir pilote/véhicules sélectionnés:

public class CrewTripFragment extends Fragment implements DateTimeDialogListener, CrewCountDialogListener, DriverVehicleDialogListener, OnItemSelectedListener { 

    @Override 
    public void onDialogPositiveClick(????) { 
     //I need a list of drivers+vehicles selected so i can use it in the fragment. 
     //an example would be: 
     //DriverID: 10 DriverName: John DriverNumber 30 - VehicleID 10 VehicleNumber: 24 VehicleVin: 34848 
    } 

    protected void showDriverVehicleDialog() { 

     // Creating a bundle object 
     Bundle bundleSettings = new Bundle(); 
     bundleSettings.putInt(DriverVehiclePickersDialogFragment.ARG_TITLE_RESOURCE, R.string.crew_driver_vehicle_title); 
     bundleSettings.putSerializable(DriverVehiclePickersDialogFragment.ARG_DIALOG_TYPE, DriverVehiclePickersDialogFragment.DialogType.DRIVER_VEHICLE_SPINNER); 

     if (mDrivers != null) { 
      bundleSettings.putLongArray(DriverVehiclePickersDialogFragment.ARG_SET_DRIVER, mDrivers); 
     } 

     if (mVehicles != null) { 
      bundleSettings.putLongArray(DriverVehiclePickersDialogFragment.ARG_SET_VEHICLE, mVehicles); 
     } 

     DriverVehiclePickersDialogFragment dialogDriverVehiclePicker = DriverVehiclePickersDialogFragment.newInstance(this, bundleSettings); 
     dialogDriverVehiclePicker.show(getFragmentManager(), getTag()); 
    } 

Je pensais que je devrais passer une liste de pilotes et une liste de véhicules de la fragmentation de dialogue au fragment? Je pensais également à renvoyer un tableau d'URI au Fragment mais ce ne serait pas une bonne idée car la base de données reste synchronisée avec un webservice et si elle se synchronise et l'enregistrement dans la base de données sqlite est supprimé puis Je ne serais pas capable de récupérer les données à l'intérieur du fragment.

Je ne sais pas vraiment quelle est la meilleure solution, toute aide serait grandement appréciée.

Répondre

1

Sans regarder en détail dans votre code, voici comment je fais (données passant d'un fragment à un DialogFragment par une activité):

Comme d'habitude Déclarez une interface statique dans Frag1 qui est mis en œuvre dans la loi:

public static interface DataProxy { 
    void sendData(Object ... args); 
} 

Préparer le DFrag pour recevoir les données en ayant une certaine méthode:

public void recvData(Object ... data){ ... } 

Supposons DFrag is shown using a tag:

DialogFragment newFragment = MyDialogFragment.newInstance(mStackLevel); 
newFragment.show(getSupportFragmentManager().beginTransaction(), "my-dialog"); 

Et puis de la Loi:

@Override 
public void sendData(Object ...data) { 
    Fragment frag = getSupportFragmentManager().findFragmentByTag("my-dialog"); 
    if(frag != null && frag instanceof MyDialogFragment) { 
     ((MyDialogFragment) frag).recvData(data); 
    } 
} 
+0

Je comprends que l'utilisation d'interfaces est la meilleure façon de faire. un moyen d'envoyer des données entre un fragment et un fragment de dialogue. Mais pour reformuler ma question un peu différemment, dans quel format devrais-je passer dans les listes de pilotes/véhicules entre le fragment et le dialogue?Dois-je utiliser des médicaments génériques et rendre les véhicules et les véhicules mis en œuvre parcelable? – user1848850

+1

Cela vaut la peine d'utiliser Parcelable si vous envoyez des données via des arguments ou si vous recréer le fragment - il sera recréé à un moment donné - et vous ne voulez pas re-interroger à nouveau la source de vos données. – gunar

3

vous pouvez choisir la méthode que vous le souhaitez. Notez cependant que dans certains cas, le fragment/l'activité peut être recréé à nouveau (comme lorsque vous faites pivoter l'appareil), vous devez donc le manipuler aussi (sauf si vous êtes d'accord, que la boîte de dialogue disparaîtra.

puisque vous utilisez les setArguments et GetArguments, vous pouvez utiliser onSaveInstanceState, mais encore une fois, tout dépend de ce que vous voulez faire sur ces cas.

pour les données à transmettre à l'activité , vous pouvez même utiliser votre propre écoute à la place

Questions connexes