簡體   English   中英

Android編程-Context / AlertDialog

[英]Android Programming - Context/AlertDialog

CrimeFragment Fragment有一個按鈕,用於存儲犯罪的日期和時間。 當用戶單擊按鈕並觸發ClickListener時,它可以更改。 我被指示讓ClickListener創建一個AlertDialog,詢問用戶他是否要更改日期或時間。 此選擇調用正確的片段(DatePickerFragment / TimePickerFragment),然后將所選數據返回到mDate。

使用Builder創建新的AlertDialog時,構造函數會要求提供上下文。 我嘗試了getActivity(),getContext()和getApplicationContext()無濟於事。 我相信這就是我需要繼續寫的所有內容,但是在我弄清楚這一點之前,不希望進一步,以便可以開始測試。 如果需要,我可以發布更多代碼,但我認為發布一堵代碼牆會有些抵消。

第一個塊是CrimeFragment類

public class CrimeFragment extends Fragment {

public static final String EXTRA_CRIME_ID = "criminalReport.CRIME_ID";
public static final String DIALOG_DATE = "date";
public static final int REQUEST_DATE = 0;
public Crime mCrime;
private EditText mTitleField;
private Button mDateButton;
private CheckBox mSolvedCheckBox;
final Context context = this.getActivity();

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    //mCrime = new Crime();
    //UUID crimeID = (UUID) getActivity().getIntent().getSerializableExtra(EXTRA_CRIME_ID);
    UUID crimeID = (UUID) getArguments().getSerializable(EXTRA_CRIME_ID);
    mCrime = CrimeLab.get(getActivity()).getCrime(crimeID);
}

@Override
//You explicitly inflate the fragment's view 
//by calling layoutInflater's inflate()
public View onCreateView(LayoutInflater inflator, ViewGroup parent, final Bundle savedInstanceState){
    //first parameter : layout resource ID
    //second parameter : view's parent
    //third parameter : tells the layout inflater whether to add the inflated view to the view's parent
    View v = inflator.inflate(R.layout.fragment_crime, parent, false);
    mTitleField=(EditText)v.findViewById(R.id.crime_title);
    mTitleField.setText(mCrime.getTitle());
    mTitleField.addTextChangedListener(new TextWatcher(){
        public void onTextChanged(CharSequence c, int start, int before, int count){
            mCrime.setTitle(c.toString());
        }
        public void beforeTextChanged(CharSequence c, int start, int count, int after){
            //this space intentionally left blank
        }
        public void afterTextChanged(Editable c){
            //this one too
        }
    });
    mDateButton = (Button)v.findViewById(R.id.crime_date);
    mDateButton.setText(mCrime.getDate().toString());
    //mDateButton.setEnabled(false);
    mDateButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            TimeDateDialogFragment tddf = TimeDateDialogFragment.newInstance(context, CrimeFragment.this, REQUEST_DATE, DIALOG_DATE, mCrime);
            tddf.show(getFragmentManager(), "dialog");

            //FragmentManager fm = getActivity().getSupportFragmentManager();
            //DatePickerFragment dialog = DatePickerFragment.newInstance(mCrime.getDate());
            //dialog.setTargetFragment(CrimeFragment.this, REQUEST_DATE);
            //dialog.show(fm, DIALOG_DATE);
        }
    });
    mSolvedCheckBox = (CheckBox) v.findViewById(R.id.crime_solved);
    mSolvedCheckBox.setChecked(mCrime.isSolved());
    mSolvedCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener(){
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked){
            //set the crime's solved property
            mCrime.setSolved(isChecked);
        }
        });
    return v;
}

//attaching argument to a fragment must be done after the fragment is creater
//but before it is added to an activity.  this method create the fragment 
//instance and bundle up and set its agrument
public static CrimeFragment newInstance(UUID crimeID){
    Bundle args = new Bundle();
    args.putSerializable(EXTRA_CRIME_ID, crimeID);

    CrimeFragment fragment = new CrimeFragment();
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
    if (resultCode != Activity.RESULT_OK){
        return;
    }
    if (requestCode == REQUEST_DATE){
        Date date = (Date) data.getSerializableExtra(DatePickerFragment.EXTRA_DATE);
        mCrime.setDate(date);
        mDateButton.setText(mCrime.getDate().toString());
    }
}
}

第二個塊是我創建的TimeDateDialogFragment類。

public class TimeDateDialogFragment extends DialogFragment {

static Context context;
static String DIALOG_DATE;
static int REQUEST_DATE;
static CrimeFragment crimeFragment;
static Crime mCrime;

public static TimeDateDialogFragment newInstance(final Context con, final CrimeFragment crimeFrag, final int rd, 
        final String dd, final Crime mc) {
    TimeDateDialogFragment frag = new TimeDateDialogFragment();
    Bundle args = new Bundle();
    args.putInt("title", 1);
    frag.setArguments(args);

    context = con;
    DIALOG_DATE = dd;
    REQUEST_DATE = rd;
    crimeFragment = crimeFrag;
    mCrime = mc;
    return frag;
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    int title = getArguments().getInt("title");

    return new AlertDialog.Builder(getActivity())
            //.setIcon(R.drawable.alert_dialog_icon)
            .setTitle("Make a selection: ")
            .setPositiveButton("Change date",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        //change the date
                        FragmentManager fm = getActivity().getSupportFragmentManager();
                        DatePickerFragment dpf = DatePickerFragment.newInstance(mCrime.getDate());
                        dpf.setTargetFragment(crimeFragment, REQUEST_DATE);
                        dpf.show(fm, DIALOG_DATE);
                    }
                }
            )
            .setNegativeButton("Change time",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        //change the time
                        FragmentManager fm = getActivity().getSupportFragmentManager();
                        TimePickerFragment tpf = TimePickerFragment.newInstance(savedInstanceState, );
                    }
                }
            )
            .create();
}
}

如果您看到其他明顯的錯誤,我很想聽聽他們的意見。

編輯-我在CrimeFragment類內部創建了一個Context對象,並嘗試將其傳遞給我創建的AlertDialog類。

edit2-大量更新。 使DatePicker工作,現在用於TimePicker。 newInstance(... TimePickerDialog.OnTimeSetListener callBack...)方法調用該TPD.OnTimeSetListener。 我找不到太多有關此的信息,也不知道它在尋找什么。 有任何想法嗎? 我已經用工作資料完全更新了代碼。

來自文檔的TimePickerFragment類:

public class TimePickerFragment extends DialogFragment
implements TimePickerDialog.OnTimeSetListener {

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    // Use the current time as the default values for the picker
    final Calendar c = Calendar.getInstance();
    int hour = c.get(Calendar.HOUR_OF_DAY);
    int minute = c.get(Calendar.MINUTE);

    // Create a new instance of TimePickerDialog and return it
    return new TimePickerDialog(getActivity(), this, hour, minute,
    DateFormat.is24HourFormat(getActivity()));
}

public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
    // Do something with the time chosen by the user
}
}

問題是由

AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());

getApplicationContext()替換為getActivity()


無論如何,您更改了代碼,但DialogFragment.onCreateDialog與原始替代方法不同,這是執行所需操作的錯誤方法。

TimeDateDialogFragment tddf = new TimeDateDialogFragment();
tddf.onCreateDialog(context, CrimeFragment.this, REQUEST_DATE, DIALOG_DATE, mCrime);

像在onClick方法中一樣使用正常的.show()方法,並使用setArguments / getArguments將數據傳遞給它。

並也改變onCreateDialog方法。

文件資料


  1. 您應該使用他的.show()方法顯示片段。
  2. 在此處覆蓋onCreateDialog並創建並返回對話框以顯示

    • 如果需要將任何數據傳遞給片段,則可以使用setArguments和getArguments。
    • 在顯示之前,先使用bundle然后使用.setArguments。

       TimeDateDialogFragment tddf = new TimeDateDialogFragment(); Bundle bundle = new Bundle(); bundle.put/*something*/(/* something else */); bundle.putInt("hello", 5); tddf.setArguments(bundle); tddf.show(getFragmentManager(), "A"); 
    • bundle.putX(X,Y)將用於在地圖包中放置一些東西,在您的情況下將

      CrimeFragment.this,REQUEST_DATE,DIALOG_DATE,mCrime

    • 要讀取捆綁包,請使用getArguments()然后使用getArguments().getX ,例如: getArguments().getInt("NAME"); 例:

       Bundle bundle = getArguments(); 
    • 然后int x = bundle.getInt("hello"); ,您將在x得到5。

  3. 在onCreateDialog內,您應該使用getActivity() ,它將返回要求顯示片段的活動的上下文。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM