ViewPager+RadioGroup+Fragment仿微信实现底部导航功能

                      ViewPager+RadioGroup+Fragment仿微信实现底部导航功能

                  今天做一个简单的仿微信底部导航功能,先简单说明一下组件,主体是一个FrameLayout,在这个帧布局上添加两个控件,ViewPager 和RadioGroup, 然后在ViePager中添加Fragment,实现导航功能.
           

         先上布局代码:
             
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/ll_contnet"
    android:orientation="vertical" >

    
    <android.support.v4.view.ViewPager
        android:id="@+id/vp"
        android:layout_width="match_parent"
        android:layout_weight="1"
        android:layout_height="0dp">
    </android.support.v4.view.ViewPager>
    
    
    
    <RadioGroup
        android:id="@+id/radio_group"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:orientation="horizontal"
         >

        <RadioButton
            android:id="@+id/rb1"
            style="@style/TabButtonStyle"
            android:checked="true"
            android:drawableTop="@drawable/ic_launcher"
            android:text="首页" />

        <RadioButton
            android:id="@+id/rb2"
            style="@style/TabButtonStyle"
            android:checked="true"
            android:drawableTop="@drawable/ic_launcher"
            android:text="首页" />

        <RadioButton
            android:id="@+id/rb3"
            style="@style/TabButtonStyle"
            android:checked="true"
            android:drawableTop="@drawable/ic_launcher"
            android:text="首页" />

        <RadioButton
            android:id="@+id/rb4"
            style="@style/TabButtonStyle"
            android:checked="true"
            android:drawableTop="@drawable/ic_launcher"
            android:text="首页" />

        <RadioButton
            android:id="@+id/rb5"
            style="@style/TabButtonStyle"
            android:checked="true"
            android:drawableTop="@drawable/ic_launcher"
            android:text="首页" />
    </RadioGroup>

</LinearLayout>

 上边是一个线性布局,把这个线性布局作为View添加到FrameLayout中

   下边是具体实现逻辑:

   
public class MainActivity extends FragmentActivity {

	private static final String TAG_CONTENT_FRAGMENT = "fl_content";
	private FrameLayout fl_content;

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

	private void initView() {
		fl_content = (FrameLayout) findViewById(R.id.fl_content);
	}

	private void setcontentFragment() {
		//1.获取fragment管理者对象
		FragmentManager supportFragmentManager = getSupportFragmentManager();
		//2.开启一个事务,替换布局内部的内容,然后提交
		supportFragmentManager.beginTransaction().replace(
				R.id.fl_content, 
				new ContentFragment(), 
				TAG_CONTENT_FRAGMENT).commit();
		
	}
}

   首先MainAvtivity继承的是V4包提供的 FragmentActivity 用来解决android3.0没有Fragment的API
其次获取Fragment管理者,开启事务,替换布局内容,最后提交。

下边来看填充替换的内容:

    
   首先我们来写一个基类BaseFragment继承Fragment:
  
    
public abstract class BaseFragment extends Fragment {

	
	protected Activity activity;
	private View rootview;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		activity = getActivity();
		super.onCreate(savedInstanceState);
	}
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		rootview = initView();
		//如果要让子类的页面效果展示,必须在此处返回view对象
		return rootview;
	}
	
	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		initData();
		super.onActivityCreated(savedInstanceState);
	}
	
	//初始化view的方法,因为fragment父类对子类的布局效果未知,所以此方法无法实现,于是抽象
		public abstract View initView();
		//给view填充数据方法,因为子类的fragment有什么控件未知,子类的fragment有什么数据也位置,所以此方法无法实现(定义抽象,空实现)
		public void initData() {
			//此方法专门留给子类重新
		}
}

  首先BaseFragment 继承V4包下的Fragment,重写了onCreate(),onCreateView(),onActivityCreated()三个方法,

 oncreat()方法在Fragment中和Activity中的oncreta()一样,
 oncreatview()在这个view创建之时调用,返回值是一个view,我们可以在这个方法内返回一个view对象,//initView() onActivitycreat()是在view添加到activity上时调用,我们可以在这个方法内做一些填充数据的操作              //initData

   然后定义两个抽象方法,initView(),initData(),让其子类来实现这两个方法,
       initView返回View填充到Fragment上
       initData 设置数据
 
     

    下边是填充FrameLayout的Fragment:

 
public class ContentFragment extends BaseFragment {

	private View view;
	private RadioGroup radio_group;
	private ViewPager vp;
	private ArrayList<BasePager> list;

	@Override
	public View initView() {
		view = View.inflate(activity, R.layout.frame_content, null);
		radio_group = (RadioGroup) view.findViewById(R.id.radio_group);
		vp = (ViewPager) view.findViewById(R.id.vp);
		return view;
	}

	@SuppressWarnings("deprecation")
	@Override
	public void initData() {

		list = new ArrayList<BasePager>();
		list.add(new FirstFragment(activity));
		list.add(new SecondFragment(activity));
		list.add(new ThirdFragment(activity));
		list.add(new fourthlyFragment(activity));
		list.add(new fifithFragment(activity));
       
		radio_group.setOnCheckedChangeListener(new OnCheckedChangeListener() {

			@Override
			public void onCheckedChanged(RadioGroup group, int checkedId) {
				switch (checkedId) {
				case R.id.rb1:
					vp.setCurrentItem(0);
					break;
				case R.id.rb2:
					vp.setCurrentItem(1);
					break;
				case R.id.rb3:
					vp.setCurrentItem(2);
					break;
				case R.id.rb4:
					vp.setCurrentItem(3);
					break;
				case R.id.rb5: 
					vp.setCurrentItem(4);
					break;
				}
			}
		});

		vp.setAdapter(new PagerAdapter() {

			@Override
			public boolean isViewFromObject(View arg0, Object arg1) {
				return arg0 == arg1;
			}
			@Override
			public int getCount() {
				return list.size();
			}
			@Override
			public Object instantiateItem(ViewGroup container, int position) {
				/*
				 * 郜哥,这个地方下边写的假数据,只是作为一个demo
				 * 
				 * 这个地方可以通过存储fragment的集合,取出fragment,返回fragment中的view对象,
				 * 但是呢,想点击一个radio_button,返回一个相对应的view,就得写一个list集合中五个fragment的父类
				 * 在父类中也定义一个initview()方法,返回每个继承这个父类的fragment的view对象,然后在这里如下写:
				 * 
				 * container.addView(list.get(position).rootView);
				 * rootview就是父类中的在initview()中返回的view
				 * 
				 * 
				 * 上边的list集合里面的数据都没用到
				 */
				container.addView(list.get(position).rootview);
				return list.get(position).rootview;
			}

			@Override
			public void destroyItem(ViewGroup container, int position,
					Object object) {
				container.removeView((View) object);
			}
		});
		vp.setCurrentItem(0);
		radio_group.check(R.id.rb1);
		vp.setOnPageChangeListener(new OnPageChangeListener() {

			@Override
			public void onPageSelected(int position) {
				// 当当前的viewpager状态改变的时候的时候,radiogroup也切换
				int currentItem = vp.getCurrentItem();
				System.out.println("currentItem==="+currentItem);
				switch (currentItem) {
				case 0:
                   radio_group.check(R.id.rb1);
					break;
				case 1:
					 radio_group.check(R.id.rb2);
					break;
				case 2:
					 radio_group.check(R.id.rb3);
					break;
				case 3:
					 radio_group.check(R.id.rb4);
					break;
				case 4:
					 radio_group.check(R.id.rb5);
					break;
				}
			}

			@Override
			public void onPageScrolled(int arg0, float arg1, int arg2) {

			}

			@Override
			public void onPageScrollStateChanged(int arg0) {

			}
		});
	}
}

     
   首先我们继承先前写好的BaseFragment,实现initView().initData()

   initView里找到我们写的布局,并返回view;

   initData()下设置viewpager适配器,radiogroup的点击监听,viewpager的页面改变监听

   
   这里面有两个地方需要注意:
       1, 点击radiobutton 切换viewpager的页面,同时改变选中的radiobutton的文本颜色
                               调用viewpager的setCurrentItem(int);可以设置viewpager当前的页面

        2,另一个是 ,滑动viewpager时,radiobutton的切换
                 在viewpager的滑动监听中 调用getCurrentItem()获取当前页面,
                用switch语句,移动到哪个页面,就调用radiogroup的check(int),设置radiobutton的选择状态,同时选中的                 radiobutton的文本会变色
  
     
      代码实现很简单,其他类就不贴出来了。有什么其他不懂的地方可以看Demo.
    Demo


   


   
         

 



  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ViewPager和Fragment可以很好地实现底部导航功能。下面是一些实现方法: 1. 创建一个包含ViewPager和底部导航的布局文件,底部导航可以使用TabLayout或者自定义的布局。 2. 创建Fragment类,每个Fragment表示一个底部导航项对应的页面内容。 3. 创建PagerAdapter类,继承自FragmentPagerAdapter或者FragmentStatePagerAdapter,用于管理ViewPager中的Fragment。 4. 在Activity中找到ViewPager和TabLayout(或者自定义的底部导航),设置PagerAdapter和TabLayout的关联。 5. 实现TabLayout的OnTabSelectedListener接口,在回调方法中切换ViewPager的当前页面。 6. 在Fragment中添加需要展示的布局和逻辑代码。 下面是一个示例代码: MainActivity.java ``` public class MainActivity extends AppCompatActivity implements TabLayout.OnTabSelectedListener { private ViewPager viewPager; private TabLayout tabLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); viewPager = findViewById(R.id.viewPager); tabLayout = findViewById(R.id.tabLayout); PagerAdapter adapter = new PagerAdapter(getSupportFragmentManager()); viewPager.setAdapter(adapter); tabLayout.setupWithViewPager(viewPager); tabLayout.addOnTabSelectedListener(this); } @Override public void onTabSelected(TabLayout.Tab tab) { viewPager.setCurrentItem(tab.getPosition()); } @Override public void onTabUnselected(TabLayout.Tab tab) { } @Override public void onTabReselected(TabLayout.Tab tab) { } private static class PagerAdapter extends FragmentPagerAdapter { private static final int NUM_PAGES = 3; public PagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { switch (position) { case 0: return new HomeFragment(); case 1: return new NewsFragment(); case 2: return new SettingsFragment(); default: return null; } } @Override public int getCount() { return NUM_PAGES; } @Override public CharSequence getPageTitle(int position) { switch (position) { case 0: return "Home"; case 1: return "News"; case 2: return "Settings"; default: return null; } } } } ``` activity_main.xml ``` <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent"/> <android.support.design.widget.TabLayout android:id="@+id/tabLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:background="@android:color/white"/> </RelativeLayout> ``` HomeFragment.java ``` public class HomeFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_home, container, false); // 添加布局和逻辑代码 return view; } } ``` NewsFragment.java ``` public class NewsFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_news, container, false); // 添加布局和逻辑代码 return view; } } ``` SettingsFragment.java ``` public class SettingsFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_settings, container, false); // 添加布局和逻辑代码 return view; } } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值