点击导航栏切换页面的几种方式
2017-03-22 19:20
183 查看
最近比较流行tablayout+viewpager+fragment的点击导航栏实现页面切换的效果,可以参考:http://blog.csdn.net/qq_33425116/article/details/52599818#t5
我在这里介绍的都是比较原始的切换做法。
示例RadioButton:
选项卡中示例FrameLayout
home布局文件:
完整布局请参考demo
示例fragment
fragment_home布局文件:
1.进入页面默认显示主页面高亮
2.用户点击按钮,点击的按钮高亮,未被点击的按钮失去高亮
NoScrollViewPager是一个被禁止滑动的viwpager
示例RedioGroup:
bottom_tab_style:
注意:
1.写完一个RedioButton后,不要选中内容,直接在RedioGroup内部右键--Refactor--Extract--Styles自动生成样式。
2.RedioButton中的drawableTop属性不能放大缩小图片,所以美工给的图片大小必须刚刚好,不然把图片弄合适很麻烦。
再创建四个子类pager
示例HomePager:
-给viewpager设置适配器PagerAdpter
-给RedioGroup里面设置点击RedioButton的监听事件,设置移动到哪个页面
-给viewpager设置滑动监听事件,里面初始化当前页面数据。
注意:
1.如果在PagerAdapter里面需要重写四个方法只会提示你重写两个方法,另外instantiateItem()和destroyItem()需要自己手动写。
2.因为viewpager会提前加载下一个布局,所以instantiateItem()里面只需要初始化根布局rootview,然后根据当前滑动到哪个页面才开始初始化哪个页面。否则会耗费流量。
点击下载示例project
我在这里介绍的都是比较原始的切换做法。
RedioGroup+Fragement(推荐)
运行效果:写布局文件:
示例RadioButton:
<RadioButton android:id="@+id/rb_home" style="@style/tab_style" android:checked="true" android:drawableTop="@drawable/bar_home_bg" android:text="主页" />样式文件tab_style:
<style name="tab_style"> <item name="android:layout_width">0dip</item> <item name="android:layout_height">wrap_content</item> <item name="android:layout_gravity">center_vertical</item> <item name="android:layout_weight">1</item> <item name="android:background">@android:color/transparent</item> <item name="android:button">@null</item> <item name="android:drawablePadding">-13dip</item> <item name="android:gravity">center</item> <item name="android:textSize">13sp</item> <item name="android:textColor">@drawable/bar_text_color</item> </style>
写对应fragment:
写切换逻辑:
public class MainActivity extends AppCompatActivity { @InjectView(R.id.fl_container) FrameLayout flContainer; @InjectView(R.id.rb_home) RadioButton rbHome; @InjectView(R.id.rb_classify) RadioButton rbClassify; @InjectView(R.id.rb_read) RadioButton rbRead; @InjectView(R.id.rb_cart) RadioButton rbCart; @InjectView(R.id.rb_user) RadioButton rbUser; @InjectView(R.id.rg_bottom) RadioGroup rgBottom; private FragmentManager mFragmentManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.inject(this); //兼容的fragment管理器 mFragmentManager = getSupportFragmentManager(); //默认让主页被选中 switchFragment(new HomeFragment()); //RedioGroup点击事件 rgBottom.setOnCheckedChangeListener(mOnCheckedChangeListener); } RadioGroup.OnCheckedChangeListener mOnCheckedChangeListener = new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup radioGroup, int checkedId) { switch (checkedId) { case R.id.rb_home://主页 switchFragment(new HomeFragment()); break; case R.id.rb_classify://分类 switchFragment(new ClassifyFragment()); break; case R.id.rb_read://阅读 switchFragment(new ReadFragment()); break; case R.id.rb_cart://购物车 switchFragment(new CartFragment()); break; case R.id.rb_user://我的 switchFragment(new UserFragment()); break; } } }; //切换Fragment的方法 public void switchFragment(Fragment fragment) { FragmentTransaction transaction = mFragmentManager.beginTransaction(); transaction.replace(R.id.fl_container, fragment); transaction.commit(); } }
底部线性布局+Fragment
运行效果:写布局文件
主布局UI选项卡中示例FrameLayout
<FrameLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1"> <ImageView android:layout_width="match_parent" android:layout_height="25dp" android:src="@drawable/home" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:gravity="bottom|center_horizontal" android:text="首页" android:textColor="@color/main_bottom_tv_color" android:textSize="14sp" /> </FrameLayout>
home布局文件:
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/home_normal" android:state_enabled="true"/> <item android:drawable="@drawable/home_disabled" android:state_enabled="false"/> </selector>
完整布局请参考demo
创建对应fragmnet
然后创建对应的四个fragment示例fragment
public class HomeFragment extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = View.inflate(getContext(), R.layout.fragment_home, null); return view; } }
fragment_home布局文件:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="首页" android:textSize="20sp" /> </FrameLayout>
完成切换逻辑
主要两点逻辑:1.进入页面默认显示主页面高亮
2.用户点击按钮,点击的按钮高亮,未被点击的按钮失去高亮
public class MainActivity extends AppCompatActivity { @InjectView(R.id.home_framents) FrameLayout homeFraments; @InjectView(R.id.home_tabs) LinearLayout homeTabs; private int currentTab; private Fragment[] mFragments; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.inject(this); currentTab = 0;//进入页面时,默认首页高亮 initFragments();//初始化fragment setTabSelected();//让指定选项卡高亮 initListener();//导航栏响应点击事件 } private void initListener() { int childCount = homeTabs.getChildCount(); for (int i = 0; i < childCount; i++) { FrameLayout child = (FrameLayout) homeTabs.getChildAt(i);//获取子元素 final int index = i; child.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { currentTab = index; setTabSelected();//修改导航按钮的选中状态 } }); } } public void setTabSelected() { int childCount = homeTabs.getChildCount(); for (int i = 0; i < childCount; i++) { FrameLayout child = (FrameLayout) homeTabs.getChildAt(i);//获取子元素 ImageView image = (ImageView) child.getChildAt(0);//图片 TextView text = (TextView) child.getChildAt(1);//文字 if (currentTab == i) { image.setEnabled(false); text.setEnabled(false); //切换Fragment FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.home_framents, mFragments[currentTab]); transaction.commit(); } else { image.setEnabled(true); text.setEnabled(true); } } } //初始化fragment private void initFragments() { mFragments = new Fragment[]{new HomeFragment(), new OrderFragment(), new UserFragment(), new MoreFragment()}; } }
RedioGroup+Viewpager
运行效果:写布局:
NoScrollViewPager是一个被禁止滑动的viwpager
public class NoScrollViewPager extends ViewPager { public NoScrollViewPager(Context context) { super(context); } public NoScrollViewPager(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onTouchEvent(MotionEvent ev) { //重写父类的onTouchEvent,此处什么都不做,从而达到禁用事件的目的 return true; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { //重写父类拦截事件,不让父viewpager拦截touch事件 return false; } }
示例RedioGroup:
<RadioButton android:id="@+id/rb_home" style="@style/bottom_tab_style" android:checked="true" android:drawableTop="@drawable/tab_home_selector" android:text="首页" />
bottom_tab_style:
<style name="bottom_tab_style"> <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> <item name="android:layout_weight">1</item> <item name="android:button">@null</item> <item name="android:gravity">center_horizontal</item> <item name="android:padding">5dp</item> <item name="android:textColor">#fff</item> </style>
注意:
1.写完一个RedioButton后,不要选中内容,直接在RedioGroup内部右键--Refactor--Extract--Styles自动生成样式。
2.RedioButton中的drawableTop属性不能放大缩小图片,所以美工给的图片大小必须刚刚好,不然把图片弄合适很麻烦。
创建对应的四个页面:
首先创建四个页面的基类BasePagerpublic class BasePager { MainActivity mActivity; public View rootView; public FrameLayout flContainer; public BasePager(MainActivity mActivity) { this.mActivity = mActivity; rootView = initView(); } public View initView() {//初始化根布局 View view = View.inflate(mActivity, R.layout.pager_base, null); //由子类动态填充的帧布局 flContainer = (FrameLayout) view.findViewById(R.id.fl_container); return view; } /**初始化数据,需要子类手动调用*/ public void initData() {} }
再创建四个子类pager
示例HomePager:
public class HomePager extends BasePager { private static final String TAG = "HomePager"; public HomePager(MainActivity mActivity) { super(mActivity); } @Override public void initData() { // super.initData(); Log.e(TAG, "调用了initData: "); //给空的帧布局动态添加布局对象 TextView tv = new TextView(mActivity); tv.setTextSize(30); tv.setTextColor(Color.RED); tv.setGravity(Gravity.CENTER); tv.setText("首页"); flContainer.addView(tv); } }
在MainAActivity中完成切换逻辑
-将四个pager加载到集合中-给viewpager设置适配器PagerAdpter
-给RedioGroup里面设置点击RedioButton的监听事件,设置移动到哪个页面
-给viewpager设置滑动监听事件,里面初始化当前页面数据。
注意:
1.如果在PagerAdapter里面需要重写四个方法只会提示你重写两个方法,另外instantiateItem()和destroyItem()需要自己手动写。
2.因为viewpager会提前加载下一个布局,所以instantiateItem()里面只需要初始化根布局rootview,然后根据当前滑动到哪个页面才开始初始化哪个页面。否则会耗费流量。
public class MainActivity extends AppCompatActivity { @InjectView(R.id.vp_main) NoScrollViewPager vpMain; @InjectView(R.id.rb_home) RadioButton rbHome; @InjectView(R.id.rb_order) RadioButton rbOrder; @InjectView(R.id.rb_user) RadioButton rbUser; @InjectView(R.id.rb_more) RadioButton rbMore; @InjectView(R.id.rg_tab) RadioGroup rgTab; private List<BasePager> pagers; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.inject(this); initPagers();//初始化viewpager中的几个页面 vpMain.setAdapter(new MyPagerAdapter()); //给RadioGroup设置一个点击radioButton的监听事件 rgTab.setOnCheckedChangeListener(mOnCheckedChangeListener); //手动初始化第一个页面的数据 pagers.get(0).initData(); //设置viewpager的滑动监听事件 vpMain.setOnPageChangeListener(mOnPageChangeListener); } ViewPager.OnPageChangeListener mOnPageChangeListener = new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {} @Override public void onPageSelected(int position) { BasePager pager = pagers.get(position); pager.initData(); } @Override public void onPageScrollStateChanged(int state) {} }; RadioGroup.OnCheckedChangeListener mOnCheckedChangeListener = new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId) { case R.id.rb_home: // vpMain.setCurrentItem(0); //将viewpager定位到哪一页 vpMain.setCurrentItem(0, false);//第二个参数:是否平滑的的移动 break; case R.id.rb_order: vpMain.setCurrentItem(1, false); break; case R.id.rb_user: vpMain.setCurrentItem(2, false); break; case R.id.rb_more: vpMain.setCurrentItem(3, false); break; } } }; private void initPagers() { pagers = new ArrayList<>(); pagers.add(new HomePager(this)); pagers.add(new OrderPager(this)); pagers.add(new UserPager(this)); pagers.add(new MorePager(this)); } class MyPagerAdapter extends PagerAdapter { @Override public int getCount() { return pagers.size(); } @Override public boolean isViewFromObject(View view, Object object) { return view == object;//固定写法 } @Override public Object instantiateItem(ViewGroup container, int position) { BasePager basePager = pagers.get(position);//获取当前页面的对象 container.addView(basePager.rootView);//将当前pager根布局加载进Viewpager容器中 return basePager.rootView;//返回当前pager的布局 } @Override public void destroyItem(ViewGroup container, int position, Object object) { // super.destroyItem(container, position, object);//如果不将这行注释掉可能会报错 container.removeView((View) object);//固定写法 } } }
点击下载示例project
相关文章推荐
- js实现页面滚动切换导航栏/点击导航栏跳转到指定位置
- jQuery Mobile页面跳转切换的几种方式
- IOS页面切换的几种方式
- 用js给div绑定事件,实现点击切换效果的几种方式总结
- Javascript(jQuery)中绑定页面上所有按钮点击事件的几种方式
- [ios]IOS页面切换的几种方式
- HTML页面中点击按钮关闭页面几种方式与取消
- jQuery Mobile页面跳转切换的几种方式
- Gridview中点击编辑实现页面跳转的几种方式总结
- js实现页面跳转的几种方式
- js实现页面跳转的几种方式
- js实现页面跳转的几种方式
- ASP.NET中页面传值的几种方式
- js实现页面跳转的几种方式
- js实现页面跳转的几种方式
- js实现页面跳转的几种方式
- 在ASP.NET中页面传值的几种方式(转)
- 页面跳转的几种方式
- ASP.NET两个页面之间传递值的几种方式
- jsp页面中几种标签的引用方式