簡體   English   中英

還原以編程方式添加的片段中的視圖

[英]Restore views in a fragment added programmatically

我有一個帶有導航抽屜的活動(Eclipse新應用程序向導提供的基本活動)。 我有一個FrameLayout作為應用程序不同片段的容器,當在導航抽屜中選擇一個項目時,這些片段將被替換。 它們也被添加到BackStack。

這些片段包含一個LinearLayout,其中包含一些EditTexts和一個Button。 如果按下該按鈕,則將創建一個新的LinearLayout,並將兩個TextViews與EditTexts的內容一起添加到其中。 用戶可以多次重復此選項,因此我無法確定需要多少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>

實際上還有許多其他EditText,但是為了簡短起見,我在這里刪除了它們,結果是一樣的。 它是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的子類,它只是創建一些TextViews並將其添加到自身。

這里一切都很好。 用戶在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()方法中創建它。

我找到了解決問題的方法。 我用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);

有關此方法如何工作的詳細信息,請參見文檔

盡管這樣,我不得不重新實現所有后退按鈕邏輯,但這仍然很簡單,這就是我的方法:我創建了一個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;
    }
};

暫無
暫無

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

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