Cannot access Textview inside fragment - android

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().

Related

How to switch existing fragments when the dialog is closed?

The main screen of the app is for bottom navigation.
And there are 3 menus, all of which are fragments.
Pressing the button on one of the fragments opens the dialog fragment window.
And when the dialog is closed, the old fragment should be switched to another new fragment.
I use show() and hide() instead of replace().
MainAcitivity.java
public class MainActivity extends AppCompatActivity {
BottomNavigationView bottomNav;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bottomNav = findViewById(R.id.bottom_nav);
bottomNav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
Fragment curFrag = fm.getPrimaryNavigationFragment();
String tag = String.valueOf(item.getItemId());
int id = item.getItemId();
if(curFrag != null) {
transaction.hide(curFrag);
}
Fragment fragment = fm.findFragmentByTag(tag);
if(fragment == null) {
if(id == R.id.list)
fragment = new WorkoutListFragment();
transaction.add(R.id.content_layout, fragment);
}
else {
transaction.show(fragment);
}
transaction.setPrimaryNavigationFragment(fragment);
transaction.setReorderingAllowed(true);
transaction.commitNow();
return true;
}
});
}
// Switch to another fragment when the dialog is closed
public void onFragmentChanged() {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
String tag = "ABC";
Fragment currentFragment = fragmentManager.getPrimaryNavigationFragment();
if (currentFragment != null) {
fragmentTransaction.hide(currentFragment);
}
Fragment fragment = fragmentManager.findFragmentByTag(tag);
if (fragment == null) {
fragment = new WriteRoutineFragment();
fragmentTransaction.add(R.id.container, fragment, tag);
} else {
fragmentTransaction.show(fragment);
}
fragmentTransaction.setPrimaryNavigationFragment(fragment);
fragmentTransaction.setReorderingAllowed(true);
fragmentTransaction.commitNow();
}
}
DialogFragment.java
Button startBtn;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_body_part_dialog, null);
startBtn = view.findViewById(R.id.check);
startBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MainActivity activity = (MainActivity) getActivity();
activity.onFragmentChanged(); // change fragment
dismiss();
}
});
return view;
}
#NonNull
#Override
public Dialog onCreateDialog(#Nullable Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dialog.setCanceledOnTouchOutside(false);
return dialog;
}
}
WriteRoutineFragment.java
public class WriteRoutineFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_write_routine, container, false);
return rootView;
}
}
ERROR
java.lang.IllegalArgumentException: No view found for id 0x7f0a0082 (com.example.writeweight:id/container) for fragment WriteRoutineFragment{f3a9b6 (137e8e27-12af-4e5a-9397-2cbdc80ed980) id=0x7f0a0082 ABC}
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:875)
at androidx.fragment.app.FragmentManagerImpl.addAddedFragments(FragmentManagerImpl.java:2100)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1874)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1830)
at androidx.fragment.app.FragmentManagerImpl.execSingleAction(FragmentManagerImpl.java:1696)
at androidx.fragment.app.BackStackRecord.commitNow(BackStackRecord.java:293)
at com.example.writeweight.activity.MainActivity.onFragmentChanged(MainActivity.java:78)
at com.example.writeweight.fragment.BodyPartDialogFragment$2.onClick(BodyPartDialogFragment.java:89)
at android.view.View.performClick(View.java:8160)
at android.widget.TextView.performClick(TextView.java:16221)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:992)
at android.view.View.performClickInternal(View.java:8137)
at android.view.View.access$3700(View.java:888)
at android.view.View$PerformClick.run(View.java:30236)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8506)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
I/Process: Sending signal. PID: 23516 SIG: 9
ADDED
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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=".activity.MainActivity">
<FrameLayout
android:id="#+id/content_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="#id/bottom_nav"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_nav"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="#menu/bottom_nav_menu"/>
</androidx.constraintlayout.widget.ConstraintLayout>
fragment_write_routine.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragment.WriteRoutineFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment" />
</FrameLayout>
When you say
fragmentTransaction.add(R.id.container, fragment, tag);
What you're saying is that you want the FragmentManager to find the R.id.container in your layout and add your fragment to that container. As you're using getSupportFragmentManager(), you're using the Activity's FragmentManager and hence, R.id.container needs to be in your activity's layout. However, R.id.container isn't in your activity's layout, which is why you're getting an exception.
Instead, you should be using the container that is in your Activity's layout - R.id.content_layout:
fragmentTransaction.add(R.id.content_layout, fragment, tag);

How to add Fragment into Activity in Android

I want add 2 fragment into activity, and when click on button switch between this fragments!
I want show Fragment_1 for by default in activity (my mean is : when running activity, show fragment_1) and when click on button switch between fragment_2 and fragment_1 !
I write below codes, and when running activity show fragment_1 but when click on button for switch between fragments, show me Force Close error.
FC error :
08-27 14:15:41.363 14224-14224/com.mohammad.nouri.diaryday E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mohammad.nouri.diaryday, PID: 14224
java.lang.IllegalStateException: commit already called
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:641)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:621)
at com.mohammad.nouri.diaryday.Activities.LoginActivity$1.onClick(LoginActivity.java:58)
at android.view.View.performClick(View.java:4764)
at android.view.View$PerformClick.run(View.java:19844)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5349)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
Activity codes:
public class LoginActivity extends AppCompatActivity {
private Context context;
private boolean status = false;
FragmentTransaction fT;
FragmentManager fM;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
context = this;
Glide.with(this).load(R.drawable.login_header_image)
.bitmapTransform(new BlurTransformation(context, 20))
.into((ImageView) findViewById(R.id.login_background));
fM = getSupportFragmentManager();
fT = fM.beginTransaction();
if (!status) {
LoginFragment f1 = new LoginFragment();
fT.add(R.id.login_cardView, f1);
fT.commit();
status = true;
}
FloatingActionButton f = (FloatingActionButton) findViewById(R.id.login_registerButton);
f.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!status) {
RegisterFragment f1 = new RegisterFragment();
fT.add(R.id.login_cardView, f1);
fT.commit();
status = true;
}else {
LoginFragment f2 = new LoginFragment();
fT.add(R.id.login_cardView, f2);
fT.commit();
status = false;
}
}
});
}
}
How can I fix it ? Thanks all <3
You only call commit() once in a FragmentTransaction which you already do in the onCreate(). So, just create a new FragmentTransaction within your fab:
FloatingActionButton f = (FloatingActionButton) findViewById(R.id.login_registerButton);
f.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!status) {
RegisterFragment f1 = new RegisterFragment();
fM.beginTransaction().add(R.id.login_cardView, f1)
.commit();
status = true;
}else {
LoginFragment f2 = new LoginFragment();
fM.beginTransaction().add(R.id.login_cardView, f2)
.commit();
status = false;
}
}
});
Instead of adding the fragments try replacing because you have already added once above.
MainActivity.java
public class MainActivity extends AppCompatActivity {
Button btnFragment;
LinearLayout fragmentContainer;
boolean toggleFlag = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentContainer = (LinearLayout) findViewById(R.id.fragment_container);
FragmentA fragmentA = new FragmentA();
final FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragmentA);
fragmentTransaction.commit();
btnFragment = (Button) findViewById(R.id.btn_fragment);
btnFragment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(toggleFlag) {
FragmentA fragmentA = new FragmentA();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragmentA);
fragmentTransaction.commit();
} else {
FragmentB fragmentB = new FragmentB();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragmentB);
fragmentTransaction.commit();
}
toggleFlag = !toggleFlag;
}
});
}
}
activity_main.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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="#+id/btn_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Toggle Fragment" />
</LinearLayout>
<LinearLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
</LinearLayout>
FragmentA.java
public class FragmentA extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootview = inflater.inflate(R.layout.layout_fragment_a, null);
return rootview;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
}
layout_fragment_a.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">
<ImageView
android:id="#+id/picture"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="#mipmap/ic_launcher"/>
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Demo Fragment A"
android:textColor="#android:color/black"/>
</LinearLayout>
FragmentB.java
public class FragmentB extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootview = inflater.inflate(R.layout.layout_fragment_b, null);
return rootview;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
}
layout_fragment_b.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">
<ImageView
android:id="#+id/picture"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="#mipmap/ic_launcher"/>
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Demo Fragment B"
android:textColor="#android:color/black"/>
</LinearLayout>
use this method to call fragment
rplaceFragment(Fragment fragment , int id){
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(id, fragment);
fragmentTransaction.commit();
}

How to replace fragment to another fragment in TabLayout and ViewPager

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 ;)

Tabs of TabLayout not showing

I have a main activity, which hosts a fragment, which in turn hosts a TabLayout (with a ViewPager). The tab bar is shown, baut the tabs themselves are not shown.
Here is my code in the main activity for displaying the host fragment:
Fragment fragment = new BMITabsFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).addToBackStack(Constants.BMI_TABS_FRAGMENT).commit();
Here is my the Fragment which hosts the TabLayout, which is BMITabsFragment (s.a.):
public class BMITabsFragment extends Fragment {
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Get the ViewPager and set it's PagerAdapter so that it can display items
ViewPager viewPager = (ViewPager) view.findViewById(R.id.viewpager);
viewPager.setAdapter(new BMIFragmentPagerAdapter(getActivity().getSupportFragmentManager(),
getActivity()));
// Give the TabLayout the ViewPager
TabLayout tabLayout = (TabLayout) view.findViewById(R.id.sliding_tabs);
tabLayout.setupWithViewPager(viewPager);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_bmitabs, container, false);
return view;
}
...
}
This is my FragmentPagerAdapter:
public class BMIFragmentPagerAdapter extends FragmentPagerAdapter {
final int PAGE_COUNT = 2;
private FragmentManager fragmentManager;
private Context context;
public BMIFragmentPagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.context = context;
this.fragmentManager = fm;
}
public BMIFragmentPagerAdapter(FragmentManager fm) {
super(fm);
fragmentManager = fm;
}
#Override
public CharSequence getPageTitle(int position) {
String[] pageTitles = context.getResources().getStringArray(R.array.page_titles_array);
return pageTitles[position];
}
#Override
public Fragment getItem(int position) {
SharedPreferences prefs = context.getSharedPreferences(Constants.SHARED_PREFS_FILE, 0);
long patientId = prefs.getLong(Constants.SELECTED_PATIENT_ID, 1);
Fragment fragment = null;
switch (position){
case 0:
return BMITabelleFragment.newInstance(patientId);
case 1:
return BMIChartFragment.newInstance(patientId);
default:
return BMITabelleFragment.newInstance(patientId);
}
}
#Override
public int getCount() {
return PAGE_COUNT;
}
}
And this is the fragment_bmitabs.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.TabLayout
android:id="#+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable" />
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
android:background="#android:color/white" />
</LinearLayout>
My code is based on the Google Android Guide at https://github.com/codepath/android_guides/wiki/Google-Play-Style-Tabs-using-TabLayout
What I am missing here?
Note: I am using AppCompatActivity and the support libraries v4 & v7 and the com:android:support:design library
This fixed it for me:
tabLayout.post(new Runnable() {
#Override
public void run() {
tabLayout.setupWithViewPager(viewPager);
}
});
https://code.google.com/p/android/issues/detail?id=180462
Set tab icons after setupWithViewPager()
private void setTabs {
tabLayout.setupWithViewPager(viewPager);
setupTabIcons();
}
private void setupTabIcons() {
tabLayout.getTabAt(0).setIcon(tabIcons[0]);
tabLayout.getTabAt(1).setIcon(tabIcons[1]);
tabLayout.getTabAt(2).setIcon(tabIcons[2]);
}
like #Nathaniel Ford said,this should a bug, I change to use design library 23.0.1。google fixed it,so change build.gradle to compile 'com.android.support:design:23.0.1'. ps:you also must change your compileSdkVersionto 23
None of the other answers worked for me, I tried all of them
However, this one did: TabLayout not showing tabs after adding navigation bar
According to that answer, you have to enclose your TabLayout in a AppBarLayout. Why? Who knows. But at least it works.
Example Code (taken from that post):
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="200dp"
android:id="#+id/appBarLayout2">
<android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/tabLayout2"
app:tabMode="fixed"
app:tabGravity="fill"
></android.support.design.widget.TabLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:id="#+id/viewPager2"
android:layout_below="#+id/appBarLayout2">
</android.support.v4.view.ViewPager>
If you are using android:tabPadding attribute in Tablayout of xml file,remove it.
You can use FragmentStatePagerAdapter instead of FragmentPagerAdapter.
It may help you.
If someone, in future, works with TabLayout along with ViewPager2 and faces same issue. Just add .attach(); at end of new TabLayoutMediator().
new TabLayoutMediator(tabLayoutRef, viewPager2Ref, (tab, position) -> tab.setText("Tab No. "+position)).attach();

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.

Categories

Resources