如何创建弹出 Android 片段,在返回主 activity 之前接收文本输入?

How do I create a pop-up Android Fragment that takes in a text input before returning to my main activity?

对于我的应用程序,我希望我的用户能够按下 "Change User" 按钮,弹出片段,接受文本输入,然后在退出时保存到共享首选项,返回到activity 它是从哪里调用的。

我希望我的方法类似于我已经实现的 TimePicker 片段,我将在本文结尾处 post。

我目前正在使用本教程作为指南:Dialog Fragment Tutorial

这是我的对话片段Class:

public class EditNameDialog extends DialogFragment {

    private EditText mEditText;

    public EditNameDialog() {
        // Empty constructor required for DialogFragment
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_edit_name, container);
        getDialog().setTitle("Hello");
        return view;
    }

    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        return true;

    }
}

这是我的 MainActivity 调用它的方法:

public class MainActivity extends Activity implements
        TimePickerFragment.FragmentCallbacks {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Use the current time as the default values for the picker
        SharedPreferences sharedPref = this.getSharedPreferences("prediction",
                Context.MODE_PRIVATE);

        final Calendar c = Calendar.getInstance();
        int defaultHour = c.get(Calendar.HOUR_OF_DAY);
        int defaultMinute = c.get(Calendar.MINUTE);

        int hour = sharedPref.getInt("prediction_hour", defaultHour);
        int minute = sharedPref.getInt("prediction_min", defaultMinute);

        String timeString = Integer.toString(hour) + ":"
                + Integer.toString(minute);

        TextView predictionText = (TextView) findViewById(R.id.prediction_time);
        predictionText.setText(timeString);
    }

    public void showTimePickerDialog(View v) {
        DialogFragment newFragment = new TimePickerFragment();
        newFragment.show(getFragmentManager(), "timePicker");

    }

    public void showUserNameEdit(View c) {
        EditNameDialog newFragment = new EditNameDialog();
        newFragment.show(getSupportFragmentManager(), "editName");
    }

    @Override
    public void TimeUpdated(int hour, int minute) {
        Toast.makeText(this, "Hour: " + hour + " Minute: " + minute,
                Toast.LENGTH_SHORT).show();
        // finish();
        // startActivity(new Intent(this, MainActivity.class));

        String timeString = Integer.toString(hour) + ":"
                + Integer.toString(minute);
        TextView predictionText = (TextView) findViewById(R.id.prediction_time);
        predictionText.setText(timeString);
    }
}

我相信这就是问题所在。要么我用 getFragmentManager() 调用 show(),它说 show() 只接受 getSupportFragmentManager(),要么我用 getSupportFragmentManager() 调用它,它说 Activity 没有这个方法。我知道我可以用 FragmentActivity 来扩展我的 activity,但这会产生其他问题。我想像我的 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
        Context context = getActivity();
        SharedPreferences sharedPref = context.getSharedPreferences(
                "prediction", Context.MODE_PRIVATE);

        final Calendar c = Calendar.getInstance();
        int defaultHour = c.get(Calendar.HOUR_OF_DAY);
        int defaultMinute = c.get(Calendar.MINUTE);

        int hour = sharedPref.getInt("prediction_hour", defaultHour);
        int minute = sharedPref.getInt("prediction_min", defaultMinute);

        // 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) {
        Context context = getActivity();
        SharedPreferences sharedPref = context.getSharedPreferences(
                "prediction", Context.MODE_PRIVATE);
        SharedPreferences.Editor editorh = sharedPref.edit();
        editorh.putInt("prediction_hour", hourOfDay);
        editorh.commit();
        SharedPreferences.Editor editorm = sharedPref.edit();
        editorm.putInt("prediction_min", minute);
        editorm.commit();
        mCallbacks.TimeUpdated(hourOfDay, minute);
    }

    /**
     * Interface
     */
    private FragmentCallbacks mCallbacks;

    public interface FragmentCallbacks {
        void TimeUpdated(int hour, int minute);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mCallbacks = (FragmentCallbacks) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(
                    "Activity must implement Fragment Two.");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mCallbacks = null;
    }

}

我建议及时了解最新的支持库,以便您的应用使用最新的用户界面设计(Material 设计),并且您的应用在所有设备上都将保持相同的外观。所以我建议做如下:

对于 DialogFragments,您应该传递参数以启动片段的新实例,而不是使用共享首选项。虽然共享首选项仍然有效,但它不是一个非常理想的解决方案。将参数传递给对话框片段的最佳实践如下所示,使用名为 newInstance() 的方法。可以找到您不将参数传递给构造函数的原因 here

在 onCreateDialog 中使用 AppCompatDialog,并使用如下所示的导入:

import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatDialog;

...
...

public class TimePickerFragment extends DialogFragment implements
    TimePickerDialog.OnTimeSetListener {

public static TimePickerFragment newInstance(int hour, int min){
    TimePickerFragment frag = new TimePickerFragment();
    Bundle args = new Bundle();
    args.putInt("hour", hour);
    args.putInt("min", min);
    frag.setArguements(args);
    return frag;
}

@Override
public AppCompatDialog onCreateDialog(Bundle savedInstanceState) {

    // Use the current time as the default values for the picker
    final Calendar c = Calendar.getInstance();
    int defaultHour = c.get(Calendar.HOUR_OF_DAY);
    int defaultMinute = c.get(Calendar.MINUTE);

    int hour = getArguments().getInt("hour");
    int minute = getArguments().getInt("min");

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

    ...
    ...
}

当你展示它时,请执行以下操作:

TimePickerFragment.newInstance(hour, min).show(getSupportFragmentManager(), "time_fragment");

并且在您的 activity 中应该像下面这样扩展 AppCompatActivity:

public class MainActivity extends AppCompatActivity implements
    TimePickerFragment.FragmentCallbacks {

然后在您的 activity 调用 show() 时使用 getSupportFragmentManager();

如果您没有随应用下载最新的支持库,请将这些依赖项添加到您的 gradle 文件中:

dependencies {
    compile 'com.android.support:appcompat-v7:22.1.1'
    compile 'com.android.support:support-v4:22.1.1'
    ...
}