天天看点

关于fragment、ActionBar与ViewPager的一些总结

今天花了大半天去研究ActionBar获取指针为空,fragment嵌套失败等问题,在此做一些总结,以免之后再犯错:

今天主要工作为在atyA中填充fragmentA,而在fragmentA中初始化ActionBar与ViewPager,而ViewPager实现FragmentPagerAdapter来填充内容

分别使用了:

import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;      

以上组合能够正常运行

一.为了使用ActionBar,由于Theme.Holo不能使用(待解决),在application中使用@style/AppTheme,它继承在API不同时使用的其实是不同的style.xml文件:

values-v11代表在API 11+的设备上,用该目录下的styles.xml代替res/values/styles.xml,其中API 11+代表android 3.0 +

values-v14代表在API 14+的设备上,用该目录下的styles.xml代替res/values/styles.xml,其中API 14+代表android 4.0 +

二.为了出现ActionBar,最好使用ActionBarActivity,用过demo测试过android.support.v4.app.FragmentActivity无法显示ActionBar,而换成android.support.v7.ActionBarActivity之后可以正常显示。查看源代码后,发现:   

android.support.v7.ActionBarActivity(并没有实现额外的方法)继承自android.support.v7.app.AppCompatActivity,

而android.support.v7.app.AppCompatActivity,继承自android.support.v4.app.FragmentActivity,

而android.support.v4.app.FragmentActivity继承自android.app.Activity

其中:Activity实现了getFragmentManager(),而FragmentActivity实现了getSupportFragmentManager(),所以AppCompatActivity与ActionBarActivity使用getSupportFragmentManager会比较合适。

Activity实现了getActionBar(),而AppCompatActivity实现了getSupportActionBar。

三.在Fragment中获取ActionBar:(比如要设计点击对应Tab时,fragment中的viewpager会selected到对应的子fragment,这时候不方便在activity中进行监听,将ActionBar.TabListener接口的实现放在fragment中就挺好。)

ab_main = ((ActionBarActivity)getActivity()).getSupportActionBar();      

需要将getActivit()获取的引用强制类型转换成ActionBarActivity,否则getSupportActionBar()报错。

个人认为是重写Fragment的onAttach()方法时,绑定的是Activity而不是ActionBarActivity:

public void onAttach(Activity activity) {

    super.onAttach(activity);
}
      

而若使用

ab_main = getActivity().getActionBar();      
获取的不是android.support.v7.app.ActionBar而是android.app.ActionBar      

四.ViewPager使用FragmentPagerAdapter来填充

由于是在Fragment中对ViewPager进行填充,故需要先使用getActivity()来获取依赖的Activity,再利用getSupportFragmentManager()方法将FragmentManager传入

FragmentMainVpAdapter adapter = new FragmentMainVpAdapter(getActivity().getSupportFragmentManager());      

以下是FragmentMainVpAdapter.java的主要内容:

public class FragmentMainVpAdapter extends FragmentPagerAdapter {
public FragmentMainVpAdapter(FragmentManager fm) {
    super(fm);
}



    @Override
    public Fragment getItem(int position) {
        switch (position){
            case 0:
                return new FragmentFindInf();
            case 1:
                return new FragmentHintInf();
        }

        return null;
    }
    @Override
    public int getCount() {
        return 2;
    }
}      

其中:FragmentFindInf与FragmentHintInf是ViewPager左右滑动切换时的两个Fragment

五.ActionBar与ViewPager的动态效果(*******************************重要*********************************)

为了能实现在点击ActionBar导航栏时ViewPager切换到对应的Fragment上、滑动ViewPager时能选中对应的ActionBar项,需要以下两个关键步骤

由于是在fragment中对ActionBar进行初始化,则这个fragment需要实现ActionBar.TabListener接口:

并重写:

@Override
public void onTabSelected(ActionBar.Tab tab, android.support.v4.app.FragmentTransaction ft) {
    if (vp_main != null) {
        vp_main.setCurrentItem(tab.getPosition());//VP是VIEWPAGER,点击ActionBar导航栏ViewPager会滑动到对应fragment
    }
}

@Override
public void onTabUnselected(ActionBar.Tab tab, android.support.v4.app.FragmentTransaction ft) {

}

@Override
public void onTabReselected(ActionBar.Tab tab, android.support.v4.app.FragmentTransaction ft) {

}      

以及为ViewPager设置监听器:

vp_main.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    }

    @Override
    public void onPageSelected(int position) {
        if(ab_main != null) {
            ab_main.setSelectedNavigationItem(position);//滑动到不同fragment时,ActionBar上对应导航项目被选中
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }
});      

以上是今天的一些小结,查了挺多资料,受益匪浅,哈哈。