Trying to move from one fragment to another with a button - java

So my goal is to swap from my CalculatorFragment to my CalculatorResultsFragment using a parent FrameLayout through a a button. I'm getting the error:
java.lang.IllegalArgumentException: No view found for id 0x7f08020f (com.example.flexplan:id/parent_fragment) for fragment CalculatorResultsFragment{1046933} (71b49e01-2328-4454-870b-5acb04ccc3d0 id=0x7f08020f)
fragment_calculator_fragment.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"
tools:context=".Calculator.CalculatorParentFragment">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/parent_fragment"/>
</LinearLayout>
CalculatorParentFragment.java
FragmentManager manager = getChildFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.parent_fragment, new CalculatorFragment());
transaction.commit();
CalculatorFragment.java
submitButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FragmentManager manager = getChildFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.parent_fragment, new CalculatorResultsFragment());
transaction.commit();
}
});
Anyone know how I can fix this?

Error says you do not have view for your fragment, check your layout files, for each fragment you need to have one layout, if not transaction can not send you there. After all layouts in place, follow the docs link like so:
FragmentManager fragmentManager = getChildFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.setReorderingAllowed(true);
transaction.replace(R.id.parent_fragment, CalculatorResultsFragment.class, null);
transaction.commit();

Related

Can't call Fragment method in parent Activity

I simply want to call a method from a fragment in my MainActivity(parent).
But as soon as I try to call the method I get an NullPointerException.
Attempt to invoke virtual method 'void
com.example.fragmenttest.TestFragment.testMethod()' on a null object
reference
Here is what I do in the onCreate of the MainActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.containerView, new TestFragment()).commit();
TestFragment fragment = (TestFragment) fragmentManager.findFragmentById(R.id.testfragment);
fragment.testMethod();
}
and here is the fragment:
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView=inflater.inflate(R.layout.activity_fragment,container,false);
return rootView;
}
public void testMethod(){
Toast.makeText(getContext(), "Test", Toast.LENGTH_LONG).show();
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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=".MainActivity">
<FrameLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/containerView">
</FrameLayout>
</RelativeLayout>
and activity_fragment.xml:
<?xml version="1.0" encoding="utf-8"?>
<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="com.example.fragmenttest.MainActivity"
android:id="#+id/testfragment">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="50dp"
android:text="Fragment" />
</RelativeLayout>
Of course this is not my real project, I just created a new one to simplify my issue.
In my real project I want to call a method from my fragment as soon as the onRewardedVideoCompleted method gets called, which is in my MainActivity.
How do I call the method from my fragment without getting a null pointer exception and without using an interface? (Using an interface for this small problem seems unnecessary)
Thanks
commit() is asynchronous. This is why your project is crashing upon launch. Instead of using commit(), use commitNow(). Also, instead of using new TestFragment(), create a variable so you can call its methods.
TestFragment testFragment= new TestFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.containerView, testFragment).commitNow();
testFragment.testMethod();
Fragment transactions are asynchronous (unless you use executePendingTransactions()). Your transaction has likely not completed yet. You use runOnCommit on FragmentTransaction (in the support library) to execute code after it is done.
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
TestFragment yourFragment = newe TestFragment();
fragmentTransaction.replace(R.id.containerView, yourFragment).commit();
yourFragment.testMethod();
First of all, You must pass yourFragment to fragmentTransaction, then you can call any methods you want.

How to start a fragment from an activity

I am trying to run a class extending a fragment from a class extending AppCompactActivity, I have tried everything I have saw in Stackover flow and I cant get any to fix my problem. LineDetails is extending the Fragment
Progress1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Fragment fr = new LineDetails();
android.app.FragmentManager fm = getFragmentManager();
android.app.FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.fragment_place, fr);
fragmentTransaction.commit();
}
});
XML
<fragment android:name="com.almac.tracker.LineDetails"
android:id="#+id/fragment_place"
android:layout_width="match_parent"
android:layout_height="match_parent" />
PART OF XML FOR ACTIVITY CLASS
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
android:overScrollMode="never"
android:scrollbars="none"
tools:context=".Dashboard">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/fragment_place">
</FrameLayout>
</RelativeLayout >
If your activity extends AppCompatActivity, then you cannot use getFragmentManager().
In fact you should get rid of classes in the package android.app such as android.app.FragmentManager. You should use the support classes from the package android.support.v4.app such as android.support.v4.app.FragmentManager
Use getSupportFragmentManager() instead of getFragmentManager()
The stack trace reports that you don't have any Layout with id R.id.fragment_place inside your activity. Check the xml of your activity and correct the id of fragment holder.
You're replacing instead of adding without a refresh, just do an add. I also simplified one of your useless variables and just went straight to ft instead of having an intermediate fm.
Progress1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Fragment fr = new LineDetails();
android.app.FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(R.id.fragment_place, fr);
ft.commit();
}
});
getSupportFragmentManager() should be used if activity extends AppcompatActivity
EDIT :
As per the Errors ! There is no View named fragment_place in the activity's layout that is #+id/fragment_place must exist in activity_main (If this is the layout attached to activity)
Double check your layout xml, It should have a FrameLayout with attribute #+id/fragment_place act as a placeholder for your LineDetails fragment.
If you already place <fragment /> in your layout, you don't need to replace() it programmatically.

Default fragment on Activity Launch

I'm trying to have a fragment loaded as the default view for the activity, but I just get a blank screen and huge memory leaks.
Activity file onCreate method:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
if (savedInstanceState == null) {
FragmentManager fragmentManager = getFragmentManager();
int fragmentTransaction = fragmentManager.beginTransaction()
.add(R.id.login_screen_fragment, new FragmentLogin())
.commit();
}
}
The XML for the activity:
<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"
tools:context=".LoginActivity">
<fragment
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/login_screen_fragment"
class="com.test.project.FragmentLogin"
/>
<fragment
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/forgotten_password_fragment"
class="com.test.project.FragmentForgottenPassword"
/>
</FrameLayout>
And the Fragment class (relevant parts):
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_login, container, false);
final Activity activity = getActivity();
... code ...
return view;
}
I followed instructions from a tutorial someone suggested earlier from a different question, but I must be doing something horribly wrong. Any ideas?
xml file
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/changeFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LoginActivity">
</FrameLayout>
your activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
if (savedInstanceState == null) {
FragmentLogin f1= new FragmentLogin();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.changeFragment, f1);
fragmentTransaction.commit();
}
}
I'm new to Android and I ran into the same problem. Here's how I fixed mine.
So in your onCreate method, use getSupportFragmentManager() from the FragmentManager class then declare FragmentTransaction separately. See below. I did this for my case and it worked.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
if (savedInstanceState == null) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.login_screen_fragment, new FragmentLogin());
fragmentTransaction.commit();
}
Hope this helps solve your problem as well.
Sincerely,
sylvery
Just replace the fragment element with FrameLayout, then you can see your fragment.
If you wanted to add the Fragment programatically, then remove the <Fragment> in your Framelayout and add some ID unto it.
It should look like this:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/login_screen_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LoginActivity" />

android onClick Button inside fragment not work and no errors

I created a fragment with some buttons and I'm trying to call other fragment by clicking on the button but nothing happens, no errors, no actions.
This is my implementation:
main_activit.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"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#color/grey"
tools:context=".MainActivity"
android:weightSum="1"
android:orientation="vertical"
>
<android.support.v7.widget.Toolbar
android:id="#+id/mainToobar"
android:layout_height="?attr/actionBarSize"
android:layout_width="match_parent"
android:elevation="4dp"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:title="#string/mainToobarTitle"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
/>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/homebuttons_fragment_container"
android:layout_width="match_parent"
android:layout_height="200dp" />
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main_fragment_container"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
HomeButtonsFragment.java
public class HomeButtonsFragment extends Fragment implements View.OnClickListener {
#Override
public View onCreateView(
LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState
) {
View view = inflater.inflate(R.layout.fragment_home_buttons, container, false);
Button button = (Button) view.findViewById(R.id.schedule_home_button);
button.setOnClickListener(this);
return view;
}
#Override
public void onClick(View v) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ScheduleFragment scheduleFragment = new ScheduleFragment();
fragmentTransaction.add(R.id.main_fragment_container, scheduleFragment);
}
}
fragment_home_button.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Button
android:id="#+id/schedule_home_button"
android:layout_width="100dp"
android:layout_height="fill_parent"
android:layout_alignParentEnd="true"
android:text="#string/label.home.button.schedule"
android:tag="home_button"
android:stateListAnimator="#null"
style="#style/ScheduleButton"
/>
</RelativeLayout>
You miss .commit() in your fragmentTransaction statement.
fragmentTransaction.add(R.id.main_fragment_container, scheduleFragment).commit();
u missed commit();,i am sure small things will be missed sometimes,just add commit(); , it will work fine
use this
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ScheduleFragment scheduleFragment = new ScheduleFragment();
fragmentTransaction.add(R.id.main_fragment_container, scheduleFragment).commit();
#Override
public void onClick(View v) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ScheduleFragment scheduleFragment = new ScheduleFragment();
fragmentTransaction.add(R.id.main_fragment_container, scheduleFragment).commit();
or
fragmentTransaction.commit();
}
Your onClick method should be,
#Override
public void onClick(View v) {
if(v.getId()==R.id.schedule_home_button){
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ScheduleFragment scheduleFragment = new ScheduleFragment();
fragmentTransaction.add(R.id.main_fragment_container, scheduleFragment).commit();
}
}

Android: simple replace fragment with an other fragment

I've run into an issue with my code.
What I want
My Activity starts automatically with Fragment01.
On Fragment01, there is a button, which should replace Fragment01 with Fragment02
What happens
When I press the button, instead of replacing Fragment01, I can still see Fragment01 in the background
MainActivity.java:
package com.lucky.fragmentexample;
import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
Button bn;
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bn = (Button)findViewById(R.id.button1);
bn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Fragment02 fragment02 = new Fragment02();
fragmentTransaction.replace(R.id.button_fragment_container, fragment02);
fragmentTransaction.commit();
}
});
}
}
activity_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<FrameLayout
android:id="#+id/button_fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:id="#+id/fragment01"
android:name="com.lucky.fragmentexample.Fragment01"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
</LinearLayout>
Your fragment element in your layout XML can only ever refer to that single fragment and can't be swapped out in the way you intend. Instead, you need to remove the fragment element from your layout XML entirely and add your Fragment01 into your container FrameLayout in code in the onCreate() method of your activity.
So, remove the fragment element, like so;
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<FrameLayout
android:id="#+id/button_fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
Then you can perform your transaction in the beginning of your onCreate() override, like so;
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
transaction.replace(R.id.button_fragment_container, new Fragment01());
transaction.commit();
You will want to instantiate a new FragmentTransaction for each new transaction, which means you'll probably want to remove the FragmentManager and FragmentTransaction from your instance members and declare them fresh each time you need to make a fragment transaction.
I hope this helps.
Further reading:
Official Fragments API Tutorial
Put beginTransaction inside onclick function and replace R.id.button_fragment_container for R.id.frame_container.
Use this inside onclick:
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.frame_container, new Fragment02()).commit();
Fragment inside xml file is not correct. Erase that part.
try this code :
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.fragment01, new Fragment02());
fragmentTransaction.commit();
also, change the 'fragment' to 'FrameLayout' in your xml. This prevents from any one fragment always remaining in the background.
Just go step by step:
First modify your layout, remove the fragment over there and make the reference of your FrameLayout in the activity.
Now initiate your fragment class which you want to add to the framelayout and call following code:
FragmentTransaction transaction = manager.beginTransaction();
transaction.remove(removePreviousFragmentIfAny);
transaction.add(R.id.button_fragment_container, newFragment);
transaction.commit();
Hope it will help you to go through.

Categories

Resources