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.
Related
Disclaimer: This is the first app I am building so I am learning the hard way to use fragments first, so my code is all over the place.
I have menu items inside a navigation view that loads fine however the menu item clicks don't work. It doesn't crash it just stares at me. I would like to use an intent to display a fragment and I am lost from changing and trying so many different options.
XML FOR NAV DRAWER & MENU ITEMS:
<android.support.v4.widget.DrawerLayout
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_pageone"
android:background="#drawable/rygg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarThumbVertical="#color/primary_dark_color"
tools:openDrawer="start"
tools:context="com.android.nohiccupsbeta.pageone">
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.design.widget.NavigationView
android:id="#+id/navigation_header_container"
app:headerLayout="#layout/header"
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:itemIconTint="#color/category_vodka"
app:itemTextColor="#color/primary_dark_color"
app:menu="#menu/drawermenu"
android:layout_gravity="start" >
</android.support.design.widget.NavigationView>
</FrameLayout>
</android.support.v4.widget.DrawerLayout>
JAVA:
public class pageone extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
DrawerLayout mDrawerLayout;
ActionBarDrawerToggle mToggle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pageone);
setupDrawer();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mToggle.onConfigurationChanged(newConfig);
}
#Override
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.drawermenu, menu);
return true;
}
/**
*
* #param item For the hamburger button
* #return
*/
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mToggle.onOptionsItemSelected(item)){
return true;
}
switch (item.getItemId()) {
case R.id.itemWhiskey:
Intent whiskeyIntent = new Intent(pageone.this, whiskeyActivity.class);
startActivity(whiskeyIntent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/**
* Make sure the drawer open and closes in sync with UI visual
* #param savedInstanceState
*/
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mToggle.syncState();
}
/**
* Function to make sure all the drawer open & closes properly
*/
public void setupDrawer() {
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mDrawerLayout = (DrawerLayout) findViewById(R.id.activity_pageone);
mToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.drawer_open, R.string.drawer_closed) {
#Override
public void onDrawerClosed(View closeView) {
Toast.makeText(pageone.this, "Happy You Learned", Toast.LENGTH_SHORT).show();
super.onDrawerClosed(closeView);
invalidateOptionsMenu();
}
#Override
public void onDrawerOpened(View openView) {
Toast.makeText(pageone.this, "Effects Of Alcohol", Toast.LENGTH_SHORT).show();
super.onDrawerOpened(openView);
invalidateOptionsMenu();
}
};
mDrawerLayout.addDrawerListener(mToggle);
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
MenuItem itemWhiskey = (MenuItem) findViewById(R.id.itemWhiskey);
itemWhiskey.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem itemWhiskey) {
FragmentManager fm = getSupportFragmentManager();
Fragment effectsFragment = fm.findFragmentById(R.id.frame_container2);
if (effectsFragment == null) {
effectsFragment = new WhiskeyFragment();
fm.beginTransaction().add(R.id.frame_container2, effectsFragment).commit();
getSupportActionBar().setTitle("Whiskey");
itemWhiskey.setChecked(true);
mDrawerLayout.closeDrawers();
}
return true;
}
});
mDrawerLayout.closeDrawer(GravityCompat.START);
return true;
}
}
XML FOR FRAGMENT:
<FrameLayout 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:id="#+id/frame_container2"
tools:context="com.android.nohiccupsbeta.WhiskeyFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="#+id/frag_whiskey_skin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="8dp"
android:textColor="#000000"
android:textSize="16sp" />
<ImageButton
android:id="#+id/expand_collapse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:background="#android:color/transparent"
android:src="#drawable/ic_expand_more"
android:padding="16dp"/>
</FrameLayout>
JAVA:
public class WhiskeyFragment extends Fragment {
private TextView mWhiskeySkin;
#Override
public void onViewCreated(View view, #Nullable Bundle SavedInstanceState) {
super.onViewCreated(view, SavedInstanceState);
getActivity().setTitle("WHISKEY EFFECTS");
mWhiskeySkin = (TextView) view.findViewById(R.id.frag_whiskey_skin);
mWhiskeySkin.setText(R.string.whiskey_skin);
hasOptionsMenu();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_whiskey, container, false);
hasOptionsMenu();
return v;
}
}
XML FOR SECOND ACTIVITY:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
JAVA:
public class whiskeyActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_whiskey);
}
public class Whiskeyed {
private String whiskeySkin;
private String whiskeyBrain;
public String getWhiskeySkin(){
return whiskeySkin;
}
public String getWhikeyBrain(){
return whiskeyBrain;
}
public void setWhiskeySkin(String whiskey_skin){
this.whiskeySkin = whiskey_skin;
}
public void setWhiskeyBrain(String whiskeyBrain) {
this.whiskeyBrain = whiskeyBrain;
}
}
}
try to change to content of your onNavigationItemSelected of your pageone.java
from here:
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
MenuItem itemWhiskey = (MenuItem) findViewById(R.id.itemWhiskey);
itemWhiskey.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem itemWhiskey) {
FragmentManager fm = getSupportFragmentManager();
Fragment effectsFragment = fm.findFragmentById(R.id.frame_container2);
if (effectsFragment == null) {
effectsFragment = new WhiskeyFragment();
fm.beginTransaction().add(R.id.frame_container2, effectsFragment).commit();
getSupportActionBar().setTitle("Whiskey");
itemWhiskey.setChecked(true);
mDrawerLayout.closeDrawers();
}
return true;
}
});
mDrawerLayout.closeDrawer(GravityCompat.START);
return true;
}
to here:
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
DrawerLayout mDrawerLayout = (DrawerLayout) findViewById(R.id.activity_pageone); // ID of your drawerLayout
int id = item.getItemId();
switch (id) {
case R.id.menu1: // Change this as your menuitem in menu.xml.
// Your fragment code goes here..
FragmentManager fm = getSupportFragmentManager();
Fragment effectsFragment = fm.findFragmentById(R.id.frame_container2);
if (effectsFragment == null) {
effectsFragment = new WhiskeyFragment();
fm.beginTransaction().add(R.id.frame_container2, effectsFragment).commit();
getSupportActionBar().setTitle("Whiskey");
itemWhiskey.setChecked(true);
mDrawerLayout.closeDrawers();
}
break;
case R.id.menu2: // Change this as your menuitem in menu.xml.
// or Your fragment code goes here...
break;
}
mDrawerLayout.closeDrawer(GravityCompat.START, true);
return true;
}
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:
I have a problem with fragments and the ViewPager, my ViewPager is composed of five tabs, each one is a Fragment.
On the first load I don't have problem with these load, but when I open another fragment (Ahead the main), and go back to the main, the fragments where I was, and those, has been removed (invisible).
For fix that I need to "get away" for two pages before the central page loads.
Everything is only in API 21 (5.0.1), with Android Studio.
MainActivity.java:
public class MainActivity extends FragmentActivity {
private MainActivityFragment frag_MainActivity;
private CreditsFragment frag_Credits;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
frag_MainActivity = new MainActivityFragment(this);
frag_Credits = new CreditsFragment();
switchFrag("main");
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_home) {
switchFrag("main");
return true;
} else if (id == R.id.action_credits) {
switchFrag("credits");
return true;
}
return super.onOptionsItemSelected(item);
}
public void switchFrag(String view){
Fragment frag = new Fragment();
if(view.equals("main")){
getActionBar().show();
frag = new MainActivityFragment(this);
} else if(view.equals("credits")){
getActionBar().hide();
frag = new CreditsFragment();
}
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, frag)
.addToBackStack(null).commit();
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
switchFrag("main");
return true;
}
return super.onKeyUp(keyCode, event);
}
public void closeApp() {
finish();
System.exit(0);
}
And the XML (activity_main.xml):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</RelativeLayout>
MainActivityFragment.java:
public class MainActivityFragment extends Fragment implements ActionBar.TabListener {
private ViewPager viewPager;
private MyAdapter mAdapter;
private ActionBar actionBar;
private String[] tabs = { "Lun", "Mar", "Merc", "Gio", "Ven"};
MainActivity main;
public MainActivityFragment(MainActivity instance) {
main = instance;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
viewPager = (ViewPager) main.findViewById(R.id.pager);
actionBar = main.getActionBar();
mAdapter = new MyAdapter(main.getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
if(actionBar.getTabCount() == 0){
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setText(tab_name)
.setTabListener(this));
}
}
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main, container, false);
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {}
XML (fragment_settings.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"
tools:context=".MainActivityFragment">
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
If the Adapter is needed, here it is:
public class MyAdapter extends FragmentPagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return 5;
}
#Override
public android.support.v4.app.Fragment getItem(int position) {
switch(position){
case 0:
return new LunFragment();
case 1:
return new MarFragment();
case 2:
return new MerFragment();
case 3:
return new GioFragment();
case 4:
return new VenFragment();
}
return null;
}
}
Replace mAdapter = new MyAdapter(main.getSupportFragmentManager()); with mAdapter = new MyAdapter(main.getChildFragmentManager());. You need to create the fragments as inner fragments of your MainActivityFragment.
LogCat Error:
https://github.com/Heromine/tempapp1/issues/2
Can anybody tell me, why I am getting this error?
I don't understand what i am doing wrong:
MainActivity.java:
public class MainActivity extends ActionBarActivity {
// UI elements
public static Toolbar toolbar;
public static ViewPager viewPager;
private AppSectionsPagerAdapter mAppSectionsPagerAdapter;
// Tab titles
private String[] tabs = {"Home", "Note"};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences settings = getSharedPreferences("prefs", 0);
boolean firstRun = settings.getBoolean("firstRun", true);
if (firstRun) { // here run your first-time instructions, for example :
startActivity(new Intent(this, MyIntro.class));
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("firstRun", false);
editor.commit();
}
mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getSupportFragmentManager());
// Set up the action/tool bar.
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar); // Setting toolbar with setSupportActionBar()
// Initilization
viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(mAppSectionsPagerAdapter);
/* ViewPager.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
swipeLayout.setEnabled(false);
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
swipeLayout.setEnabled(true);
break;
}
return false;
}
});
*/
// Adding Tabs
PagerSlidingTabStrip tabs = (PagerSlidingTabStrip) findViewById(R.id.tabs);
tabs.setViewPager(viewPager);
tabs.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// When swiping between different app sections
// change toolbar title
if (position == 0)
toolbar.setTitle(getResources().getString(R.string.app_name));
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
startActivity(new Intent("android.intent.action.SettingsActivity"));
return true;
case R.id.action_donate:
startActivity(new Intent("android.intent.action.DonateActivity"));
return true;
case R.id.action_rate:
Intent i2 = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.service.beta.servicenotesbeta"));
startActivity(i2);
return super.onOptionsItemSelected(item);
default:
return super.onOptionsItemSelected(item);
}
}
public static class AppSectionsPagerAdapter extends FragmentPagerAdapter {
public AppSectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public android.support.v4.app.Fragment getItem(int i) {
switch (i) {
case 0:
return new Fragment_main();
case 1:
return new Fragment_second();
/*case 2:
return new Fragment_third();
case 3:
return new Fragment_fourth();*/
default:
return null;
}
}
#Override
public int getCount() {
return 2; //3-4
}
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="#style/ToolBarStyle"
android:id="#+id/toolbar"/>
<com.astuetz.PagerSlidingTabStrip
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="48dip" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true" />
</RelativeLayout>
</LinearLayout>
Please tell me what i am doing wrong
I put the issue link because when i put the issue code it gives me an error
Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.String java.lang.CharSequence.toString()' on a null object reference
at com.astuetz.PagerSlidingTabStrip.notifyDataSetChanged(PagerSlidingTabStrip.java:200)
at com.astuetz.PagerSlidingTabStrip.setViewPager(PagerSlidingTabStrip.java:182)
at com.service.beta.servicenotesbeta.MainActivity.onCreate(MainActivity.java:67)
there is a problem with <com.astuetz.PagerSlidingTabStrip
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="48dip" />
have you looked at https://github.com/astuetz/PagerSlidingTabStrip/ for further infos?
Go to AppSectionsPagerAdapter.java and add this piece of code necessary to provide a title that your PagerSlidingTabStrip can obtain.
#Override
public CharSequence getPageTitle(int position) {
if (position == 0)
{
return "Movies";
}
if (position == 1)
{
return "Events";
}
return null;
}
I fixed, the problem was that i didn't add the titles to the tabs
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 :)