替换viewpager中的片段

时间:2013-04-13 22:31:53

标签: android android-fragments android-viewpager

我目前遇到的问题是将ViewPager中的某个片段替换为另一个片段。要替换的片段ID是我的“Departments”,它具有Imagebutton id,用于开始替换。我试图从其他类似的问题中应用一些建议(其中大部分是旧的,在新的api发布之前允许嵌套片段)并且没有成功。使用嵌套片段会更容易吗?我是Android应用程序开发的新手,所以任何帮助都会很棒。提前谢谢。

这是我的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;
    }

}

此外,这是我的main.xml文件,它承载了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>

我感到困惑的一件事是,我不知道将哪个id放入transaction.replace(r.id.viewPager,newfragment)的第一个参数中......我读过它需要容器的id但是当我使用它时,我从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}

2 个答案:

答案 0 :(得分:1)

我认为重点是将片段用作容器。

在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布局应如下所示:

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

直接用你的第一个“真实”片段填充它:

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

最后,您可以替换片段。例如,在“真实”片段中,您可以有一个按钮:

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

我开发了一个显示类似概念的示例应用程序。您可以替换ViewPager中的片段而无需更改为新的Activity。该代码可在以下网址获得:

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

答案 1 :(得分:0)

我假设您希望Engineering片段位于一个全新的页面上,因为您没有在ViewPagerAdapter中使用它。如果是这种情况,请在布局中使用Activity片段创建新的Engineering,然后从Activity点击启动engineeringButton

问题是您正在尝试将您的工程片段推入R.layout.activity_departments的View层次结构中,并且(希望)没有ViewPager,因此出现错误。