我有一个带导航抽屉的活动(Eclipse新应用程序向导提供的基本活动)。我有一个FrameLayout作为应用程序的不同片段的容器,在导航抽屉中选择项目时会替换它们。它们也被添加到BackStack中。
这些片段包含一个LinearLayout,它有一些EditTexts和一个Button。如果按下该按钮,则会创建一个新的LinearLayout,并使用EditTexts的内容向其中添加几个TextView。用户可以多次重复此选项,因此我无法确定我需要多少LinearLayouts,因此我需要以编程方式添加它们。
其中一个片段xml:
<LinearLayout
android:id="@+id/pen_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/new_pen_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_vertical_margin"
android:background="@drawable/border"
android:orientation="vertical"
android:paddingBottom="@dimen/home_section_margin_bottom"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/home_section_margin_top" >
<EditText
android:id="@+id/new_pen_round"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:hint="@string/new_pen_round_hint"
android:textSize="@dimen/normal_text_size" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="2" >
<Button
android:id="@+id/new_pen_cancel_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/new_item_button_margin_right"
android:layout_weight="1"
android:background="@drawable/button_bg"
android:paddingBottom="@dimen/new_item_button_padding_bottom"
android:paddingTop="@dimen/new_item_button_padding_top"
android:text="@string/new_item_cancel_button"
android:textSize="@dimen/normal_text_size" />
<Button
android:id="@+id/new_pen_insert_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/new_item_button_margin_left"
android:layout_weight="1"
android:background="@drawable/button_bg"
android:paddingBottom="@dimen/new_item_button_padding_bottom"
android:paddingTop="@dimen/new_item_button_padding_top"
android:text="@string/new_pen_insert_button"
android:textSize="@dimen/normal_text_size" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
实际上还有很多其他的EditTexts,但我在这里删除它们以保持简短,结果是一样的。这是java文件:
public class PenaltiesFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_penalties, container, false);
Button insertNewPen = (Button) view.findViewById(R.id.new_pen_insert_button);
insertNewPen.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
TextView round = (TextView) getActivity().findViewById(R.id.new_pen_round);
LinearLayout layout = (LinearLayout) getActivity().findViewById(R.id.pen_layout);
int numChilds = layout.getChildCount();
CustomPenaltyLayout penalty = new CustomPenaltyLayout(getActivity(), round.getText());
layout.addView(penalty, numChilds - 1);
}
});
return view;
}
}
我删除了一些无用的方法,这些方法只是默认方法。 CustomPenaltyLayout
是我创建的LinearLayout的子类,它只是创建一些TextView并将它们添加到自身。
这里一切正常。用户在EditText中插入数据,按下Insert按钮,然后创建一个新的布局并添加到片段中。
我想要实现的是:说我打开导航抽屉并选择另一个页面,片段被替换,如果我回到这个片段(通过导航抽屉或通过后退按钮)我想要的文本,即用户补充说,仍然在那里。
每次切换回此片段时,我都不会调用PenaltiesFragment.newInstance()
,而是创建PenaltiesFragment
对象一次并继续使用该对象。这就是我的工作:
Fragment fragment;
switch (newContent) {
// various cases
case PEN:
if(penFragment == null) // penFragment is a private field of the Main Activity
penFragment = PenaltiesFragment.newInstance();
fragment = penFragment;
break;
}
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.container, fragment)
.addToBackStack("fragment back")
.commit();
我知道重新加载片段时会再次调用onCreateView()
,对吧?所以这可能就是我看到的一个新的空白片段的原因。但是如何将插入的CustomPenaltyLayout
取回?我无法在onCreateView()
方法中创建它。
答案 0 :(得分:0)
我找到了解决问题的方法。我使用ViewPager替换了Android自动创建的默认FrameLayout作为我的片段的容器,然后创建了像这样的FragmentPagerAdapter:
public static class MyAdapter extends FragmentPagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
Fragment fragment;
switch (position) {
// ...other cases
case PEN:
fragment = PenaltiesFragment.newInstance();
break;
// ...other cases
}
return fragment;
}
@Override
public int getCount() {
return 6;
}
}
然后,唯一要保留所有观看次数的方法就是将此行添加到我的活动onCreate
方法中。
mPager.setOffscreenPageLimit(5);
有关此方法如何工作的详细信息,请参阅documentation。
但是,这种方式,我不得不重新实现所有后退按钮逻辑,但它仍然很简单,这就是我做的方式:我创建一个java.util.Stack<Integer>
对象,向其添加片段数(当你使用后退按钮时,见下文),当我的历史堆栈不为空时,覆盖onBackPressed()
以使其弹出最后查看的片段而不是使用后台堆栈。
当您按下后退按钮时,您希望避免在堆栈上推送元素,否则如果继续使用后退按钮,则会卡在两个片段之间,而不是最终退出。
我的代码:
MyAdapter mAdapter;
ViewPager mPager;
Stack<Integer> pageHistory;
int currentPage;
boolean saveToHistory;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAdapter = new MyAdapter(getSupportFragmentManager());
mPager = (ViewPager)findViewById(R.id.container);
mPager.setAdapter(mAdapter);
mPager.setOffscreenPageLimit(5);
pageHistory = new Stack<Integer>();
mPager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int arg0) {
if(saveToHistory)
pageHistory.push(Integer.valueOf(currentPage));
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
saveToHistory = true;
}
@Override
public void onBackPressed() {
if(pageHistory.empty())
super.onBackPressed();
else {
saveToHistory = false;
mPager.setCurrentItem(pageHistory.pop().intValue());
saveToHistory = true;
}
};