如何创建弹出 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'
...
}
对于我的应用程序,我希望我的用户能够按下 "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'
...
}