我有一个屏幕,用户按下按钮以显示DialogFragment
EditText
。他们输入信息,然后按Ok
。如果他们再次按下按钮,我就会这样做,EditText
将显示他们刚刚放入的信息,一切正常。
但是,如果他们输入信息,请按Ok
,然后使用选项菜单查看另一个屏幕/ fragment
,该信息将不会显示在EditText
中一旦他们再次按下按钮。
即使用户暂时离开该屏幕,我如何保存信息?我认为在片段类中需要newInstance
方法,然后让托管活动调用newInstance
而不是构造函数。但我不确定如何实现它。任何帮助赞赏。谢谢!
SingleFragmentActivity
:
public abstract class SingleFragmentActivity extends FragmentActivity
{
protected abstract Fragment createFragment();
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragmentContainer);
if (fragment == null)
{
fragment = createFragment();
fm.beginTransaction()
.add(R.id.fragmentContainer, fragment)
.commit();
}
}
}
来自托管活动的相关代码,AdviceActivity:
public class AdviceActivity extends SingleFragmentActivity
{
@Override
protected Fragment createFragment()
{
return new AdviceFragment();
}
}
来自托管片段的相关代码,AdviceFragment:
private boolean isTextButtonFirstClick = true;
...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)
{
mTextButton = (Button) v.findViewById(R.id.textButton);
mTextButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
if (isTextButtonFirstClick)
{
FragmentManager fm = getActivity().getSupportFragmentManager();
InputTextFragment dialog = InputTextFragment.newInstance("", isTextButtonFirstClick);
dialog.setTargetFragment(AdviceFragment.this, REQUEST_TEXT);
dialog.show(fm, DIALOG_TEXT);
isTextButtonFirstClick = false;
}
else
{
FragmentManager fm = getActivity().getSupportFragmentManager();
InputTextFragment dialog = InputTextFragment.newInstance(mAdvice.getText(), isTextButtonFirstClick);
dialog.setTargetFragment(AdviceFragment.this, REQUEST_TEXT);
dialog.show(fm, DIALOG_TEXT);
}
}
});
...
}
DialogFragment InputTextFragment的相关代码:
public static InputTextFragment newInstance(String text, boolean isTextButtonFirstClick)
{
Bundle args = new Bundle();
args.putSerializable(EXTRA_TEXTBUTTON_FIRSTCLICK, isTextButtonFirstClick);
args.putSerializable(EXTRA_TEXT, text);
InputTextFragment fragment = new InputTextFragment();
fragment.setArguments(args);
return fragment;
}
...
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
...
boolean isTextButtonFirstClick = getArguments().getBoolean(EXTRA_TEXTBUTTON_FIRSTCLICK);
final EditText editText = (EditText) v.findViewById(R.id.dialogInputEditText);
if (!isTextButtonFirstClick)
{
editText.setText(text);
editText.setSelection(text.length());
}
...
}
XML activity_fragment:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent">
</RelativeLayout>
答案 0 :(得分:1)
听起来好像布尔值isTextButtonFirstClick被错误地设置为false。
这将理解在导航过程中创建的Advice Fragment的新实例。
尝试
在建议片段的onCreate中设置setRetainInstance(true)以保持布尔值。
如果R.id.fragmentContainer是XML中的片段标记,则将其更改为LinearLayout或RelativeLayout(无论如何都要在顶部添加片段,我怀疑findFragmentById始终返回null)
将您的活动中的代码更改为:
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentByTag("singleFragment");
if (fragment == null)
{
fragment = createFragment();
}
fm.beginTransaction()
.replace(R.id.fragmentContainer, fragment, "singleFragment" )
.commit();
通常在以编程方式添加片段时,您使用标签,而在使用XML定义片段时,让Android框架处理生命周期,您可以通过id找到它。
在我看来,好像你处于中间解决方案中,试图同时做这两种解决方案,这将无法按预期工作。
如果存在格式问题,希望这可以提前帮助和抱歉。答案是用手机写的:-)
修改强>
如果您只想保存简单类型的信息(例如布尔值),我会在此向您指出我的旧答案之一:Saving textview in a fragment when rotating screen
您的上一条评论显示您有一些您想要保留的复杂信息(文字,照片,视频等)。
让所有Parcelable成为一个巨大的痛苦,所以这是我的第二个建议:
为信息创建一个持有者类,例如
public class AdviceHolder {
private boolean isTextButtonFirstClick;
private String text;
private BitMap image;
...
// setter and getter methods (if using eclipse alt+shit+s 'create setter and getters from fields')
}
现在,在启动AdviceActivity时,您需要准备一个新的AdviceHolder
public class AdviceActivity extends SingleFragmentActivity
{
@Override
public void onCreate(Bundle savedInstanceState) {
// make a new AdviceHolder if none existed
AdviceHolder holder = new AdviceHolder();
AdviceHolder existingHolder = EventBus.getDefault().getStickyEvent(AdviceHolder.class);
if (existingHolder == null) {
EventBus.getDefault().postSticky(holder);
}
super.onCreate(savedInstanceState);
}
@Override
protected Fragment createFragment()
{
return new AdviceFragment();
}
}
此步骤将使代码中的AdviceHolder对象随时随地。将其视为全球存储库。
这意味着无论您如何在Activites或Fragments之间移动,他们都可以访问AdviceHolder并进行编辑。
例如,你在AdviceFragment:
private AdviceHolder holder;
...
@Override
public void onCreate (Bundle savedInstanceState) {
AdviceHolder holder = (AdviceHolder)EventBus.getDefault().getStickyEvent(AdviceHolder.class);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)
{
// read isTextButtonFirstClick from holder
boolean isTextButtonFirstClick = holder.isTextButtonFirstClick();
mTextButton = (Button) v.findViewById(R.id.textButton);
mTextButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
if (isTextButtonFirstClick)
{
FragmentManager fm = getActivity().getSupportFragmentManager();
InputTextFragment dialog = InputTextFragment.newInstance("", isTextButtonFirstClick);
dialog.setTargetFragment(AdviceFragment.this, REQUEST_TEXT);
dialog.show(fm, DIALOG_TEXT);
// update isTextButtonFirstClick in holder
holder.setTextButtonFirstClick(false);
EventBus.getDefault().postStickyEvent(holder);
}
else
{
FragmentManager fm = getActivity().getSupportFragmentManager();
InputTextFragment dialog = InputTextFragment.newInstance(mAdvice.getText(), isTextButtonFirstClick);
dialog.setTargetFragment(AdviceFragment.this, REQUEST_TEXT);
dialog.show(fm, DIALOG_TEXT);
}
}
});
...
}
当你在某个时刻填写AdviceHolder
(并将其发送到服务器或任何计划)时,将其从EventBus中删除,以便在AdviceActivity
中创建新的持有者。
EventBus.getDefault().removeStickyEvent(AdviceHolder.class);
有关EventBus的其他示例,请查看http://www.stevenmarkford.com/passing-objects-between-android-activities/
这是很多信息,希望它不会太混乱。