2013-07-10 50 views
0

我試圖找出在我的片段和DialogFragment之間傳遞數據的最佳方法。 (雙向通信)將數據從片段傳遞到DialogFragment的最佳方式

首先我有一個對話框片段,允許用戶選擇用於旅行的司機/車輛。用戶可以選擇多個司機和車輛。下面是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); 
    } 
} 

這裏是我的車類:

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

這裏是我的驅動程序類:

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

,這裏是我的片段調用dialogfragment獲得驅動程序/已選車輛:

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

我在想我應該將對話框中的驅動程序列表和車輛列表傳回碎片?

我也想過將URI數組傳回給Fragment,但這不是一個好主意,因爲數據庫與web服務保持同步,並且如果它同步並且sqlite數據庫中的記錄被刪除,那麼我wouldnt能夠檢索片段內的數據。

我真的不確定什麼是最好的解決方案,任何幫助將不勝感激。

回答

1

沒有尋找到的細節在你的代碼,這裏就是我正在做這(通過活動從片段將數據傳遞到DialogFragment):

像往常一樣申報Frag1一個靜態的界面,在法案實施:

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

準備DFrag通過具有一些方法來接收數據:

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

假設DFrag is shown using a tag

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

然後從法:

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

我明白使用接口是最好的方法,我看到你的解決方案使用Activity作爲一種在片段和對話框片段之間來回發送數據的方式。但是爲了讓我的問題稍微有點不同,我應該以什麼格式傳遞片段和對話框之間的驅動程序/車輛列表?我是否應該使用泛型並使司機和車輛實現可分派? – user1848850

+1

如果通過參數發送數據,或者如果重新創建片段 - 它將在某個時候重新創建 - 並且您不想再次重新查詢數據的源,則它值得使用Parcelable。 – gunar

3

你可以選擇你希望的任何方式。

但請注意,在某些情況下,片段/活動可能會重新創建(例如當您旋轉設備時),因此您也需要處理它(除非您確定,否則對話框將消失。

,因爲你使用的是setArguments和getArguments,你可以使用的onSaveInstanceState,但同樣,這一切都取決於你想在這種情況下做什麼。

的數據傳遞到活動,你甚至可以使用你自己的監聽器來代替

相關問題