我有這個奇怪的問題,其中我的列表片段創建了兩次,一次是在父活動上調用super.oncreate並且一次在同一父活動上調用setContentView時。這是一個簡單的應用程序,我使用不同的肖像和橫向佈局。在定位更改上創建了兩次android片段
這裏是主要的活動:
private HeadlinesFragment headlines;
@Override
public void onCreate(Bundle savedInstanceState) {
Log.w("MainActivity", "Before super.onCreate: " + this.toString());
super.onCreate(savedInstanceState);
Log.w("MainActivity", "Before setContentView: " + this.toString());
setContentView(R.layout.news_articles);
//check to see if its portrait
if (findViewById(R.id.fragment_container) != null) {
if(getSupportFragmentManager().findFragmentById(R.id.fragment_container) == null) {
headlines = new HeadlinesFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, headlines).commit();
}
}
}
這裏是在佈局,土地文件夾中的news_articles:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment android:name="com.example.android.fragments.HeadlinesFragment"
android:id="@+id/headlines_fragment"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<fragment android:name="com.example.android.fragments.ArticleFragment"
android:id="@+id/article_fragment"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
這裏是在佈局文件夾中的news_articles(對於縱向)
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
這裏是headlinesfragment這就是被創建兩次
public class HeadlinesFragment extends ListFragment {
OnHeadlineSelectedListener mCallback;
// The container Activity must implement this interface so the frag can deliver messages
public interface OnHeadlineSelectedListener {
/** Called by HeadlinesFragment when a list item is selected */
public void onArticleSelected(int position);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.w("HeadlinesFragment", "inside onCreate: " + this.toString());
// We need to use a different list item layout for devices older than Honeycomb
int layout = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ?
android.R.layout.simple_list_item_activated_1 : android.R.layout.simple_list_item_1;
// Create an array adapter for the list view, using the Ipsum headlines array
setListAdapter(new ArrayAdapter<String>(getActivity(), layout, Ipsum.Headlines));
}
@Override
public void onStart() {
super.onStart();
// When in landscape layout, set the listview to highlight the selected list item
// (We do this during onStart because at the point the listview is available.)
if (getFragmentManager().findFragmentById(R.id.article_fragment) != null) {
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
}
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception.
try {
mCallback = (OnHeadlineSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// TODO Auto-generated method stub
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public void onDestroy() {
Log.w("HeadlinesFragment", "inside onDestroy: " + this.toString());
super.onDestroy();
}
}
這裏是articlefragment
public class ArticleFragment extends Fragment {
final static String ARG_POSITION = "position";
int mCurrentPosition = 0;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.w("ArticleFragment", "inside onCreateView: " + this.toString());
if (savedInstanceState != null) {
mCurrentPosition = savedInstanceState.getInt(ARG_POSITION);
}
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.article_view, container, false);
return view;
}
@Override
public void onStart() {
super.onStart();
Bundle args = getArguments();
if (args != null) {
// Set article based on argument passed in
updateArticleView(args.getInt(ARG_POSITION));
} else if (mCurrentPosition != -1) {
// Set article based on saved instance state defined during onCreateView
updateArticleView(mCurrentPosition);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// Save the current article selection in case we need to recreate the fragment
outState.putInt(ARG_POSITION, mCurrentPosition);
}
@Override
public void onDestroy() {
Log.w("ArticleFragment", "inside onDestroy: " + this.toString());
super.onDestroy();
}
}
詳細問題是這樣的:
1)啓動應用程序縱向方向 2)調用setContentView並加載news_articles,但它帶有frag的一個ment_container。 3)headlinesfragment創建//到目前爲止正常行爲 4)改變方向爲橫向 5)mainActivity被破壞 - > headlinefragment被破壞 6)上mainactivity super.oncreate稱爲 7)Headlinefragment創建 8)的setContentView在主要活動被稱爲 9)另一個標題片段被創建//問題
我已經放置日誌,可以在上面的代碼中看到,這裏是當我在縱向模式中啓動應用程序,我改變爲風景的輸出。
W/MainActivity(6925): Before super.onCreate: [email protected]
W/MainActivity(6925): Before setContentView: [email protected]
W/HeadlinesFragment(6925): inside onCreate: HeadlinesFragment{41d8d4d8 #0 id=0x7f050001}
W/MainActivity(6925): inside onDestroy: [email protected]
W/HeadlinesFragment(6925): inside onDestroy: HeadlinesFragment{41d8d4d8 # 0id=0x7f050001}
W/MainActivity(6925): Before super.onCreate: [email protected]
W/HeadlinesFragment(6925): inside onCreate: HeadlinesFragment{41ea7290 #0 id=0x7f050001}
W/MainActivity(6925): Before setContentView: [email protected]
W/HeadlinesFragment(6925): inside onCreate: HeadlinesFragment{41eb1f30 #1 id=0x7f050002}
W/ArticleFragment(6925): inside onCreateView: ArticleFragment{41eb5f20 #2 id=0x7f050003}
我希望我已經與我的代碼和日誌清楚,在我看來super.oncreate和的setContentView都創建一個每一個headlinesfragment;至少我想。
我的問題是爲什麼會創建2個headlinesfragment實例,以及我如何避免這種情況。
,瞭解關於此次
感謝您的迴應,但是問題在於應用程序轉向橫向時,您所提供的代碼仍然無法執行。另外關於你給出的代碼,當應用程序第一次以縱向模式啓動時,savedInstanceState爲null,else塊被執行,所以如果我們從來沒有創建它,我們如何通過標記找到HeadlinesFragment? – 2013-05-12 16:03:50
我認爲如果陳述條件是倒退在這裏。如果存在已保存的實例狀態,則應找到現有片段。如果保存的實例狀態爲空,則應該創建一個新的片段。 – Razz 2015-04-09 15:24:40
@Razz是正確的。注意:如果savedInstanceState IS爲null,那麼您創建一個新的片段,否則片段已經存在!所以,只要將內部if語句更改爲if(savedInstanceState == null) – 2015-11-08 00:07:52