java - Portrait layout doesnt work when activity starts in landscape -
this scaled down version of actual problem. recreate difficulty facing.
i have taken example official website developer.android.com cite problem. building flexible ui
mainactivity has 2 layouts. 1 default(portrait in small screen devices) layout in layout folder. other layout both large-screen , landscape mode, kept in layout-large , layout-land folder.
default layout activity_main.xml contains 1 framelayout (r.id.fragment_container) in add , replace 2 fragments create, dynamically.
the other layout same both layout-land , layout-large folders. has 2 static fragments [r.id.headlines_fragment - display list of headlines] , [r.id.article_fragment - display details when headlines selected]. horizontally placed. 1 on left show lists , 1 on right show details.
this code mainactivity.java controls fragments :
public class mainactivity extends activity implements onheadlineselectedlistener { @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.news_article); 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 void onarticleselected(int position) { articlefragment articlefrag = (articlefragment) getfragmentmanager().findfragmentbyid(r.id.article_fragment); if(articlefrag != null && articlefrag.isvisible()) { articlefrag.updatearticleview(position); } else { articlefrag = new articlefragment(); fragmenttransaction transaction = getfragmentmanager().begintransaction().replace(r.id.fragment_container, articlefrag); transaction.addtobackstack(null); transaction.commit(); } } } as activity started, check if fragment_container framelayout present or not. if not present, layout 2 fragments has been loaded. hence no need add fragments dynamicaly present.
otherwise, check if savedinstancestate null or not. if null, create new headlinesfragment , add frame. if not null, means activity has been created previously, , hence headlinesfragment must have been added already. no need add again. so, return.
and onarticleselected() method replaces existing fragment in frame articlefragment, or if in other layout, updates fragment present. called headlinesfragment when item selected.
now, works if enter activity in portrait mode , change orientation. no problem. flawless.
but if enter activity in landscape mode, change orientation portrait mode, blank screen shown.
the reason being, oncreate() called, , savedinstancestate returns not null. hence, headlinesfragment not created , added frame.
and yes, if remove check, app works fine, mean new headlinesfragment created , added frame each time , gets stacked on top of eachother. not @ desirable.
i cannot implement finding out orientation , applying appropriate layout. because, in large-screen devices, if in portrait mode, supposed show both fragments @ once.
i have tried many convoluted logic. nothing seems work. appreciated.
entering activity in portrait mode
1> list items shown.
2> clicking items replaces fragment articlefragment (details).
3> changing orientation, shows both side side. works.
entering activity in landscape mode
1> both list , details shown. works.
2> orientation changes, blank screen. headlines fragment not created , added.
it helpful if guide me how can solve problem. , actual project huge, , logic has been implemented, drastic change in logic not option anymore mean re writting thousands of lines of code. thank you. :)
ok. got problem. problem using fragments in xml layouts in large devices.
<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" /> </linearlayout> so android trying catch fragments in savedinstancestate in mainactivity. when screen rotates, system tries restore above fragments though different layout loads in potrait mode. , system considers article_fragment available on right side , tries update on click on headline.
so, what's solution ?
i have changed little code in mainactivity , nothing else :-)
/** called when activity first created. */ @override public void oncreate(bundle savedinstancestate) { super.oncreate(null); setcontentview(r.layout.news_articles); // check whether activity using layout version // fragment_container framelayout. if so, must add first fragment if (findviewbyid(r.id.fragment_container) != null) { // however, if we're being restored previous state, // don't need , should return or else // end overlapping fragments. /*if (savedinstancestate != null) { return; }*/ // create instance of examplefragment headlinesfragment firstfragment = new headlinesfragment(); // in case activity started special instructions intent, // pass intent's extras fragment arguments firstfragment.setarguments(getintent().getextras()); // add fragment 'fragment_container' framelayout getsupportfragmentmanager().begintransaction() .add(r.id.fragment_container, firstfragment).commit(); } } so have done told system don't want thing restored using super.oncreate(null); restoring nothing now.
about blank screen getting
whenever start activity in landscape mode. loads large display default. without entering if satement. because can't fragment_container in landscape mode. , rotate screen load portrait layout , system gets savedinstancestate != null , returns without loading headlinesfragment. bank screen.
so have commented if statement can notice.
/*if (savedinstancestate != null) { return; }*/ so load correctly. no issue





Comments
Post a Comment