Send Data to 2 Fragments on Click

0

I'm quite new to java, and I want to send data from my first fragment to the second and third fragments on button click. I'm using bundles and keep getting force closed. The codes are below. After some trials looks like the issue is in the last line of the first fragment:

FragmentManager fragmentManager = myContext.getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.secondLayout, fragment).commit();
fragmentManager.beginTransaction().replace(R.id.thirdLayout, fragment).commit();

but I have not find a way to fix it yet. Any help would be appreciated, thank you!

FirstFragment.java

private FragmentActivity myContext;
@Override
public void onAttach(@NotNull Context context) {
    super.onAttach(context);
    myContext =(FragmentActivity) context;
}

@Override
public void onDetach() {
    super.onDetach();
    myContext = null;
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    final View view = inflater.inflate(R.layout.fragment_first, container, false);

    final EditText inNum1 = view.findViewById (R.id.inEnergyUse);
    final EditText inNum3 = view.findViewById (R.id.inPeakSun);
    final EditText inNum4 = view.findViewById (R.id.inSolarCover);
    final Button calc = view.findViewById(R.id.btn1Calc);

    calc.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            double a = Double.parseDouble(inNum1.getText().toString());
            double b = Double.parseDouble(inNum3.getText().toString());
            double c = Double.parseDouble(inNum4.getText().toString());
            double minPVSize = new BigDecimal((a / 30 * c / 100) / b / 0.8).setScale(2, RoundingMode.HALF_UP).doubleValue();
            double solarGenerated = new BigDecimal(a  * 12 * c / 100).setScale(2, RoundingMode.HALF_UP).doubleValue();
            double CO2FullGrid = new BigDecimal(a * 0.37).setScale(2, RoundingMode.HALF_UP).doubleValue();

            SecondFragment fragment = new SecondFragment();
            Bundle args = new Bundle();
            args.putString("argPV", String.valueOf(minPVSize));
            args.putString("argSolar", String.valueOf(solarGenerated));
            args.putString("argCO2", String.valueOf(CO2FullGrid));
            fragment.setArguments(args);

            FragmentManager fragmentManager = myContext.getSupportFragmentManager();
            fragmentManager.beginTransaction().replace(R.id.secondLayout, fragment).commit();
            fragmentManager.beginTransaction().replace(R.id.thirdLayout, fragment).commit();
        }
    });
    return view;
}

SecondFragment.java

private String ans1;
private String ans2;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    final View view = inflater.inflate(R.layout.fragment_second, container, false);

    if (getArguments() !=null) {
        ans1 = getArguments().getString("argPV");
        ans2 = getArguments().getString("argSolar");
    }

    TextView minPVSize = view.findViewById(R.id.minPVSize);
    minPVSize.setText(ans1);
    TextView solarGenerated = view.findViewById(R.id.solarGenerated);
    solarGenerated.setText(ans2);

    return view;
}

ThirdFragment.java

private String ans3;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    final View view = inflater.inflate(R.layout.fragment_third, container, false);

    if (getArguments() !=null) {
        ans3 = getArguments().getString("argCO2");
    }

    TextView gridC02 = view.findViewById(R.id.gridCO2);
    gridC02.setText(ans3);

    return view;
}

POST UPDATED with logcat:

05-17 135853.145 7235-7235com.example.solarpanelandcarboncalculator EAndroidRuntime FATAL EXCEPTION main
Process com.example.solarpanelandcarboncalculator, PID 7235
java.lang.IllegalArgumentException No view found for id 0x7f080158 (com.example.solarpanelandcarboncalculatoridthirdLayout) for fragment ThirdFragment{2a3c831d} (cd17f1a2-11b8-477f-b9dc-3c91a381b4ed) id=0x7f080158}
    at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java315)
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java1187)
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java1356)
    at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java1434)
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java1497)
    at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java447)
    at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java2169)
    at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java1992)
    at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java1947)
    at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java1849)
    at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java413)
    at android.os.Handler.handleCallback(Handler.java739)
    at android.os.Handler.dispatchMessage(Handler.java95)
    at android.os.Looper.loop(Looper.java135)
    at android.app.ActivityThread.main(ActivityThread.java5254)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java903)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java698)
05-17 135853.146 1547-1561system_process WActivityManager   Force finishing activity 1 com.example.solarpanelandcarboncalculator.MainActivity
05-17 135853.152 1145-1653 Dgralloc_ranchu gralloc_alloc Creating ashmem region of size 1806336
05-17 135853.158 1145-1145 EEGL_emulation tid 1145 eglCreateSyncKHR(1881) error 0x3004 (EGL_BAD_ATTRIBUTE)
05-17 135853.210 1547-1622system_process IOpenGLRenderer Initialized EGL, version 1.4
05-17 135853.217 1547-1622system_process DEGL_emulation eglCreateContext 0xb42bc880 maj 2 min 0 rcv 2
05-17 135853.221 1547-1622system_process DEGL_emulation eglMakeCurrent 0xb42bc880 ver 2 0 (tinfo 0xa28297c0)
05-17 135853.246 1547-1622system_process DEGL_emulation eglMakeCurrent 0xb42bc880 ver 2 0 (tinfo 0xa28297c0)
05-17 135853.674 1547-1568system_process WActivityManager Activity pause timeout for ActivityRecord{255655e9 u0 com.example.solarpanelandcarboncalculator.MainActivity t270 f}
05-17 135854.086 1818-2131com.google.android.googlequicksearchbox DEGL_emulation eglMakeCurrent 0xae834e20 ver 2 0 (tinfo 0xae839500)
05-17 135854.877 1547-1573system_process IChoreographer Skipped 68 frames!  The application may be doing too much work on its main thread.
05-17 135854.883 1818-1818com.google.android.googlequicksearchbox IChoreographer Skipped 71 frames!  The application may be doing too much work on its main thread.
05-17 135854.900 1672-1672com.android.systemui WResourceType No package identifier when getting value for resource number 0x00000000
05-17 135854.900 1672-1672com.android.systemui WPackageManager Failure retrieving resources for com.example.solarpanelandcarboncalculator Resource ID #0x0
05-17 135855.386 1818-2131com.google.android.googlequicksearchbox DEGL_emulation eglMakeCurrent 0xae834e20 ver 2 0 (tinfo 0xae839500)
05-17 135855.599 1818-2131com.google.android.googlequicksearchbox DEGL_emulation eglMakeCurrent 0xae834e20 ver 2 0 (tinfo 0xae839500)
05-17 135855.600 1818-2131com.google.android.googlequicksearchbox DEGL_emulation eglMakeCurrent 0xae834e20 ver 2 0 (tinfo 0xae839500)
05-17 135855.601 1818-2131com.google.android.googlequicksearchbox WOpenGLRenderer Incorrectly called buildLayer on View aep, destroying layer...
05-17 135855.601 1818-2131com.google.android.googlequicksearchbox DEGL_emulation eglMakeCurrent 0xae834e20 ver 2 0 (tinfo 0xae839500)
05-17 135900.016 1672-2075com.android.systemui DEGL_emulation eglMakeCurrent 0xb43e1100 ver 2 0 (tinfo 0xb437bea0)
05-17 135905.427 1547-1568system_process WActivityManager Activity destroy timeout for ActivityRecord{255655e9 u0 com.example.solarpanelandcarboncalculator.MainActivity t270 f}
05-17 135905.432 1145-1145 WSurfaceFlinger couldn't log to binary event log overflow.
05-17 140049.211 1150-1478 DMDnsDS MDnsSdListenerMonitor poll timed out
05-17 140049.211 1150-1478 DMDnsDS Going to poll with pollCount 1

POST UPDATED with MainActivity.java

public class MainActivity extends AppCompatActivity {
private ViewPager viewPager;
private TabLayout tabLayout;
private FirstFragment firstFragment;
private SecondFragment secondFragment;
private ThirdFragment thirdFragment;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    viewPager = findViewById(R.id.view_pager);
    tabLayout = findViewById(R.id.tab_layout);
    firstFragment = new FirstFragment(); // this should be created in FragmentPagerAdapter.getItem()
    secondFragment = new SecondFragment(); // this should be created in FragmentPagerAdapter.getItem()
    thirdFragment = new ThirdFragment(); // this should be created in FragmentPagerAdapter.getItem()

    tabLayout.setupWithViewPager(viewPager);
    viewPagerAdapter viewPagerAdapter = new viewPagerAdapter(getSupportFragmentManager(), FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
    viewPagerAdapter.addFragment(firstFragment, "Input"); // this line can cause crashes
    viewPagerAdapter.addFragment(secondFragment, "Savings"); // this line can cause crashes
    viewPagerAdapter.addFragment(thirdFragment, "Carbon"); // this line can cause crashes
    viewPager.setAdapter(viewPagerAdapter);

    tabLayout.getTabAt(0).setIcon(R.drawable.ic_input);
    tabLayout.getTabAt(1).setIcon(R.drawable.ic_cost_save);
    tabLayout.getTabAt(2).setIcon(R.drawable.ic_carbon_save);
}

private class viewPagerAdapter extends FragmentPagerAdapter{
    private List<Fragment> fragmentList = new ArrayList<>(); // this line can cause crashes
    private List<String> fragmentTitle = new ArrayList<>();

    public viewPagerAdapter(@NonNull FragmentManager fm, int behavior) {
        super(fm, behavior);
    }
    public void addFragment(Fragment fragment, String title){
        fragmentList.add(fragment); // this line can cause crashes
        fragmentTitle.add(title);
    }

    @NonNull
    @Override
    public Fragment getItem(int position) {
        return fragmentList.get(position);
    }

    @Override
    public int getCount() {
        return fragmentList.size();
    }

    @Nullable
    @Override
    public CharSequence getPageTitle(int position) {
        return fragmentTitle.get(position);
    }
}

}

java
android
asked on Stack Overflow May 17, 2020 by Chris K • edited Jan 21, 2021 by EpicPandaForce

3 Answers

0

We need the stack trace to be certain, but looks like the issue is that you add the same instance of a fragment to 2 containers - that's not allowed

        FragmentManager fragmentManager = myContext.getSupportFragmentManager();
        fragmentManager.beginTransaction().replace(R.id.secondLayout, fragment).commit();
        fragmentManager.beginTransaction().replace(R.id.thirdLayout, fragment).commit();

This should be

        SecondFragment secondFragment = new SecondFragment();
        ThirdFragment thirdFragment = new ThirdFragment();

        /* other stuff */

        FragmentManager fragmentManager = myContext.getSupportFragmentManager();
        fragmentManager
            .beginTransaction()
            .replace(R.id.secondLayout, secondFragment)
            .replace(R.id.thirdLayout,thirdFragment)
            .commit();

I combined both transactions into a single one as well.

answered on Stack Overflow May 17, 2020 by Francesc
0

Have all your fragments implement an interface with desired methods. You can then call the methods using fragment instances and pass in data.

interface SomeInterface {
     void update(String data);
}

SecondFragment implements SomeInterface {
     ...
     @Override
     void update(String data) {
        // do something with data
     }
}

Same with ThirdFragment.

From your main fragment, call these methods:

secondFragment.update(data);
thirdFragment.update(data);
answered on Stack Overflow May 17, 2020 by XurajB
0

The correct way to implement a regular FragmentPagerAdapter is:

public class ViewPagerAdapter extends FragmentPagerAdapter {
    public ViewPagerAdapter(FragmentManager fragmentManager) {
        super(fragmentManager);
    }

    @Override
    public Fragment getItem(int position) {
        if(position == 0) return new FirstFragment();
        if(position == 1) return new SecondFragment();
        if(position == 2) return new ThirdFragment();

        throw new IllegalStateException("Unexpected position " + position);
    }

    @Override
    public int getCount() {
        return 3;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        if(position == 0) return "Input";
        if(position == 1) return "Savings";
        if(position == 2) return "Carbon";
      
        throw new IllegalStateException("Unexpected position " + position);
    }
}

To get a reference to a Fragment created by a ViewPager, use the following findFragmentByTag scheme:

Fragment fragment = supportFragmentManager.findFragmentByTag("android:switcher:" + viewPager.getId() + ":" + fragmentPosition)

With that, you can communicate to the host Activity using getActivity(), and the activity can find the fragment by tag, and invoke methods on it. Lately, you can use an Activity-scoped ViewModel, and each Fragment can observe a LiveData in it.

answered on Stack Overflow Jan 21, 2021 by EpicPandaForce

User contributions licensed under CC BY-SA 3.0