主界面: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 实现左右滑动的效果的更多相关文章

  1. Android开发之ViewPager+ActionBar+Fragment实现响应式可滑动Tab

     今天我们要实现的这个效果呢,在Android的应用中十分地常见,我们可以看到下面两张图,无论是系统内置的联系人应用,还是AnyView的阅读器应用,我们总能找到这样的影子,当我们滑动屏幕时,Tab可 ...

  2. ViewPager结合Fragment进行无限滑动

    实现ViewPager结合Fragment实现无限循环切换,这里也是在适配器里面进行的,当然使用滑动监听也能够实现 import android.support.v4.app.Fragment; im ...

  3. Android开发之ViewPager实现多页面切换及动画效果(仿Android的Launcher效果)

    Android开发中经常会有引导页或者切换页面等效果,本文采用ViewPager结合动画效果来实现仿Launcher以及页面切换的效果.源码地址在文章最后给出下载. 效果图如下:       1.Vi ...

  4. Android Tab -- 使用ViewPager、Fragment、FragmentPagerAdapter来实现

    原文地址:http://blog.csdn.net/crazy1235/article/details/42678877 效果:滑动切换:点击标签切换. 代码:https://github.com/l ...

  5. 使用BottomNavigationView+ViewPager+Fragment的底部导航栏

    2019独角兽企业重金招聘Python工程师标准>>> 使用BottomNavigationView做底部工具栏,使用ViewPager做页面切换,使用Fragment完成每个页面的 ...

  6. 【Android 界面效果27】利用ViewPager、Fragment、PagerTabStrip实现多页面滑动效果

    本文主要介绍如何利用ViewPager.Fragment.PagerTabStrip实现多页面滑动效果.即google play首页.新浪微博消息(at.评论.私信.广播)页面的效果.ViewPage ...

  7. Android Tab类型主界面 Fragment+TabPageIndicator+ViewPager

    文章地址: Android项目Tab类型主界面大总结 Fragment+TabPageIndicator+ViewPager 1.使用ViewPager + PagerAdapter 每个页面的内容都 ...

  8. Android 利用ViewPager、Fragment、PagerTabStrip实现多页面滑动效果

    本文主要介绍如何利用ViewPager.Fragment.PagerTabStrip实现多页面滑动效果.即google play首页.新浪微博消息(at.评论.私信.广播)页面的效果.ViewPage ...

  9. Android -- ViewPager、Fragment、状态保存、通信

    工程架构                                                                                      TabAFm到Tab ...

随机推荐

  1. Oracle恢复流程图

    本图来自于网络,想当初小麦苗刚开始接触备份恢复的时候,就是靠着这张图来学习的,今天把这张图分享给大家,共勉. ............................................. ...

  2. 第9章 运行TensorFlow

    目录 第9章 运行TensorFlow 创建一个计算图并在会话中执行 管理图 节点值的生命周期 TensorFlow中的线性回归 实现梯度下降 给训练算法提供数据 保存和恢复模型 用TensorBoa ...

  3. golang方法和接口

    一.  go方法 go方法:在函数的func和函数名间增加一个特殊的接收器类型,接收器可以是结构体类型或非结构体类型.接收器可以在方法内部访问.创建一个接收器类型为Type的methodName方法. ...

  4. 分布式存储-ceph

    1. ceph 简介 Ceph是一种为优秀的性能.可靠性和可扩展性而设计的统一的.分布式文件系统().ceph 的统一体现在可以提供文件系统.块存储和对象存储,分布式体现在可以动态扩展.在国内一些公司 ...

  5. 将mysql从MyISAM更改为INNODB

    今天更新django中的表字段,由于mysql从5.1升级到5.7.以前的外键关联必须从MYISAM改新为INNODB才可以继续. 过程有点刺激,但还好,只要想清楚了过程,提前作好备份,就没啥大问题. ...

  6. ThinkPHP模型中的HAS_ONE,BELONG_TO,HAS_MANY实践

    因为很熟悉DJANGO,所以对TP,要慢慢适应. 1,SQL文件 /* Navicat MySQL Data Transfer Source Server : localhost_3306 Sourc ...

  7. SQLAlchemy多对多

    创建多对多表 from sqlalchemy.ext.declarative import declarative_base Base=declarative_base() from sqlalche ...

  8. tensorflow API _ 3 (tf.train.polynomial_decay)

    学习率的三种调整方式:固定的,指数的,多项式的 def _configure_learning_rate(num_samples_per_epoch, global_step): "&quo ...

  9. CDN工作机制

    CDN(content delivery network),即内容分布网络,是一种构建在现有Internet上的一种先进的流量分配网络.CDN以缓存网站中的静态数据为主,当用户请求动态内容时,先从CD ...

  10. VisualStudio 2019 Serials

    9DP6T-9AGWG-KWV33-9MPC8-JDCVF 7G2HE-JR8KL-ABB9D-Y7789-GLNFL U2PWU-H7D9H-69T3B-JEYC2-3R2NG R8R8P-MTT6 ...