I created a test project that has two different fragments to be shown in the same activity. One fragment is for landscape and the other for portrait.
# My unique activity
public class MainActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
# First Fragment
public class LandscapeFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
TextView v = (TextView) inflater.inflate(R.layout.fragment, container, false);
v.setText("LANDSCAPE");
return v;
}
}
# Other Fragment
public class PortraitFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
TextView v = (TextView) inflater.inflate(R.layout.fragment, container, false);
v.setText("PORTRAIT");
return v;
}
}
And I have two main.xml, one in layout/ and the other in layout-land/. Each main.xml points to the correct Fragment to be used.
<!-- layout-land/main.xml -->
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment"
android:name="br.luckcheese.test.LandscapeFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp" />
<!-- layout/main.xml -->
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment"
android:name="br.luckcheese.test.PortraitFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp" />
<!-- layout/fragment.xml -->
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="30sp" />
When I open the app on landscape the LandscapeFragment is shown, and when I open in Portrait the PortraitFragment is shown. So far, so good.
But if I open in landscape and rotate the device to portrait then the LandscapeFragment is reloaded and shown.
Which is not the predicted behavior. The PortraitFragment should have been loaded.
And the same thing happens the other way around, if the device starts at the portrait orientation and then I rotate it to landscape: the PortraitFragment just gets reloaded, instead of having the LandscapeFragment loaded.
What am I doing wrong?
Make sure that you don't have: android:config="orientation" in your manifest.xml
The problem is in your 2 layouts, the fragment ids are the same.
Just change these fragment ids, like :
fragmentportrait for layout/main.xml
fragmentlanscape for layout-land/main.xml.
(And change also:
Fragment frag = getSupportFragmentManager().findFragmentById(R.id.fragment);
frag.setRetainInstance(false);
)
Related
I've an activity che contains a fragment, that I call fragment A.
When the screen is large enough, (layout-large) A shows two others fragment, B (a list of a products) and C (the details of the selected item from the list).
When the screen is not large enough, A shows only the fragment B, and when I click on some list item, it opens the fragment C with the selected product.
The problem is that when in portrait mode the fragment C is visible (the fragment vith details), if i change orientation, it comes back visible the fragment B (the list), but i would like to mantain the fragment C visible, in landscape mode.
How can i achieve this?
Here's some code:
Large screen
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal"
android:id="#+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="#+id/book_list_content"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"/>
<FrameLayout
android:id="#+id/book_details_content"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="3"/>
</LinearLayout>
Normal screen
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="#+id/book_list_content"
android:layout_below="#id/tool_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"/>
</LinearLayout>
And in the end the fragment A:
public class HomeFragment extends Fragment implements ListFragment.onBookSelectedListener {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedIstance){
return inflater.inflate(R.layout.drawer_fragments,container,false);
/*drawer_fragments is the name of the layout that i've posted above*/
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState){
if(savedInstanceState == null) {
ListFragment listfrag = new ListFragment();
FragmentManager fragManager = getChildFragmentManager();
fragManager.beginTransaction().replace(R.id.book_list_content, listfrag).commit();
if (view.findViewById(R.id.book_details_content) != null) {
/*Here if the screen is large enought to see also the details*/
fragManager.beginTransaction().replace(R.id.book_details_content, new DetailsFragment()).commit();
}
}
/*Other code...*/
}
In your Fragment_One
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
frameLayout = new FrameLayout(getActivity());
rootView = inflater.inflate(R.layout.fragment_home_page_updated, null);
frameLayout.addView(rootView);
initUI();
return frameLayout;
}
and make onConfigurationChange()
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setRetainInstance(true);
frameLayout.removeAllViews();
LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rootView = inflater.inflate(R.layout.fragment_home_page_updated, null);
frameLayout.addView(rootView);
initUI();
}
I am using a preference fragment and replacing the fragment in the id of the root layout of the main xml file. So my problem is that the preferences are displaying alongside with the main activity xml elements.
I have seen in Android apps that the preferences open up separately I am not sure whether they do open up separately or just occupying the entire screen. For opening the preference fragment I am doing a normal fragment transaction(Note: I am not using the support library not sure if this has something to do with my problem but still mentioning it).
Here is what the problem is,
And so here is my code
sampleprefs.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:defaultValue="false"
android:title="Check box preference"
android:key="check_box_preference_1" />
<EditTextPreference
android:defaultValue="Default value"
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="Edit text preference"
android:key="edit_text_preference_1" />
</PreferenceScreen>
Here is the main layout,
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.random.preferenceexample.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:id="#+id/textView" />
<Button
android:text="Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/button" />
</LinearLayout>
This is my Main Activity code where the fragment displays on the click of a button,
public class MainActivity extends Activity implements View.OnClickListener {
boolean result;
Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button)findViewById(R.id.button);
button.setOnClickListener(this);
}
#Override
public void onClick(View v) {
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
SettingsFragment sf = new SettingsFragment();
ft.add(R.id.activity_main,sf);
ft.commit();
}
This is the fragment class
public class SettingsFragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.sampleprefs);
}
}
It looks the problem seems to be with the background transparency of Fragment. Fragments are transparent backgrounded by default because they can be used to paint only a small portion of the screen but if you want your Fragment to cover fullscreen then just add some background to it, it will work.
Moreover, it's good practice to use a root layout which supports views to be placed one above the other(for ex. FrameLayout) for FragmentTransactions.
Add these in your Fragment :
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = super.onCreateView(inflater, container, savedInstanceState);
view.setBackgroundColor(getResources().getColor(android.R.color.white));
return view;
}
Here is the working example
I have made a ListView on a Fragment.
public class MyList extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.mylist, container, false);
return view;
}
}
This is the xml file where is the ListView:
<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ddffff"
xmlns:app="http://schemas.android.com/apk/res-auto"
>>
<android.support.wearable.view.WearableListView
android:id="#+id/mylist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="none"></android.support.wearable.view.WearableListView>
</android.support.wearable.view.BoxInsetLayout>
When I run my app the listview does not appear. The entire screen is black. What I want to know is why this is happening.
Because of the typo in the following line:
xmlns:app="http://schemas.android.com/apk/res-auto"
>>
It cannot read >>. Android doesn't throw an exception for this typo
I have a Fragment in my MainActivity, that displays a Digital Clock. It works: It shows the current system time. But it looks rather simple. So before I start trying to style this clock I wanted to ask, if there is a way, to use the systems Digital-Clock Widget?
Screenshot of the widget, that I'd like to use in my Fragment:
FragmentClock.java:
public class FragmentClock extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View view = inflater.inflate(R.layout.fragment_clock, container, false);
return view;
}
}
fragment_clock.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LinearLayoutClockDisplay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#000000">
<DigitalClock
android:id="#+id/digital_clock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"/>
</LinearLayout>
Is is possible to use the android dashboard pattern from Google I/O as a fragment so that in landscape mode on a tablet the dashboard is shown on the left while the content of the current category is shown on the right?
I've tried something that looks like the code below but it doesnt work.
main.xml:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Include dashboard -->
<include layout="#layout/fragment_dashboard"/>
<!-- Include details -->
<fragment
android:id="#+id/fragment_details"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.example.fragments.Details" />
</LinearLayout>
Details.java:
public class Details extends Fragment
{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.details, container, false);
return view;
}
}