1

I'm essentially a new Android Studio developer and currently I am attempting to switch between 3 tabs for my program. Unfortunately, the program forces a close when I try to open things up. I'm not entirely sure where the problem lies since I declared an instance of the classes in regards to the tab.

MainActivity.java

import java.util.Locale;
import android.app.Activity;
import android.app.ActionBar;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.support.v13.app.FragmentPagerAdapter;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;


public class Main extends Activity implements ActionBar.TabListener {


    Fragment FragmentTab1 = new Tab1();
    Fragment FragmentTab2 = new Tab2();
    Fragment FragmentTab3 = new Tab3();
    /**
     * The {@link android.support.v4.view.PagerAdapter} that will provide
     * fragments for each of the sections. We use a
     * {@link FragmentPagerAdapter} derivative, which will keep every
     * loaded fragment in memory. If this becomes too memory intensive, it
     * may be best to switch to a
     * {@link android.support.v13.app.FragmentStatePagerAdapter}.
     */
    SectionsPagerAdapter mSectionsPagerAdapter;

    /**
     * The {@link ViewPager} that will host the section contents.
     */
    ViewPager mViewPager;

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

        // Set up the action bar.
        final ActionBar actionBar = getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        // Create the adapter that will return a fragment for each of the three
        // primary sections of the activity.
        mSectionsPagerAdapter = new SectionsPagerAdapter(getFragmentManager());

        // Set up the ViewPager with the sections adapter.
        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mSectionsPagerAdapter);


        // When swiping between different sections, select the corresponding
        // tab. We can also use ActionBar.Tab#select() to do this if we have
        // a reference to the Tab.
        mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                actionBar.setSelectedNavigationItem(position);
            }
        });

        // For each of the sections in the app, add a tab to the action bar.
        for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
            // Create a tab with text corresponding to the page title defined by
            // the adapter. Also specify this Activity object, which implements
            // the TabListener interface, as the callback (listener) for when
            // this tab is selected.
            actionBar.addTab(
                    actionBar.newTab()
                            .setText(mSectionsPagerAdapter.getPageTitle(i))
                            .setTabListener(this));
        }
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.auth_port, menu);
        return true;
    }


    @Override
    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
        // When the given tab is selected, switch to the corresponding page in
        // the ViewPager.
        mViewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
    }

    @Override
    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
    }

    /**
     * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
     * one of the sections/tabs/pages.
     */
    public class SectionsPagerAdapter extends FragmentPagerAdapter {

        public SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            // getItem is called to instantiate the fragment for the given page.
            // Return a PlaceholderFragment (defined as a static inner class below).
            Fragment fragment = null;
            if (position == 0)
            {
                fragment = FragmentTab1;
            }
            if (position == 1)
            {
                fragment = FragmentTab2;
            }
            if (position == 2)
            {
                fragment = FragmentTab3;
            }
            return fragment;
        }

        @Override
        public int getCount() {
            // Show 3 total pages.
            return 3;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            Locale l = Locale.getDefault();
            switch (position) {
                case 0:
                    return getString(R.string.title_section1).toUpperCase(l);
                case 1:
                    return getString(R.string.title_section2).toUpperCase(l);
                case 2:
                    return getString(R.string.title_section3).toUpperCase(l);
            }
            return null;
        }
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {
        /**
         * The fragment argument representing the section number for this
         * fragment.
         */
        private static final String ARG_SECTION_NUMBER = "section_number";

        /**
         * Returns a new instance of this fragment for the given section
         * number.
         */
        public static PlaceholderFragment newInstance(int sectionNumber) {
            PlaceholderFragment fragment = new PlaceholderFragment();
            Bundle args = new Bundle();
            args.putInt(ARG_SECTION_NUMBER, sectionNumber);
            fragment.setArguments(args);
            return fragment;
        }

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);
            return rootView;
        }
    }

Tab1 (The Other 2 Tabs are the same)

import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;



/**
 * A simple {@link Fragment} subclass.
 * Activities that contain this fragment must implement the
 * {@link Tab1.OnFragmentInteractionListener} interface
 * to handle interaction events.
 * Use the {@link Charge#newInstance} factory method to
 * create an instance of this fragment.
 *
 */
public class Tab1 extends Fragment {
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    private OnFragmentInteractionListener mListener;

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment Tab1
     */
    // TODO: Rename and change types and number of parameters
    public static Charge newInstance(String param1, String param2) {
        Tab1 fragment = new Tab1();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }
    public Tab1() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_tab1, container, false);
    }

    // TODO: Rename method, update argument and hook method into UI event
    public void onButtonPressed(Uri uri) {
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
        }
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnFragmentInteractionListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

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

    /**
     * This interface must be implemented by activities that contain this
     * fragment to allow an interaction in this fragment to be communicated
     * to the activity and potentially other fragments contained in that
     * activity.
     * <p>
     * See the Android Training lesson <a href=
     * "http://developer.android.com/training/basics/fragments/communicating.html"
     * >Communicating with Other Fragments</a> for more information.
     */
    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        public void onFragmentInteraction(Uri uri);
    }

}

I've looked on other websites for help on this, mostly they cover programs that are obsolete or don't cover the question completely, I have nothing else to turn to so any help on this problem I'd appreciate it.

Edit: I've learned it has to do with creating a .newinstance of the class but how this gets accomplished I haven't quite grasped yet.

Logcat output. Only included error portion

10-29 21:04:04.599 9452-9452/com.example.main E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.authpayx.authportbeta04, PID: 9452 java.lang.ClassCastException: com.example.main.main@42d45398 must implement OnFragmentInteractionListener at com.example.main.Tab1.onAttach(Tab1.java:84) at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:849) at android.app.FragmentManagerImpl.performPendingDeferredStart(FragmentManager.java:785) at android.app.Fragment.setUserVisibleHint(Fragment.java:997) at android.support.v13.app.FragmentCompatICSMR1.setUserVisibleHint(FragmentCompatICSMR1.java:23) at android.support.v13.app.FragmentCompat$ICSMR1FragmentCompatImpl.setUserVisibleHint(FragmentCompat.java:48) at android.support.v13.app.FragmentCompat.setUserVisibleHint(FragmentCompat.java:76) at android.support.v13.app.FragmentPagerAdapter.setPrimaryItem(FragmentPagerAdapter.java:134) at android.support.v4.view.ViewPager.populate(ViewPager.java:1071) at android.support.v4.view.ViewPager.populate(ViewPager.java:919) at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1441) at android.view.View.measure(View.java:17478) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5364) at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) at android.view.View.measure(View.java:17478) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5364) at com.android.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:412) at android.view.View.measure(View.java:17478) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5364) at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2548) at android.view.View.measure(View.java:17478) at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2262) at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1391) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1590) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1249) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6585) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:803) at android.view.Choreographer.doCallbacks(Choreographer.java:603) at android.view.Choreographer.doFrame(Choreographer.java:573) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:789) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5579) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084) at dalvik.system.NativeStart.main(Native Method)

The Radio Guy
  • 11
  • 1
  • 4

3 Answers3

0

You must implement OnFragmentInteractionListener inside your main activity. change

public class Main extends Activity implements ActionBar.TabListener

to

public class Main extends Activity implements ActionBar.TabListener, OnFragmentInteractionListener

Then make sure your implement

public void onFragmentInteraction(Uri uri);

inside your main activity.

A little info on the new instance method. This is a common practice not a special method you are implementing. You can call it anything that you want but the idea is that new instance method takes your parameters and adds them to a bundle. when android destroys your fragment it gets recreated using its default constructor which does not have your data.

The solution is to use a new instance method and put your data in a bundle because when android recreates your fragment its bundle sticks around.

The only time you would not care about new instance is when you are not passing anything into your fragment.

doubleA
  • 2,446
  • 22
  • 45
0

It seems that this issue related to your Tab1 Fragment class. Also it seems that you created this Fragment class by android studio auto generated blank Fragment class.
For fixing this issue you can change codes of auto generated Fragment classes like Tab1 with code like below.

package com.example.android.actionbarcompat.styled;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
* Created by taher on 1/7/15.
*/
public class MainFragment extends Fragment {
 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.main_view, container, false);
 }
}

If you want to use your Tab1 fragment class please not that below comment from your Fragment Class.

/**
 * This interface must be implemented by activities that contain this
 * fragment to allow an interaction in this fragment to be communicated
 * to the activity and potentially other fragments contained in that
 * activity.
 * <p>
 * See the Android Training lesson <a href=
 * "http://developer.android.com/training/basics/fragments/communicating.html"
 * >Communicating with Other Fragments</a> for more information.
 */
public interface OnFragmentInteractionListener {
    // TODO: Update argument type and name
    public void onFragmentInteraction(Uri uri);
}
taher
  • 539
  • 1
  • 9
  • 22
0

I had the same problem, and in my case, delete

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        mListener = (OnFragmentInteractionListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement OnFragmentInteractionListener");
    }
}

these code, problem solved

cdytoby
  • 839
  • 10
  • 26