0

I am currently having an issue with replacing a certain fragment within ViewPager with another. The fragment id like to replace is my "Departments" which has an Imagebutton id like to use to begin the replacement. I've tried to apply some suggestions from other similar questions (most of which were old and prior to the new api release which allows for nested fragments) and have had no success. Would using nested fragments be easier? I am new to android app development so any help would be great. Thanks in advance.

here is my FragmentAcitivty

    public class ViewPagerStyle extends FragmentActivity {
    private ViewPager mViewPager;
    private ViewPagerAdapter adapter;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        setUpView();
        setTab();
    }
    private void setUpView(){       
     mViewPager = (ViewPager) findViewById(R.id.viewPager);
     adapter = new ViewPagerAdapter(getApplicationContext(),getSupportFragmentManager());
     mViewPager.setAdapter(adapter);
     mViewPager.setCurrentItem(0);
    }
    private void setTab(){
            mViewPager.setOnPageChangeListener(new OnPageChangeListener(){

                        @Override
                        public void onPageScrollStateChanged(int position) {}
                        @Override
                        public void onPageScrolled(int arg0, float arg1, int arg2) {}
                        @Override
                        public void onPageSelected(int position) {
                            // TODO Auto-generated method stub
                            switch(position){
                            case 0:
                                findViewById(R.id.first_tab).setVisibility(View.VISIBLE);
                                findViewById(R.id.second_tab).setVisibility(View.INVISIBLE);
                                findViewById(R.id.third_tab).setVisibility(View.INVISIBLE);
                                break;

                            case 1:
                                findViewById(R.id.first_tab).setVisibility(View.INVISIBLE);
                                findViewById(R.id.second_tab).setVisibility(View.VISIBLE);
                                findViewById(R.id.third_tab).setVisibility(View.INVISIBLE);
                                break;

                            case 2:
                                findViewById(R.id.first_tab).setVisibility(View.INVISIBLE);
                                findViewById(R.id.second_tab).setVisibility(View.INVISIBLE);
                                findViewById(R.id.third_tab).setVisibility(View.VISIBLE);
                                break;
                            }
                        }

                    });

    }
}

FragmentPagerAdapter

    public class ViewPagerAdapter extends FragmentPagerAdapter {

    private Context _context;

    public ViewPagerAdapter(Context context, FragmentManager fm) {
        super(fm);  

          _context = context;
        }
    @Override
    public Fragment getItem(int position) {
        Fragment f = new Fragment();
        switch(position){
        case 0:
            f=PubView.newInstance(_context);    
            break;
        case 1:
            f=MyView.newInstance(_context); 
            break;
        case 2:
            f=Departments.newInstance(_context);
            break;

        }

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

}

Departments Fragment with button

    public class Departments extends Fragment {
    public static Fragment newInstance(Context context) {
        Departments f = new Departments();  

        return f;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
        View root = (View) inflater.inflate(R.layout.activity_departments, null);   

        ImageButton engineeringButton = (ImageButton)root.findViewById(R.id.engineeringButton);
        engineeringButton.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View v){
                Fragment newFragment = Engineering.newInstance(null);
                FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
                transaction.addToBackStack(null);
                transaction.replace(R.id.viewPager, newFragment).commit();

            }
        });

        return root;
    }

}

Also, here is my main.xml file which hosts the viewpager

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/purple"
    android:orientation="vertical" >

    <TableLayout
        style="@style/layout_f_w"
        android:stretchColumns="*" >

        <TableRow
            android:id="@+id/tableRow1"
            style="@style/layout_wrap"
            android:background="@color/white" >

            <!-- First Tab -->

            <LinearLayout
                android:id="@+id/first_text"
                style="@style/layout_f_w"
                android:orientation="vertical" >

                <TextView
                    android:id="@+id/textView1"
                    style="@style/text_title"
                    android:text="pubView"
                    android:textColor="@color/purple" />
            </LinearLayout>

            <!-- Second Tab -->

            <LinearLayout
                android:id="@+id/second_text"
                style="@style/layout_f_w"
                android:orientation="vertical" >

                <TextView
                    android:id="@+id/textView1"
                    style="@style/text_title"
                    android:gravity="center"
                    android:text="myView"
                    android:textColor="@color/purple" />
            </LinearLayout>

            <!-- Third Tab -->

            <LinearLayout
                android:id="@+id/third_text"
                style="@style/layout_f_w"
                android:orientation="vertical" >

                <TextView
                    android:id="@+id/textView1"
                    style="@style/text_title"
                    android:text="Dept."
                    android:textColor="@color/purple" />
            </LinearLayout>
        </TableRow>
    </TableLayout>
    <!-- Include Tab Indicator -->

    <include
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        layout="@layout/indicator" />

    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="fill_parent"
        android:layout_height="450dp" />

    <ImageButton
        android:id="@+id/settingsButton"
        android:layout_width="wrap_content"
        android:layout_height="30dp"
        android:layout_marginLeft="50dp"
        android:background="@drawable/settings_button"
        android:src="@drawable/settings_button" />

</LinearLayout>

One thing i am confused on is that I don't know which id to put into the first argument of transaction.replace(r.id.viewPager, newfragment)...Ive read that it needs the id of the container but when I use this I receive the runtime error from logcat:

04-13 21:41:48.680: E/AndroidRuntime(960): java.lang.IllegalArgumentException: No view found for id 0x7f0a0029 (com.pvcalendar:id/viewPager) for fragment Engineering{4089a730 #0 id=0x7f0a0029}
playboy
  • 3
  • 2

2 Answers2

1

I think the point is to use a fragment as a container.

In your ViewPagerAdapter:

    @Override
    public Fragment getItem(int position) {
        /*
         * IMPORTANT: This is the point. We create a RootFragment acting as
         * a container for other fragments
         */
        if (position == 0)
            return new RootFragment();
        else
            return new StaticFragment();
    }

RootFragment layout should look like:

<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"
  android:id="@+id/root_frame" >
</FrameLayout>

And directly, you fill it with your first "real" fragment:

public class RootFragment extends Fragment {

private static final String TAG = "RootFragment";

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    /* Inflate the layout for this fragment */
    View view = inflater.inflate(R.layout.root_fragment, container, false);

    FragmentTransaction transaction = getFragmentManager()
            .beginTransaction();
    /*
     * When this container fragment is created, we fill it with our first
     * "real" fragment
     */
    transaction.replace(R.id.root_frame, new FirstFragment());

    transaction.commit();

    return view;
}
}

Finally, you can replace fragments. For instance, inside your "real" fragment you could have a button:

btn.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            FragmentTransaction trans = getFragmentManager()
                    .beginTransaction();
            /*
             * IMPORTANT: We use the "root frame" defined in
             * "root_fragment.xml" as the reference to replace fragment
             */
            trans.replace(R.id.root_frame, new SecondFragment());

            /*
             * IMPORTANT: The following lines allow us to add the fragment
             * to the stack and return to it later, by pressing back
             */
            trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
            trans.addToBackStack(null);

            trans.commit();
        }
    });

I've developed an example application that shows a similar concept. You could replace a fragment inside a ViewPager without changing to a new Activity. The code is available in:

https://github.com/danilao/fragments-viewpager-example

dlao
  • 351
  • 2
  • 9
  • Hi @dlao I tried your project its really nice solution but I am facing an issue when I go to 2nd fragment1 by clicking on button in that fragment and now if I swipe and go to next fragment(static) .. Here if I press back it closing the secondfragment... so know if i swipe to firstfragment insted of secondfragment there appears 1st fragment.. Do you have any solution to this?? – Pramod May 16 '14 at 13:31
  • Hi @Pramod. Not at the moment, but I'll check it. Thanks for your comment. – dlao May 21 '14 at 16:21
0

I'm assuming you want the Engineering fragment to be on a completely new page, because you aren't using it in your ViewPagerAdapter. If that's the case, create a new Activity, with your Engineering fragment in the layout, and launch the Activity from the engineeringButton click.

The problem is you are trying to shove your Engineering fragment into the View hierarchy of R.layout.activity_departments, and there is (hopefully) no ViewPager in there, hence the error.

Christopher Perry
  • 38,891
  • 43
  • 145
  • 187
  • 1
    Yea, you are right. This actually turned out to be an easy fix. I originally didn't have an "id" for my Departments layout, which is why the fragment manager couldn't find the view to replace anything with. As soon as I gave my activity_departments.xml an ID for it to be recognized in transaction.replace() it now works. A bone head miss by me but I really do appreciate your input and your want to help me. Thanks :) – playboy Apr 14 '13 at 19:40