On Back Pressed in Android Fragments - java

I have One Activity
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Activities.Dashboard.MainActivity">
<FrameLayout
android:id="#+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</RelativeLayout>
And I have 10 Fragments i show them in main_container Frame Layout
How can i write code to go back to last fragment
This is my Activity code :
public class MainActivity extends AppCompatActivity{
#Override
protected void onCreate(Bundle savedInstanceState) {
fragmentManager = getSupportFragmentManager();
fragment = new HomeFragment();
final FragmentTransaction transaction =
fragmentManager.beginTransaction();
transaction.replace(R.id.main_container, fragment).commit();
}
}
In Home Fragment :
public class HomeFragment extends Fragment{
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.bottom_bar_home, container, false);
fragmentManager = getActivity().getSupportFragmentManager();
// ...... etc
return view;
}
}
and all fragments the same code with another data.

It worked to me by this code :
I put in Base Activity :
#Override
public void onBackPressed() {
int count = getFragmentManager().getBackStackEntryCount();
if (count == 0) {
super.onBackPressed();
} else {
getFragmentManager().popBackStack();
}
}
And every call for fragment i put AddtoBackStack(null) :
fragment = new yourFragment();
final FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.main_container,
fragment).addToBackStack(null).commit();

Try this:
if( getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStack();
return;
}
super.onBackPressed();
You should read this related question as well:

Related

How to use Helpshift Embeddable Support Fragments Android

I am building an Android app that uses the Helpshift API. It was all working, but I am currently trying to move everything into a TabLayout, using Fragments and an ActionBar. I made a mini app to figure out functionality of the fragments without messing everything else up. I have a home screen where you click a button and it starts the activity containing the TabLayout with the Fragments. I cannot figure out how to make the embeddable support fragments show up in the TabLayout. I'm pretty new to Android, so sorry if my code is not the best. Right now the placeholder is not being replaced in the fragment transaction, and I can't figure out why. I would greatly appreciate any advice! Thank you :) Let me know if I can provide anything else
Here is my main activity class (Helpshift info has been redacted for privacy reasons, hopefully my issue can still be fixed)
public class MainActivity extends AppCompatActivity {
Context mContext;
public ConstraintLayout layout;
Activity goToFragment;
public Button start;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home_screen);
mContext = getApplicationContext();
goToFragment = MainActivity.this;
start = (Button) findViewById(R.id.button);
start.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick (View view) {
launchFragments();
}
});
//HELPSHIFT SET UP
Core.init(All.getInstance());
InstallConfig installConfig = new InstallConfig.Builder()
.setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE)
.setEnableInAppNotification(true)
.build();
try {
Core.install(getApplication(),
"****APIKEY*****",
"****DOMAIN*****",
"****APPID******", installConfig);
} catch (InstallException e) {
android.util.Log.e("Helpshift", "install call : ", e);
}
}
private void launchFragments() {
Intent intent1 = new Intent(mContext, HomeTab.class);
intent1.putExtra("fragmentNumber", 0);
startActivity(intent1);
}
}
Here is my ViewPager Adapter class:
public class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager){
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
Here is my fragment activity class:
public class HomeTab extends AppCompatActivity {
// ImageButton FindCareButton;
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
public Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = getApplicationContext();
Intent intent1 = getIntent();
int var = intent1.getIntExtra("fragmentNumber", 0);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
viewPager.setCurrentItem(var);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
if (findViewById(R.id.placeholder) != null) {
if (savedInstanceState != null) {
return;
}
Fragment faqFragment = new Fragment();
faqFragment = Support.getFAQsFragment(HomeTab.this);
getSupportFragmentManager().beginTransaction().add(R.id.placeholder, faqFragment).commit();
}
}
private void setupViewPager(ViewPager viewPager){
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new FAQTab(), "FAQ");
viewPager.setAdapter(adapter);
}
}
Here is my FAQTab class:
public class FAQTab extends Fragment {
public FAQTab(){
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.faq_tab, container, false);
}
}
For layouts, my faq_tab layout is an empty FrameLayout with id "placeholder"
My home_screen layout is a ConstraintLayout with a button (id "button")
And here is my activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.sasha.fragment_tester.MainActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/BarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:background="?android:attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabGravity="fill"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
/>
</android.support.design.widget.CoordinatorLayout>

Android Dynamic Fragments

I have a activity with only 2 buttons and a FrameLayout:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="#+id/linearLayout">
<Button
android:id="#+id/btPrincipal1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Ver Fragment 1"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
/>
<Button
android:id="#+id/btPrincipal2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Ver Fragment 2"
android:layout_gravity="center_horizontal"
android:layout_weight="1"/>
</LinearLayout>
<FrameLayout
android:layout_width="250dp"
android:layout_height="match_parent"
android:id="#+id/contenedor"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_below="#+id/linearLayout">
</FrameLayout>
When I click button 1, I call the fragment and, when I click button 2, I want to call the same fragment but with different properties. For example:
I click button 1 , call fragment A with background color green.
I click button 2 , call fragment A with background color red.
It's possible? and how can I do this? Thanks.
In your MainActivity, do:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button1 = (Button) findViewById(R.id.btPrincipal1);
Button button2 = (Button) findViewById(R.id.btPrincipal2);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FragmentManager supportFragmentManager = getSupportFragmentManager();
Bundle bundle = new Bundle();
bundle.putString(COLOR_PARAM, "green");
supportFragmentManager.beginTransaction()
.replace(R.id.contenedor, YourFragment.newInstance("Button1"))
.commit();
}
});
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FragmentManager supportFragmentManager = getSupportFragmentManager();
Bundle bundle = new Bundle();
bundle.putString(COLOR_PARAM, "red");
supportFragmentManager.beginTransaction()
.replace(R.id.contenedor, YourFragment.newInstance("Button2"))
.commit();
}
});
}
Then, in YourFragment.java, do:
public class YourFragment extends Fragment {
public static final String COLOR_PARAM = "param1";
private String currentColor;
public YourFragment() {}
public static Fragment newInstance(String param) {
Fragment fragment = new Fragment();
Bundle args = new Bundle();
args.putString(COLOR_PARAM, param);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
currentColor = getArguments().getString(COLOR_PARAM);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.your_fragment_layout, container, false);
FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.fragment_layout);
if (currentColor.equals("green")) {
frameLayout.setBackgroundColor(getActivity().getResources().getColor(android.R.color.holo_green_dark));
}
else if (currentColor.equals("red")) {
frameLayout.setBackgroundColor(getActivity().getResources().getColor(android.R.color.holo_red_dark));
}
return view;
}
}
If you want to change the background just create and object of your fragment, and after clicking on buttons call a method to change the fragment background. but if you wanna to change fragments layout or other things create a new fragment cause of code readability.
try this:
public class FragmentA extends Fragment {
public static FragmentA newInstance(int colorResId) {
FragmentA fragment = new FragmentA();
Bundle bundle = new Bundle();
bundle.putInt("colorId", colorResId);
fragment.setArguments(bundle);
return new FragmentA();
}
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
int resId = getArguments().getInt("colorId", 0);
if (resId != 0) {
//set background
}
}
public void changeBackground(int colorId){
//set background
}
}

Android app using OnClickListener closes on startActivity(intent)

I have an OnClickListener in a fragment activity as shown here:
public class Menu1_Fragment extends Fragment {
Button CreateGroupButton;
View rootview;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootview = inflater.inflate(R.layout.menu1_layout, container, false);
CreateGroupButton = (Button) rootview.findViewById(R.id.create_study_group);
CreateGroupButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
Toast.makeText(getActivity().getApplicationContext(), "Test", Toast.LENGTH_LONG).show();
Intent intent = new Intent(Menu1_Fragment.this.getActivity(), CreateGroup.class);
startActivity(intent);
}
});
return rootview;
}
}
Here is my menu1_layout.xml code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:gravity="center_horizontal">
<Button
android:id="#+id/create_study_group"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/CreateGroupBtn"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="This is the page where you can create and view existing groups"
android:id="#+id/textView"
android:layout_below="#+id/create_study_group"/>
</RelativeLayout>
When the Button is clicked, the "Test" message is displayed but the app closes right after.
Here is the CreateGroup java class:
public class CreateGroup extends Fragment{
View rootview;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootview = inflater.inflate(R.layout.create_group, container, false);
return rootview;
}
}
and the create_group.xml file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:gravity="center_horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="This is the page where the form is displayed"
android:id="#+id/textView"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
NavigationActivity:
public class NavigationActivity extends FragmentActivity
implements NavigationDrawerFragment.NavigationDrawerCallbacks {
/**
* Fragment managing the behaviors, interactions and presentation of the navigation drawer.
*/
private NavigationDrawerFragment mNavigationDrawerFragment;
/**
* Used to store the last screen title. For use in {#link #restoreActionBar()}.
*/
private CharSequence mTitle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_navigation);
FragmentManager fragmentManager = getSupportFragmentManager();
mNavigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
}
#Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager =getSupportFragmentManager();
Fragment fragment= new Fragment();
switch (position){
case 0:
mTitle = getString(R.string.title_section1);
fragment = new Menu1_Fragment();
break;
case 1:
mTitle = getString(R.string.title_section2);
fragment = new Menu2_Fragment();
break;
}
fragmentManager.beginTransaction()
.replace(R.id.container, fragment)
.commit();
}
public void onSectionAttached(int number) {
switch (number) {
case 1:
mTitle = getString(R.string.title_section1);
break;
case 2:
mTitle = getString(R.string.title_section2);
break;
case 3:
mTitle = getString(R.string.title_section3);
break;
}
}
public void restoreActionBar() {
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.navigation, menu);
restoreActionBar();
return true;
}
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
//if the log out button is selected, log out of Parse and go back to log in page
if (id == R.id.action_logout) {
ParseUser.logOut();
Intent intent = new Intent(NavigationActivity.this,LoginSignupActivity.class);
startActivity(intent);
Toast.makeText(getApplicationContext(), "Successfully Logged out", Toast.LENGTH_LONG).show();
finish();
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_navigation, container, false);
return rootView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((NavigationActivity) activity).onSectionAttached(
getArguments().getInt(ARG_SECTION_NUMBER));
}
}
}
I'm having trouble figuring out why the CreateGroup class/layout file aren't being displayed as a new page.
The CreateGroup class is a fragment , the intent should be using an activity if startActivity is being used
CreateGroup is a fragment, so you should change fragments and not start an activity:
CreateGroupButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view){
Toast.makeText(getActivity().getApplicationContext(), "Test", Toast.LENGTH_LONG).show();
// Create new fragment and transaction
Fragment createGroupFragment = new CreateGroup();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, createGroupFragment)
.commit();
}
});

Retain getChildFragmentManager navigation stack after removing and re-adding fragment

I have activity:
`<RelativeLayout>
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<Button/>
<Button/>
</RelativeLayout>`
Inside this container, depending on which button pressed appear FragmentA or FragmentB. These fragments are containers for nested child-fragments. I.e. in each fragment contains its own navigation stack.
In onCreate of Activity I instantiate these 2 fragments:
fragmentA = (FragmentContainer) Fragment.instantiate(this, FragmentContainer.class.getName());
fragmentB = (FragmentContainer) Fragment.instantiate(this, FragmentContainer.class.getName());
Then, I'm continue replacing one each other:
final FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction()
.replace(R.id.container, fragment);
.commitAllowingStateLoss();
So far, so good, everything is working. BUT
Problem:
Every time I replace fragmentA by fragmentB (and vice verse) - getChildFragmentManager() destroy its navigation stack and fragmentA/B starts every time from scratch, not with the nested fragment it contained before being replaced.
Any ideas? Is it doable, at least?
Have a brilliant day,
Konstantin
So that's how I solved this:
MainActivity.xml
<RelativeLayout>
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
MainActivity.java
public class MainActivity extends FragmentActivity {
final FragmentContainer [] fragmentContainers = new FragmentContainer[3];
int currentTabIndex = -1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final FragmentMetaData [] fragmentContainersMetaData = {
new FragmentMetaData(FragmentA.class.getName(), null),
new FragmentMetaData(FragmentB.class.getName(), null),
new FragmentMetaData(FragmentC.class.getName(), null)
};
for (int i = 0; i < fragmentContainers.length; i++) {
fragmentContainers[i] = (FragmentContainer) Fragment.instantiate(this, FragmentContainer.class.getName());
fragmentContainers[i].addMetaData(fragmentContainersMetaData[i]);
}
tabPageNavigationSelection(0);
}
void replaceFragmentBy(final Fragment fragment) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container, fragment);
fragmentTransaction.commitAllowingStateLoss();
}
// Method to switch between tabs
void tabPageNavigationSelection (final int index) {
if (currentTabIndex == index) {
fragmentContainers[currentTabIndex].clearStackExceptRootFragment();
} else {
currentTabIndex = index;
replaceFragmentBy(fragmentContainers[currentTabIndex]);
}
}
}
FragmentContainer.xml
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#color/lightest_gray"
android:id="#+id/nestedContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
FragmentContainer.java
public final class FragmentContainer extends Fragment {
private final List<FragmentMetaData> fragmentMetaDataStack = new ArrayList<>();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
initialize(inflater, container, R.layout.fragment_container);
for (FragmentMetaData metaData : fragmentMetaDataStack) {
showNestedFragment(Fragment.instantiate(getActivity(), metaData.className, metaData.fragmentBundle), fragmentMetaDataStack.indexOf(metaData) > 0, true);
}
return getFragmentView();
}
#Override
public void onResume() {
super.onResume();
if (getChildFragmentManager().getFragments() == null){
return;
}
int stackDepth = getChildFragmentManager().getFragments().size();
if (stackDepth > 0 && fragmentMetaDataStack.size() < stackDepth &&
getChildFragmentManager().getFragments().get(fragmentMetaDataStack.size() - 1) != null) {
getChildFragmentManager().getFragments().get(fragmentMetaDataStack.size()-1).onResume();
}
}
public void showNestedFragment(final Fragment fragment, final boolean addToBackStack, final boolean isRestoring) {
final FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.nestedContainer, fragment);
if (addToBackStack) {
fragmentTransaction.addToBackStack(null);
}
if (!isRestoring) {
fragmentMetaDataStack.add(new FragmentMetaData(fragment.getClass().getName(), fragment.getArguments()));
}
fragmentTransaction.commitAllowingStateLoss();
}
public void onBackPressed() {
if (getChildFragmentManager().getBackStackEntryCount() > 0) {
getChildFragmentManager().popBackStack();
fragmentMetaDataStack.remove(fragmentMetaDataStack.size() - 1);
} else {
getActivity().finish();
}
}
public void addMetaData(FragmentMetaData metaData) {
fragmentMetaDataStack.add(metaData);
}
public void clearStackExceptRootFragment() {
getChildFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
while (fragmentMetaDataStack.size() > 1) {
fragmentMetaDataStack.remove(1);
}
}
}
Hopefully, it would help someone, who's trying to copy instagram navigation model :)

No view found for fragment

A number of people have queried on fixing fragments but my confusion may be based on the evolving nature of fragment APIs or I simply misunderstand them. I am pruning this code to show an attempt to how I am trying to use fragments to have multiple layouts on a big screen or a single layout on a smaller screen that goes to other layouts via buttons. The essential portion of my log is
12-03 21:17:29.711: E/FragmentManager(13440): No view found for id 0x7f090046
(com.ruleagents.rpgsheet:id/main_fragment) for fragment MainFragment{4053b368 #0 ....
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.ruleagents.rpgsheet/com.ruleagents.rpgsheet.SheetActivity}:
java.lang.IllegalArgumentException: No view found for id 0x7f090046
(com.ruleagents.rpgsheet:id/main_fragment) for fragment MainFragment{4053b368 #0 id=0x7f090046}
12-03 21:17:29.721: E/AndroidRuntime(13440): at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1821)
My activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="#+id/container"
android:layout_width="0px"
android:layout_height="match_parent"
tools:context="com.ruleagents.rpgsheet.MainActivity"
tools:ignore="MergeRootFrame" />
</RelativeLayout>
attribute_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/linear1">
... nested layout that works independently
</LinearLayout>
main_fragment.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:id="#+id/main_fragment" >
<LinearLayout
...
</LinearLayout>
<LinearLayout
...
</LinearLayout>
<LinearLayout
...
</RelativeLayout>
With my MainActivity.java as:
package com.ruleagents.rpgsheet;
import java.io.BufferedReader;
...
public class MainActivity extends FragmentActivity { //ActionBarActivity {
SectionsPagerAdapter mSectionsPagerAdapter;
FragmentManager fragmentManager; // = getFragmentManager();
AttributeFragment af = new AttributeFragment();
MainFragment mf = new MainFragment();
String characterClass, level, att1, att2, att3;
//other local variables
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_fragment);
Configuration config = getResources().getConfiguration();
af.setArguments(getIntent().getExtras());
mf.setArguments(getIntent().getExtras());
fragmentManager = getSupportFragmentManager();
if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
fragmentManager.beginTransaction().add(R.id.main_fragment, mf).commit();
fragmentManager.beginTransaction().add(R.layout.attribute_fragment, af).commit();
}else{
System.err.println("AAA creating portrait view");
fragmentManager.beginTransaction().add(R.id.container, mf).commit();
}
}
public void onMainButton(View view) {
android.support.v4.app.FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.id.main_fragment, mf);
ft.addToBackStack(null);
ft.commit();
}
public void onAttributesButton(View view) {
android.support.v4.app.FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.layout.attribute_fragment, af);
ft.addToBackStack(null);
ft.commit();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
// Unused PlaceholderFragment method ...
// unused FragmentPageAdapter ...
// local methods
}
My MainFragment.java
package com.ruleagents.rpgsheet;
... imports
public class MainFragment extends Fragment {
public MainFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
return inflater.inflate(R.layout.main_fragment, container, false);
}
#Override
public void onPause() {
super.onPause();
}
}
My SheetActivity.java
package com.ruleagents.rpgsheet;
... imports
public class SheetActivity extends ActionBarActivity {
// Local variables...
FragmentManager fragmentManager; // = getFragmentManager();
AttributeFragment af = new AttributeFragment();
MainFragment mf = new MainFragment();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.err.println("AAA in onCreate of SheetActivity");
Configuration config = getResources().getConfiguration();
//FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
//setContentView(R.layout.activity_main);
//setContentView(R.layout.whole_sheet);
System.err.println("AAA got config");
af.setArguments(getIntent().getExtras());
mf.setArguments(getIntent().getExtras());
fragmentManager = getSupportFragmentManager();
System.err.println("AAA got frag manager");
if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
fragmentManager.beginTransaction().add(R.id.container, mf).commit();
fragmentManager.beginTransaction().add(R.id.container, af).commit();
}else{
System.err.println("AAA creating portrait view");
fragmentManager.beginTransaction().add(R.id.main_fragment, mf).commit();
}
}
public void onMainButton(View view) {
android.support.v4.app.FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.id.main_fragment, mf);
ft.addToBackStack(null);
ft.commit();
}
public void onSkillsButton(View view) {
android.support.v4.app.FragmentTransaction ft = fragmentManager.beginTransaction();
ft.addToBackStack(null);
ft.commit();
}
public void onAttributesButton(View view) {
android.support.v4.app.FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.layout.attribute_fragment, af);
ft.addToBackStack(null);
ft.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 boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
// Local methods ...
// Unused PlaceholderFragment ...
// Unused SectionsPagerAdapter
}
When you are adding a fragment, the add() method needs the container id be in your activity layout that the fragment will go into. So, your error is because there is no main_fragment id in your activity_main.xml.

Categories

Resources