I have problem when I try to use fragment on screen rotate
My code is come from FragmentBasics on android training with Fragment, but I instead layout-large with layout-land
res/layout-land/activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:baselineAligned="false" >
<fragment
android:id="@+id/headlines_fragment"
android:name="com.example.fragmentoverhoneycomb.HeadlinesFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<fragment
android:id="@+id/article_fragment"
android:name="com.example.fragmentoverhoneycomb.Articles"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2" />
MainActivity
public class MainActivity extends Activity
implements OnHeadlineSelectedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(findViewById(R.id.fragment_container) != null) {
if (savedInstanceState != null) {
return;
}
HeadlinesFragment firstFragment = new HeadlinesFragment();
firstFragment.setArguments(getIntent().getExtras());
getFragmentManager().beginTransaction().add(R.id.fragment_container, firstFragment).commit();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void onArticleSelected(int position) {
// TODO Auto-generated method stub
Articles articleFrag = (Articles) getFragmentManager().findFragmentById(R.id.article_fragment);
if (articleFrag != null) {
articleFrag.updateArticleView(position);
} else {
Articles newFragment = new Articles();
Bundle args = new Bundle();
args.putInt(Articles.ARG_POSITION, position);
newFragment.setArguments(args);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
transaction.commit();
}
}
Articles.java
public class Articles extends Fragment {
final static String ARG_POSITION = "position";
int mCurrentPosition = -1;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (savedInstanceState != null) {
mCurrentPosition = savedInstanceState.getInt(ARG_POSITION);
}
return inflater.inflate(R.layout.activity_article, container, false);
}
@Override
public void onDestroyView() {
super.onDestroyView();
}
@Override
public void onStart() {
super.onStart();
Bundle args = getArguments();
if(args != null) {
updateArticleView(args.getInt(ARG_POSITION));
} else if (mCurrentPosition != -1) {
updateArticleView(mCurrentPosition);
}
}
public void updateArticleView(int position) {
TextView article = (TextView) getActivity().findViewById(R.id.textViewArticle);
article.setText(Ipsum.Articles[position]);
mCurrentPosition = position;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(ARG_POSITION, mCurrentPosition);
}
}
So my idea is use single fragment when portrait and combine two fragment when landscape, but I get a error when I do this:
Step.1 start with portrait state and show article_fragment via onArticleSelected once to show a article and then return to the HeadlinesFragment
Step.2 Ctrl-F11 twice (portrait -> landscape -> portrait)
Step.3 redo Step.1 then the error occurs:
Articles articleFrag = (Articles) getFragmentManager().findFragmentById(R.id.article_fragment);
return not null when I debug this, I found the onCreateView() function didn't called when Step.3 occurrs
You create your fragment in the code which means you can't give it any id so the fragment cannot be found. You can use the tag of the fragment to identify it by using an overloaded add
method to give it a tag:
getFragmentManager().beginTransaction()
.add(R.id.fragment_container, firstFragment, "fragmenttag").commit();
You can then find your fragment by this tag:
Articles articleFrag = (Articles) getFragmentManager().findFragmentByTag("fragmenttag");
It will be best to make the fragment tag a constant.