我有这个奇怪的问题,其中我的列表片段创建了两次,一次是在父活动上调用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