How to replace fragment to another fragment in TabLayout and ViewPager - android

I want to replace fragment to another fragment which contain by TabLayout Viewpager. like this:
Activity -> A Fragment -> B Fragment(TabLayout ViewPager) -> C Fragment(Tab's Fragment) -> D Fragment
I task is switch Fragment C to Fragment D.
Note:- TabLayout ViewPager also contain 3 tab Fragment control by FragmentPagerAdapter.
Tablayout fragment's layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<android.support.design.widget.TabLayout
android:id="#+id/tablayout_postpaid_service"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
app:tabGravity="fill"
app:tabIndicatorColor="#color/white"
app:tabMode="scrollable"
app:tabSelectedTextColor="#color/white"
app:tabTextColor="#color/tab_fade_text_color" >
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager_postpaid_service"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- <FrameLayout
android:id="#+id/container_body"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" /> -->
</android.support.v4.view.ViewPager>
Fragment B class:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_select_postpaid_service, container, false);
tablayout = (TabLayout) view.findViewById(R.id.tablayout_postpaid_service);
viewpager = (ViewPager) view.findViewById(R.id.viewpager_postpaid_service);
viewpager.setAdapter(new TabPagerAdapter(getChildFragmentManager(), TabConstants.POSTPAID_SERVICE_TYPE_TABS_FLAG, TabConstants.POSTPAID_SERVICE_TYPE_TABS));
tablayout.post(new Runnable() {
#Override
public void run() {
tablayout.setupWithViewPager(viewpager);
setupTabIcons();
}
});
return view;
}
Fragment C class:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_select_operator, container,
false);
setGridview();
return view;
}
private void setGridview() {
operatorName = new ArrayList<String>();
operatorCode = new ArrayList<String>();
recyclerview = (RecyclerView) view
.findViewById(R.id.select_operator_recycler_view);
recyclerview.setHasFixedSize(true);
GridLayoutManager layoutManager = new GridLayoutManager(getActivity(),
Constants.NO_OF_OPERATOR_GRID);
recyclerview.setLayoutManager(layoutManager);
OperatorGridAdapter adapter = new OperatorGridAdapter(getActivity(),
HomeConstants.OPERATOR_LIST_ICON);
recyclerview.setAdapter(adapter);
recyclerview.addOnItemTouchListener(new RecyclerItemClickListener(
getActivity(),
new RecyclerItemClickListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
navigateFragment(position);
}
}));
}
private void navigateFragment(int position) {
Fragment fragment = new DFragment();
// FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction();
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.container_body, fragment);
//fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle(
getResources().getString(R.string.app_name));
Log.d(Constants.ACTIVITY_TAG, "********************");
}
I getting an error
java.lang.IllegalArgumentException: No view found for id 0x7f0a006e (com.recharge:id/container_body) for fragment DFragment{4327cfd0 #2 id=0x7f0a006e}
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1070)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1259)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1624)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517)
I've tried many tick and solution but not hit for me .
Please help me short out this problem.

Have you tried?
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.main_container, new FragmentB()).commit();

and I think the error was quite obvious. The compile says:
not view found for container_body
And in your code:
private void navigateFragment(int position) {
Fragment fragment = new DFragment();
// FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction();
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.container_body, fragment);
//fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle(
getResources().getString(R.string.app_name));
Log.d(Constants.ACTIVITY_TAG, "********************");
}
I see that you try to use fragmentTransaction.replace(R.id.container_body, fragment); However you just comment the container_body in your layout. That's why the compile told you that it can't find container_body for the fragment to inflate. Maybe that's the problem?
Also it should be helpful if you could post more details about your layout for fragment D.
Let me know if this solve your problem ;)

Related

Implement Bottom Navigation View into a fragment

In my Android Studio project I want to implement into the MainActivity a NavigationDrawer with fragments and on every fragments a bottom navigation view.
This is the code of one fragment:
public class U16 extends Fragment{
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getActivity().setTitle("TITOLO U16");
}
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
switch (item.getItemId()) {
case R.id.navigation_home:
fragmentTransaction.replace(R.id.content, new Calendario()).commit();
return true;
case R.id.navigation_dashboard:
fragmentTransaction.replace(R.id.content, new Palestre()).commit();
return true;
case R.id.navigation_notifications:
fragmentTransaction.replace(R.id.content, new Squadra()).commit();
return true;
}
return false;
}
};
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
BottomNavigationView navigation = (BottomNavigationView) getActivity().findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.content, new Calendario()).commit();
return inflater.inflate(R.layout.u16_layout, container, false);
}
}
I get this error:
FATAL EXCEPTION: main
Process: app.navigationdrawerfragment, PID: 21499
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.design.widget.BottomNavigationView.setOnNavigationItemSelectedListener(android.support.design.widget.BottomNavigationView$OnNavigationItemSelectedListener)' on a null object reference at app.navigationdrawerfragment.U16.onCreateView(U16.java:52)
I know that this error in into the procedure "OnCreateView" doing " navigation.setOnNavigationItemSelectedListener..."
This is the u16_layout.xml:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="simone.biliato.navigationdrawerfragment.MainActivity">
<FrameLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</FrameLayout>
<android.support.design.widget.BottomNavigationView
android:id="#+id/navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="?android:attr/windowBackground"
app:menu="#menu/navigation" />
</LinearLayout>
So, anyone tried to do the same?
You are trying do set someone that is isn't already created.
So move the code into the event onViewCreated, like this:
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getActivity().setTitle("Titolo");
BottomNavigationView navigation = (BottomNavigationView) getActivity().findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.content, new Calendario()).commit();
return inflater.inflate(R.layout.u16_layout, container, false);
}
This will work :)

Cannot access Textview inside fragment

I have an activity with a fragment on it that has a TextView inside. In the CourseFragment.java I made a simple method that changes the text of the TextView. However, when I try to call the fragment's method from the Activity, it says that the TextView object is null. Here is some of my code:
CourseFragment.java
public class CourseFragment extends Fragment {
private Subject subject;
View rootView;
private TextView title;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
rootView = inflater.inflate(R.layout.fragment_course, container,
false);
title = (TextView) rootView.findViewById(R.id.course_title);
return rootView;
}
public void setTitle() {
title.setText("My Title");
}
}
this is the code in my activity that makes the new fragment and puts in the right location:
CourseFragment fragment = new CourseFragment();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.course1, fragment);
fragment.setTitle();
ft.addToBackStack(null);
ft.commit();
the error coming from the setTitle() method inside the fragment
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
this seems so straight forward yet I don't understand why I keep getting NPE. I looked at similar questions about this and tried all the accepted solutions but to no avail. any ideas?
thanks in advance
edit: here is some more code as per requested:
the beginning of fragment_course.xml
<LinearLayout 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:id="#+id/course_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.stagenda.stagenda.CourseFragment"
android:padding="16dp"
android:orientation="vertical"
android:background="#android:color/background_light">
<RelativeLayout
android:layout_width="match_parent"
tools:ignore="UselessParent"
android:background="#color/colorAccent"
android:padding="16dp"
android:layout_height="wrap_content"
android:id="#+id/course_container">
<TextView
android:text="Course Given Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/course_given_title"
android:textColor="#android:color/background_light"
android:textSize="18sp" />
<TextView
android:text="Course Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/course_title"
android:layout_below="#+id/course_given_title"
android:textColor="#android:color/background_light" />
<TextView
android:text="Course Code"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/course_code"
android:textColor="#android:color/background_light"
android:layout_toRightOf="#+id/course_title"
android:layout_below="#+id/course_given_title"
android:layout_alignParentEnd="false"
android:layout_marginStart="10dp" />
full error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.stagenda.stagenda, PID: 1654
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
at android.view.View.performClick(View.java:5639)
at android.view.View$PerformClick.run(View.java:22387)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6088)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:5639) 
at android.view.View$PerformClick.run(View.java:22387) 
at android.os.Handler.handleCallback(Handler.java:751) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6088) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at com.stagenda.stagenda.CourseFragment.setTitle(CourseFragment.java:34)
at com.stagenda.stagenda.MainPage.confirmAddCourse(MainPage.java:435)
at java.lang.reflect.Method.invoke(Native Method) 
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) 
at android.view.View.performClick(View.java:5639) 
at android.view.View$PerformClick.run(View.java:22387) 
at android.os.Handler.handleCallback(Handler.java:751) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6088) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 
I/Process: Sending signal. PID: 1654 SIG: 9
Disconnected from the target VM, address: 'localhost:8612', transport: 'socket'
explanation of layout (image)
Go with this approch.
Bundle bundle = new Bundle();
bundle.putString("title", "whatever you want to pass");
CourseFragment fragment = new CourseFragment();
fragment.setArguments(bundle);
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.course1, fragment);
ft.addToBackStack(null);
ft.commit();
public class CourseFragment extends Fragment {
private Subject subject;
View rootView;
private TextView title;
Bundle bundle;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
bundle = getArguments();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
rootView = inflater.inflate(R.layout.fragment_course, container,
false);
title = (TextView) rootView.findViewById(R.id.course_title);
String text = bundle.getString("title");
title.setText(text);
return rootView;
}
}
I figured it out myself. The problem was here:
CourseFragment fragment = new CourseFragment();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.course1, fragment);
fragment.setTitle();
ft.addToBackStack(null);
ft.commit();
The problem was that I was calling setTitle() on fragment which did not have its view created. when instead I did the following the problem was solved:
CourseFragment fragment = new CourseFragment();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.course1, fragment);
ft.addToBackStack(null);
ft.commit();
CourseFragment frag = fm.findFragmentById(R.id.course1);
frag.setTitle();
I eventually changed a lot of my code but I hope this helps someone. thanks for the answers everyone
Fragment transactions are not synchronous. When you add a transaction it can be executed when the main looper has a chance to run it (it gets queued for later).
This means that the fragment gets attached until after the current method ends. Check the order in which CourseFragment.setTitle() and onCreateView() are executed.
See docs for FragmentTransaction.commit(): commit
Consider using commitNow() if it works for you.
Also, consider passing the title as an argument to the fragment so that it can be read inside onCreateView using getArguments().
Layout for tabs:
<?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:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#ffffff">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways"
app:layout_collapseMode="pin"
android:background="#000000"
app:titleTextColor="#ffffff"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/PopupMenuStyle">
<TextView
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:id="#+id/textview"
android:textColor="#color/colorTrueWhite"/>
</android.support.v7.widget.Toolbar>
<!-- our tablayout to display tabs -->
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorBlack"
android:minHeight="?attr/actionBarSize"
app:tabIndicatorColor="#color/colorTrueWhite"
app:tabIndicatorHeight="5dp"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<!-- View pager to swipe views -->
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
Activity using that layout:
public class Main2Activity extends AppCompatActivity implements TabLayout.OnTabSelectedListener {
private TabLayout tabLayout;
public static ViewPager viewPager;
public static Context ctx;
Pager adapter;
public static int expired, paid;
Boolean isConnection;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Toolbar tb = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(tb);
TextView tv = (TextView) findViewById(R.id.textview);
//getSupportActionBar().setDisplayHomeAsUpEnabled(true);
ctx = getApplicationContext();
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
viewPager = (ViewPager) findViewById(R.id.pager);
tabLayout.addTab(tabLayout.newTab().setText("title1"));
tabLayout.addTab(tabLayout.newTab().setText("title2"));
tabLayout.addTab(tabLayout.newTab().setText("title3"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setupWithViewPager(viewPager);
adapter = new Pager(getSupportFragmentManager(), tabLayout.getTabCount(), ctx);
viewPager.setAdapter(adapter);
if(some condition)
{
viewPager.setCurrentItem(2);
}
else
{
viewPager.setCurrentItem(1);
}
viewPager.setOffscreenPageLimit(2);
tabLayout.addOnTabSelectedListener(this);
ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
int tabsCount = vg.getChildCount();
for (int j = 0; j < tabsCount; j++) {
ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
int tabChildsCount = vgTab.getChildCount();
for (int i = 0; i < tabChildsCount; i++) {
View tabViewChild = vgTab.getChildAt(i);
if (tabViewChild instanceof TextView) {
((TextView) tabViewChild).setTypeface(Typeface.DEFAULT, Typeface.BOLD);
}
}
}
}
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
}
Pager code:
public class Pager extends FragmentStatePagerAdapter
{
int tabcount;
Context ctx;
private String [] Titles = {"title1", "title2", "title3"};
public Pager(FragmentManager fm, int tabcount, Context ctx)
{
super(fm);
this.tabcount = tabcount;
this.ctx = ctx;
}
#Override
public int getCount() {
return tabcount;
}
#Override
public CharSequence getPageTitle(int position) {
return Titles[position];
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
Tab1 tab1 = new Tab1();
return tab1;
case 1:
Tab2 tab2 = new Tab2();
return tab2;
case 2:
Tab3 tab3 = new Tab3();
return tab3;
default:
return null;
}
}
}
One thing you can do is pass your data as parameters:
CourseFragment fragment = new CourseFragment(Your title);
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.course1, fragment);
ft.addToBackStack(null);
ft.commit();
You can also use Bundle to pass your data.
solved this problem by using Framgnet Callbacks as described in here http://developer.android.com/training/basics/fragments/communicating.html I believe that this is the best was to pass fragment TextViews into my activity after they are created.
The onCreateView() method is called after fragmentTransaction.commit().
Since, you are calling setTitle() before fragmentTransaction.commit(), the TextView instance title is not instantiated and so is null.
Add the line fragment.setTitle() after fragmentTransaction.commit().

TabLayout ViewPager Not Loading When Using Backstack [duplicate]

This question already has an answer here:
Lifecycle of a replaced ViewPager and BackStack?
(1 answer)
Closed 7 years ago.
I'm using a TabLayout in one of my fragments with a viewPager to switch between two fragments below the tabs.
When I click the FAB inside one of the lower fragments, I load a new fragment (for input).
However- when I press the BACK button, the TabLayout shows up but WITHOUT either of the lower fragments (represented by the pages).
So what am I doing wrong?
and is there a better way to be swapping fragments?
and is there a way to press the back button and get back to the viewPager Page that was showing?
Fragment with TabLayout: CustomTemplatesFragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_custom_templates, container, false);
final TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tab_layout);
tabLayout.addTab(tabLayout.newTab().setText(R.string.macro_tab));
tabLayout.addTab(tabLayout.newTab().setText(R.string.lifestyle_tab));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
final ViewPager viewPager = (ViewPager) view.findViewById(R.id.pager);
final CustomTemplatesPagerAdapter adapter = new CustomTemplatesPagerAdapter
(getFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
return view;
}
Pager Adapter: CustomTemplatePagerAdapter
public class CustomTemplatesPagerAdapter extends FragmentStatePagerAdapter {
int mNumOfTabs;
public CustomTemplatesPagerAdapter(FragmentManager fm, int NumOfTabs) {
super(fm);
this.mNumOfTabs = NumOfTabs;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
CustomMacroFragment tab1 = new CustomMacroFragment();
return tab1;
case 1:
CustomLifestyleFragment tab2 = new CustomLifestyleFragment();
return tab2;
default:
return null;
}
}
Lower Fragment with FAB: CustomMacroFragment
private void onFABClicked() {
Fragment fragment = null;
Class fragmentClass = MacroTemplateDetailFragment.class;
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
// Insert the fragment by replacing any existing fragment
FragmentManager fm = getActivity().getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.flContent, fragment);
ft.addToBackStack(null);
ft.commit();
}
TabLayout/ViewPager XML
<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:id="#+id/customLayout"
tools:context=".CustomTemplatesFragment">
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:elevation="6dp"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<!--android:minHeight="?attr/actionBarSize"-->
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_below="#id/tab_layout"/>
Fragment with FAB XML
<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:id="#+id/macroCoordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CustomMacroFragment">
<!-- using RecyclerView because of
https://guides.codepath.com/android/Floating-Action-Buttons -->
<android.support.v7.widget.RecyclerView
android:id="#+id/rvMacrolist"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
<TextView
android:id="#+id/emptyView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal|center_vertical"
android:visibility="gone"
android:text="Please add a Macronutrient Template"/>
<!--https://guides.codepath.com/android/Floating-Action-Buttons-->
<android.support.design.widget.FloatingActionButton
android:id="#+id/macroListFAB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_margin="#dimen/activity_margin"
android:src="#drawable/ic_plus"
app:layout_anchor="#id/rvMacrolist"
app:layout_anchorGravity="bottom|right|end"
app:layout_behavior=".utilities.behavior.ScrollAwareFABBehavior"/>
I believe found the answer here: Lifecycle of a replaced ViewPager and BackStack?
Works for initial testing. Need to replace getFragmentManager() with getChildFragment Manager at the adapter
ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager());

PagerView with fragment

I have a ListView with books. When I click the row I am able to see book details in new fragment, something similar like in Training Android. I would like to slide books (right -> next element from the list, left <- previous element from the list).
PROBLEM
How to integrate ViewPager with fragements? When I click element on the list FragmentTransaction is invoke.
Activity:
public class MyActivity extends FragmentActivity implements RecyclerViewFragment.OnFragmentInteractionListener {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private ViewPager mPager;
private PagerAdapter mPagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
final Fragment mFragment = new RecyclerViewFragment();
if (savedInstanceState == null) {
getSupportFragmentManager()
.beginTransaction()
.add(R.id.container, mFragment)
.commit();
}
}
#Override
public void onFragmentInteraction(int id) {
Log.d("Element Id ", String.valueOf(id));
PagerViewFragment newFragment = new PagerViewFragment();
Bundle args = new Bundle();
args.putInt(PagerViewFragment.ARG_POSITION, id);
newFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);
transaction.replace(R.id.container, newFragment);
transaction.addToBackStack(null);
transaction.commit();
}
How to inform fragment that should change the view?
Should I use this code?
mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
EDIT
After ILovemyPancho answer stack again. java.lang.NullPointerException:
PagerViewFragment:
public class PagerViewFragment extends Fragment {
final static String ARG_POSITION = "position";
private ViewPager mPager;
private PagerAdapter mPagerAdapter;
public PagerViewFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ViewGroup viewRoot = (ViewGroup) inflater.inflate(R.layout.pager_fragment, container, false);
mPager = (ViewPager) container.findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getChildFragmentManager());
mPager.setAdapter(mPagerAdapter); //line 39. Error is here
return viewRoot;
}
#Override
public void onStart() {
super.onStart();
}
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
PagerViewFragment frag = new PagerViewFragment();
Bundle args = new Bundle();
args.putString("BookTitle", "FD");
DummyContent dummyContent = new DummyContent(); //elements
TextView street = (TextView) getView().findViewById(R.id.street_article);
street.setText(dummyContent.murals.get(position).getStreet());
TextView artist = (TextView) getView().findViewById(R.id.artist_article);
artist.setText(dummyContent.murals.get(position).getArtists().get(0).getName());
frag.setArguments(args);
return frag;
}
#Override
public int getCount() {
return DummyContent.murals.size();
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
}
MyActivity:
public class MyActivity extends FragmentActivity implements RecyclerViewFragment.OnFragmentInteractionListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
final Fragment mFragment = new RecyclerViewFragment();
if (savedInstanceState == null) {
getSupportFragmentManager()
.beginTransaction()
.add(R.id.container, mFragment)
.commit();
}
}
#Override
public void onFragmentInteraction(int id) {
Log.d("Element Id ", String.valueOf(id));
PagerViewFragment newFragment = new PagerViewFragment();
Bundle args = new Bundle();
args.putInt(PagerViewFragment.ARG_POSITION, id);
newFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);
transaction.replace(R.id.container, newFragment);
transaction.addToBackStack(null);
transaction.commit();
}
}
activity_screen_slide.xml
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
pager_fragmet.xml
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/blank_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.szymon.fragmentexample.BlankFragment">
<TextView
android:id="#+id/street_article"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:layout_marginTop="50dp"
android:text="hello_blank_fragment"
android:textSize="23dp" />
<TextView
android:id="#+id/artist_article"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/street_article"
android:layout_marginLeft="50dp"
android:layout_marginTop="10dp"
android:text="hello_blank_fragment"
android:textSize="15dp" />
<TextView
android:id="#+id/picture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/artist_article"
android:layout_marginLeft="50dp"
android:layout_marginTop="100dp"
android:text="here will be the picture"
android:textSize="15dp" />
</RelativeLayout>
</ScrollView>
I got an error:
java.lang.NullPointerException
at com.example.szymon.recyclerview.PagerViewFragment.onCreateView(PagerViewFragment.java:39)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1504)
Ok, So you have an Activity dislaying a ListFragment (RecyclerViewFragment). When you click a list item, ListFragment is replaced by PagerViewFragment showing the details of the book.
Try this. Create a fragment containing the ViewPager. This fragment is going to replace your ListFragment when an item is clicked. Lets call it BookDetailsContainer, and is going to receive the list item id:
BookDetailsContainer newFragment = BookDetailsContainer.newInstance(id);
Inside this fragment you set the viewpager:
mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getChildFragmentManager());
mPager.setAdapter(mPagerAdapter);
getChildFragmentManager() is needed by the ViewPager to handle the nested fragments (the PagerViewFragment inside the BookDetailsContainer). And since you passed the list position id to the BookDetailsContainer, you can set the position:
mPager.setCurrentItem(positionId);
In your ScreenSlidePagerAdapter, you are going to create a PagerViewFragment instance,
get the information to display from your data source (array, cursor...) based on the
position, pass that data to the fragment using a Bundle, and return the fragment:
#Override
public Fragment getItem(int position) {
PagerViewFragment frag = new PagerViewFragment();
Bundle args = new Bundle();
//get data from your data source based on the "position"
args.putString("BookTitle", ...);
args.putString("BookAuthor", ...);
...
frag.setArguments(args);
return frag;
}
And that's basically how you can do it.

Call fragment from fragment

i have an activity with button on it and when a click i call the fragment with another button on fragment. but when click on fragment's button i cant call a second fragment. this is my source, pretty simple:
activity_main.xml:
<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="horizontal"
tools:context=".MainActivity" >
<Button
android:id="#+id/btn_click"
android:text="Call Fragment"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:onClick="onClick"
/>
</LinearLayout>
fragment1.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:background="#f0f0f0"
android:orientation="vertical" >
<TextView
android:id="#+id/fragment1"
android:text="Fragment 1"
android:textSize="25sp"
android:gravity="center"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
/>
<Button
android:id="#+id/btn_frag2"
android:text="Call Fragment 2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
fragment2.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:background="#f0f0f0"
android:orientation="vertical" >
<TextView
android:id="#+id/fragment2"
android:text="Fragment 2"
android:textSize="25sp"
android:gravity="center_vertical|center_horizontal"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
/>
</LinearLayout>
MainActivity.java
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public void onClick(View v) {
Fragment1 fragment1 = new Fragment1();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(android.R.id.content, fragment1);
fragmentTransaction.commit();
}
}
Fragment1.java
public class Fragment1 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment1, container, false);
}
public void onClick2(View view) {
Fragment2 fragment2 = new Fragment2();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment1, fragment2);
fragmentTransaction.commit();
}
}
Fragment2.java
public class Fragment2 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment2, container, false);
}
}
what is wrong in my code?
I think now Fragment nesting is available just update the back computability jar
now lets dig in the problem it self .
public void onClick2(View view) {
Fragment2 fragment2 = new Fragment2();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment1, fragment2);
fragmentTransaction.commit();
}
I think the R.id.fragment1 belongs to a TextView which is not a good place to include child views in because its not a ViewGroup, you can remove the textView from the xml and replace it with a LinearLayout lets say and it will work , if not tell me what the error .
fragment1.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:background="#f0f0f0"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/fragment1"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
/>
<Button
android:id="#+id/btn_frag2"
android:text="Call Fragment 2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
Update for the error in the comment
public class Fragment1 extends Fragment implements OnClickListener{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment1, container, false);
((Button) v.findViewById(R.id.btn_frag2)).setOnClickListener(this);
return v;
}
public void onClick(View view) {
Fragment2 fragment2 = new Fragment2();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container, fragment2);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
}
If you want to replace the entire Fragment1 with Fragment2, you need to do it inside MainActivity, by using:
Fragment2 fragment2 = new Fragment2();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(android.R.id.content, fragment2);
fragmentTransaction.commit();
Just put this code inside a method in MainActivity, then call that method from Fragment1.
This is my answer which solved the same problem. Fragment2.java is the fragment class which holds the layout of fragment2.xml.
public void onClick(View v) {
Fragment fragment2 = new Fragement2();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_container, fragment2);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
I would use a listener. Fragment1 calling the listener (main activity)
This code works for me to call the parent_fragment method from child_fragment.
ParentFragment parent = (ParentFragment) activity.getFragmentManager().findViewById(R.id.contaniner);
parent.callMethod();
In MainActivity
private static android.support.v4.app.FragmentManager fragmentManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentManager = getSupportFragmentManager();
}
public void secondFragment() {
fragmentManager
.beginTransaction()
.setCustomAnimations(R.anim.right_enter, R.anim.left_out)
.replace(R.id.frameContainer, new secondFragment(), "secondFragmentTag").addToBackStack(null)
.commit();
}
In FirstFragment call SecondFrgment Like this:
new MainActivity().secondFragment();
Just do that: getTabAt(index of your tab)
ActionBar actionBar = getSupportActionBar();
actionBar.selectTab(actionBar.getTabAt(0));

Categories

Resources