android: 结合BottomNavigationView、ViewPager和Fragment 实现左右滑动的效果
主界面:MainActivity
- package com.yongdaimi.android.androidapitest;
- import android.os.Bundle;
- import androidx.appcompat.app.AppCompatActivity;
- import com.yongdaimi.android.androidapitest.fragment.HomePageFragment;
- public class MainActivity extends AppCompatActivity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- initFragment();
- }
- private void initFragment() {
- HomePageFragment homePageFragment = HomePageFragment.newInstance();
- getSupportFragmentManager()
- .beginTransaction()
- .add(R.id.fl_main_container, homePageFragment, homePageFragment.getClass().getSimpleName())
- .commit();
- }
- }
主界面布局:activity_main.xml
- <?xml version="1.0" encoding="utf-8"?>
- <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:id="@+id/fl_main_container"
- />
主界面入口的Fragment: HomePageFragment.java
- package com.yongdaimi.android.androidapitest.fragment;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.LayoutInflater;
- import android.view.MenuItem;
- import android.view.View;
- import android.view.ViewGroup;
- import androidx.annotation.NonNull;
- import androidx.annotation.Nullable;
- import androidx.fragment.app.Fragment;
- import androidx.viewpager.widget.PagerAdapter;
- import androidx.viewpager.widget.ViewPager;
- import com.google.android.material.bottomnavigation.BottomNavigationView;
- import com.google.android.material.bottomnavigation.LabelVisibilityMode;
- import com.yongdaimi.android.androidapitest.R;
- import java.util.ArrayList;
- import java.util.List;
- /**
- * A simple {@link Fragment} subclass.
- * Activities that contain this fragment must implement the
- * HomePageFragment.OnFragmentInteractionListener interface
- * to handle interaction events.
- * Use the {@link HomePageFragment#newInstance} factory method to
- * create an instance of this fragment.
- */
- public class HomePageFragment extends Fragment {
- public static final String TAG = "xp.chen";
- private View mContentView;
- private ViewPager vp_pager;
- private BottomNavigationView nv_bottom_menu;
- private List<BaseViewController> mPageList;
- public static HomePageFragment newInstance() {
- return new HomePageFragment();
- }
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- // Inflate the layout for this fragment
- mContentView = inflater.inflate(R.layout.fragment_home_page, container, false);
- return mContentView;
- }
- @Override
- public void onActivityCreated(@Nullable Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- initView();
- initPages();
- setListener();
- }
- private void initPages() {
- mPageList = new ArrayList<>();
- HomeViewController homeViewController = new HomeViewController(getActivity());
- mPageList.add(homeViewController);
- ContactViewController contactViewController = new ContactViewController(getActivity());
- mPageList.add(contactViewController);
- SearchViewController searchViewController = new SearchViewController(getActivity());
- mPageList.add(searchViewController);
- SettingsViewController settingsViewController = new SettingsViewController(getActivity());
- mPageList.add(settingsViewController);
- vp_pager.setAdapter(mPagerAdapter);
- }
- private void initView() {
- vp_pager = mContentView.findViewById(R.id.vp_pager);
- nv_bottom_menu = mContentView.findViewById(R.id.nv_bottom_menu);
- nv_bottom_menu.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);
- nv_bottom_menu.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
- }
- private void setListener() {
- vp_pager.addOnPageChangeListener(mOnPageChangeListener);
- }
- private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() {
- @Override
- public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
- vp_pager.setCurrentItem(menuItem.getOrder());
- return true;
- }
- };
- private PagerAdapter mPagerAdapter = new PagerAdapter() {
- @Override
- public int getCount() {
- return mPageList.size();
- }
- @Override
- public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
- return view == object;
- }
- @NonNull
- @Override
- public Object instantiateItem(@NonNull ViewGroup container, int position) {
- BaseViewController baseViewController = mPageList.get(position);
- ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
- container.addView(baseViewController, layoutParams);
- return baseViewController;
- }
- @Override
- public void destroyItem(ViewGroup container, int position, Object object) {
- container.removeView((View) object);
- }
- @Override
- public int getItemPosition(Object object) {
- return super.getItemPosition(object);
- }
- @Override
- public void notifyDataSetChanged() {
- super.notifyDataSetChanged();
- }
- };
- private ViewPager.OnPageChangeListener mOnPageChangeListener = new ViewPager.OnPageChangeListener() {
- @Override
- public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
- }
- @Override
- public void onPageSelected(int position) {
- Log.i(TAG, "onPageSelected: " + position);
- nv_bottom_menu.getMenu().getItem(position).setChecked(true);
- }
- @Override
- public void onPageScrollStateChanged(int state) {
- }
- };
- }
主界面入口Fragment的布局:fragment_home_page.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- >
- <androidx.viewpager.widget.ViewPager
- android:id="@+id/vp_pager"
- android:layout_width="match_parent"
- android:layout_height="0dip"
- android:layout_weight="1"
- />
- <com.google.android.material.bottomnavigation.BottomNavigationView
- android:id="@+id/nv_bottom_menu"
- android:layout_width="match_parent"
- android:layout_height="50dip"
- android:layout_gravity="bottom"
- android:background="?android:attr/windowBackground"
- app:menu="@menu/menu_navigation"
- app:elevation="4dip"
- />
- </LinearLayout>
BottomNavigationView的menu文件:menu_navigation.xml
- <?xml version="1.0" encoding="utf-8"?>
- <menu xmlns:android="http://schemas.android.com/apk/res/android">
- <item
- android:id="@+id/item_tab1"
- android:icon="@drawable/ic_menu_home"
- android:title="Home"
- android:checked="true"
- android:orderInCategory="0"
- />
- <item
- android:id="@+id/item_tab2"
- android:icon="@drawable/ic_menu_contact"
- android:title="Contact"
- android:orderInCategory="1"
- />
- <item
- android:id="@+id/item_tab3"
- android:icon="@drawable/ic_menu_search"
- android:title="Search"
- android:orderInCategory="2"
- />
- <item
- android:id="@+id/item_tab4"
- android:icon="@drawable/ic_menu_settings"
- android:title="Settings"
- android:orderInCategory="3"
- />
- </menu>
这里有几个地方需要特别说明一下:
1. HomePageFragment.java 文件中的 nv_bottom_menu.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED); 用来设置BottomNavigationView在切换时的状态,如果不设置,在点击BottomNavigationView上的item在切换时文字可能会发生隐藏。
2. 上面menu文件中的 orderInCategory 属性用于设置菜单项的排列顺序,必须设置为大于或者等于0的整数值。数值小的排列在前,如果值相等,则按照XML中的顺序展现。 title 属性用于指定navigation Item的标题, icon 属性用于指定navigation item的图标。
3. fragment_home_page文件中的 app:elevation="4dip" 属性用于设置BottomNavigationView菜单顶部的模糊程度,如果不设置的话,BottomNavigationView的菜单顶部会很模糊。
最后是几个用于切换的Layout:
- package com.yongdaimi.android.androidapitest.fragment;
- import android.content.Context;
- import android.widget.FrameLayout;
- import androidx.annotation.NonNull;
- public abstract class BaseViewController extends FrameLayout {
- public BaseViewController(@NonNull Context context) {
- super(context);
- }
- }
BaseViewController.java
- package com.yongdaimi.android.androidapitest.fragment;
- import android.content.Context;
- import android.view.LayoutInflater;
- import androidx.annotation.NonNull;
- import com.yongdaimi.android.androidapitest.R;
- public class HomeViewController extends BaseViewController {
- public HomeViewController(@NonNull Context context) {
- super(context);
- LayoutInflater.from(context).inflate(R.layout.layout_home, this);
- }
- }
HomeViewController.java
- package com.yongdaimi.android.androidapitest.fragment;
- import android.content.Context;
- import android.view.LayoutInflater;
- import androidx.annotation.NonNull;
- import com.yongdaimi.android.androidapitest.R;
- public class ContactViewController extends BaseViewController {
- public ContactViewController(@NonNull Context context) {
- super(context);
- LayoutInflater.from(context).inflate(R.layout.layout_contact, this);
- }
- }
ContactViewController.java
- package com.yongdaimi.android.androidapitest.fragment;
- import android.content.Context;
- import android.view.LayoutInflater;
- import androidx.annotation.NonNull;
- import com.yongdaimi.android.androidapitest.R;
- public class SearchViewController extends BaseViewController {
- public SearchViewController(@NonNull Context context) {
- super(context);
- LayoutInflater.from(context).inflate(R.layout.layout_search, this);
- }
- }
SearchViewController.java
- package com.yongdaimi.android.androidapitest.fragment;
- import android.content.Context;
- import android.view.LayoutInflater;
- import androidx.annotation.NonNull;
- import com.yongdaimi.android.androidapitest.R;
- public class SettingsViewController extends BaseViewController {
- public SettingsViewController(@NonNull Context context) {
- super(context);
- LayoutInflater.from(context).inflate(R.layout.layout_settings, this);
- }
- }
SettingsViewController.java
基本上都是一样的,它们的布局文件也很简单,就是一个布局里加一个TextView。
最终效果:
我这里的PageAdapter中并没有直接使用Fragment, 因为ViewPager在加载Fragment时,会同时初始化几个Fragment,这在实际开发中很不友好,目前正在想办法解决,这也是我什么只使用一个Fragment多个Layout的主要原因。如果希望ViewPager中添加的也是Fragment,可参考:
Android布局实现-BottomNavigationView+ViewPager+Fragment+整合
android: 结合BottomNavigationView、ViewPager和Fragment 实现左右滑动的效果的更多相关文章
- Android开发之ViewPager+ActionBar+Fragment实现响应式可滑动Tab
今天我们要实现的这个效果呢,在Android的应用中十分地常见,我们可以看到下面两张图,无论是系统内置的联系人应用,还是AnyView的阅读器应用,我们总能找到这样的影子,当我们滑动屏幕时,Tab可 ...
- ViewPager结合Fragment进行无限滑动
实现ViewPager结合Fragment实现无限循环切换,这里也是在适配器里面进行的,当然使用滑动监听也能够实现 import android.support.v4.app.Fragment; im ...
- Android开发之ViewPager实现多页面切换及动画效果(仿Android的Launcher效果)
Android开发中经常会有引导页或者切换页面等效果,本文采用ViewPager结合动画效果来实现仿Launcher以及页面切换的效果.源码地址在文章最后给出下载. 效果图如下: 1.Vi ...
- Android Tab -- 使用ViewPager、Fragment、FragmentPagerAdapter来实现
原文地址:http://blog.csdn.net/crazy1235/article/details/42678877 效果:滑动切换:点击标签切换. 代码:https://github.com/l ...
- 使用BottomNavigationView+ViewPager+Fragment的底部导航栏
2019独角兽企业重金招聘Python工程师标准>>> 使用BottomNavigationView做底部工具栏,使用ViewPager做页面切换,使用Fragment完成每个页面的 ...
- 【Android 界面效果27】利用ViewPager、Fragment、PagerTabStrip实现多页面滑动效果
本文主要介绍如何利用ViewPager.Fragment.PagerTabStrip实现多页面滑动效果.即google play首页.新浪微博消息(at.评论.私信.广播)页面的效果.ViewPage ...
- Android Tab类型主界面 Fragment+TabPageIndicator+ViewPager
文章地址: Android项目Tab类型主界面大总结 Fragment+TabPageIndicator+ViewPager 1.使用ViewPager + PagerAdapter 每个页面的内容都 ...
- Android 利用ViewPager、Fragment、PagerTabStrip实现多页面滑动效果
本文主要介绍如何利用ViewPager.Fragment.PagerTabStrip实现多页面滑动效果.即google play首页.新浪微博消息(at.评论.私信.广播)页面的效果.ViewPage ...
- Android -- ViewPager、Fragment、状态保存、通信
工程架构 TabAFm到Tab ...
随机推荐
- Maven项目命名规范
Guide to naming conventions on groupId, artifactId and versiongroupId will identify your project uni ...
- MySQL Percona Toolkit--pt-osc执行SQL命令
pt-osc执行日志 在对数据量为100000的表tb004做DROP COLUMN操作,pt-osc工具日志为: Operation, tries, wait: analyze_table, , c ...
- 04-JavaScript的操作
本篇主要介绍获取元素的方法.操作元素.数组和字符串的操作方法.定时器和封闭函数.以及贪吃蛇案例: 一.获取元素的方法 1.document.getElementById:可以使用内置对象documen ...
- [LIN].LIN总线详解
转自:https://www.2cto.com/kf/201806/754227.html 参考:https://wenku.baidu.com/view/a9b08d786bd97f192379e9 ...
- C#模拟鼠标、键盘操作
C语言 在程序中打开网页,模拟鼠标点击.键盘输入 一.简述 记--使用C语言 打开指定网页,并模拟鼠标点击.键盘输入.实现半自动填写账号密码,并登录网站(当然现在的大部分网站都有验证码 ...
- ARTS-week7
Algorithm 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. Two Sum 编写一个 SQL 查询,满足条件:无论 ...
- CodeForces - 76A:Gift (最小生成树 解决单调性问题是思想)
题意:给定N点M边的无向连通图,每条边有两个权值(g,s). 给定G,S. 让你给出一组(g0,s0)使得图中仅留下g<=g0, s<=s0的边之后,依然连通,并求Gg0+Ss0的最小值. ...
- git version info & svn version info map(七)
To generate the same version number as SVN, we can generate the same version number as SVN with the ...
- vigil rpm 包制作
vigil 可以方便的进行服务的监控,以下尝试制作一个rpm 包,方便使用 安装依赖 ruby yum -y install ruby rubygems ruby-devel 修改gem 源 可选, ...
- snmp-get
使用mibbroser可以连接到监控主机,可以获取主机mib信息 使用walk出的oid就可以获取到对应的值, 使用 -O fn 可以将返回的字符创形式的键改为数字型oid oid还有一种字符串的形式 ...