In this tutorial we’ll be implementing a ViewPager under the TabLayout that we’d already implemented in this tutorial.

在本教程中,我们将在我们已经在本教程中实现的TabLayout下实现ViewPager。

Android TabLayout ViewPager概述 (Android TabLayout ViewPager Overview)

ViewPagers are used to swipe through pages of data. It’s generally used in conjunction with fragments.
Let’s modify our layout from the previous tutorial as below.

ViewPagers用于在数据页面之间滑动。 它通常与片段结合使用。
让我们从上一教程中修改我们的布局,如下所示。

activity_main.xml

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="https://schemas.android.com/apk/res/android"xmlns:app="https://schemas.android.com/apk/res-auto"xmlns:tools="https://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:fitsSystemWindows="true"tools:context="com.journaldev.tablayoutviewpager.MainActivity"><android.support.design.widget.AppBarLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:theme="@style/AppTheme.AppBarOverlay"><android.support.v7.widget.Toolbarandroid:id="@+id/toolbar"android:layout_width="match_parent"android:layout_height="?attr/actionBarSize"android:background="?attr/colorPrimary"app:layout_scrollFlags="scroll|enterAlways"app:popupTheme="@style/AppTheme.PopupOverlay" /><android.support.design.widget.TabLayoutandroid:id="@+id/tabs"style="@style/MyStyle"android:layout_width="match_parent"android:layout_height="wrap_content"app:tabGravity="fill"app:tabMode="fixed" /></android.support.design.widget.AppBarLayout><android.support.v4.view.ViewPagerandroid:id="@+id/viewPager"android:layout_width="match_parent"android:layout_height="wrap_content"app:layout_behavior="@string/appbar_scrolling_view_behavior" /><android.support.design.widget.FloatingActionButtonandroid:id="@+id/fab"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="bottom|end"android:layout_margin="@dimen/fab_margin"android:src="@android:drawable/ic_dialog_email" /></android.support.design.widget.CoordinatorLayout>

Before we add up our ViewPager in the MainActivity, let’s set up it’s adapter.

在MainActivity中添加ViewPager之前,让我们设置它的适配器。

public class ViewPagerAdapter extends FragmentPagerAdapter {public ViewPagerAdapter(FragmentManager fm) {super(fm);}@Overridepublic Fragment getItem(int position) {Fragment fragment = null;if (position == 0){fragment = new FragmentA();}else if (position == 1){fragment = new FragmentB();}else if (position == 2){fragment = new FragmentC();}return fragment;}@Overridepublic int getCount() {return 3;}@Overridepublic CharSequence getPageTitle(int position) {String title = null;if (position == 0){title = "Tab-1";}else if (position == 1){title = "Tab-2";}else if (position == 2){title = "Tab-3";}return title;}
}

The above ViewPagerAdapter extends the FragmentPagerAdapter. It invokes three Fragments, one for each of its pages. Each of the fragments holds a ListView as shown below

上面的ViewPagerAdapter扩展了FragmentPagerAdapter 。 它调用三个片段,每个页面一个。 每个片段都具有一个ListView,如下所示

fragment_list.xml

fragment_list.xml

<?xml version="1.0" encoding="utf-8"?><ListView xmlns:android="https://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/list"/>

The FragmentA(/B/C).java is given below:

FragmentA(/ B / C).java如下所示:

public class FragmentA extends Fragment {ListView list;public FragmentA() {}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {View view = inflater.inflate(R.layout.fragment, container, false);list = (ListView) view.findViewById(R.id.list);ArrayList stringList= new ArrayList();stringList.add("Item 1A");stringList.add("Item 1B");stringList.add("Item 1C");stringList.add("Item 1D");stringList.add("Item 1E");stringList.add("Item 1F");stringList.add("Item 1G");stringList.add("Item 1H");stringList.add("Item 1I");stringList.add("Item 1J");stringList.add("Item 1K");stringList.add("Item 1L");stringList.add("Item 1M");stringList.add("Item 1N");stringList.add("Item 1O");stringList.add("Item 1P");stringList.add("Item 1Q");stringList.add("Item 1R");stringList.add("Item 1S");stringList.add("Item 1T");stringList.add("Item 1U");stringList.add("Item 1V");stringList.add("Item 1W");stringList.add("Item 1X");stringList.add("Item 1Y");stringList.add("Item 1Z");CustomAdapter adapter = new CustomAdapter(stringList,getActivity());list.setAdapter(adapter);return view;}
}

The CustomAdapter.java class for the above ListView is:

上述ListView的CustomAdapter.java类为:

public class CustomAdapter extends ArrayAdapter {private ArrayList dataSet;Context mContext;// View lookup cacheprivate static class ViewHolder {TextView txtName;}public CustomAdapter(ArrayList data, Context context) {super(context, R.layout.row_item, data);this.dataSet = data;this.mContext = context;}@Nullable@Overridepublic String getItem(int position) {return dataSet.get(position);}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder viewHolder; // view lookup cache stored in tagif (convertView == null) {viewHolder = new ViewHolder();LayoutInflater inflater = LayoutInflater.from(getContext());convertView = inflater.inflate(R.layout.row_item, parent, false);viewHolder.txtName = (TextView) convertView.findViewById(R.id.name);convertView.setTag(viewHolder);} else {viewHolder = (ViewHolder) convertView.getTag();}viewHolder.txtName.setText(getItem(position));// Return the completed view to render on screenreturn convertView;}
}

The MainActivity.java class is given below

MainActivity.java类如下所示

public class MainActivity extends AppCompatActivity {TabLayout tabLayout;ViewPager viewPager;ViewPagerAdapter viewPagerAdapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);setSupportActionBar(toolbar);FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);fab.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG).setAction("Action", null).show();}});viewPager = (ViewPager) findViewById(R.id.viewPager);viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());viewPager.setAdapter(viewPagerAdapter);tabLayout = (TabLayout) findViewById(R.id.tabs);tabLayout.setupWithViewPager(viewPager);}}

In the above code setupWithViewPager() is used to join the TabLayout with the ViewPager.
The getPageTitle() method in the FragmentPagerAdapter is used to set the title of each of the Tabs. Let’s look at output when the above code is run

在上面的代码中, setupWithViewPager()用于将TabLayout与ViewPager结合在一起。
FragmentPagerAdapter中的getPageTitle()方法用于设置每个选项卡的标题。 让我们看一下上面代码运行时的输出

Question : Why isn’t the ToolBar scrolling as per the scrollFlags set?

问题 :为什么ToolBar不能按scrollFlags设置滚动?

It’s due to the ListView. The CoordinatorLayout doesn’t support the ListView(it’s not a part of Material Design) and it’s scrolling gestures. Hence it’s recommended to use RecyclerView instead.

这是由于ListView 。 CoordinatorLayout不支持ListView(它不是Material Design的一部分),而是滚动手势。 因此,建议改用RecyclerView。

Note: Fragments that belong to a CoordinatorLayout activity need to use NestedScrollView or RecyclerView as parent to allow the scrolling gestures to work correctly.

注意 :属于CoordinatorLayout活动的片段需要使用NestedScrollView或RecyclerView作为父对象,以允许滚动手势正确工作。

Before we replace our ListView implementation in the application, let’s wrap the current fragment’s layout with a NestedScrollView as shown below.

在我们在应用程序中替换ListView实现之前,让我们用NestedScrollView包装当前片段的布局,如下所示。

fragment_list.xml

fragment_list.xml

<?xml version="1.0" encoding="utf-8"?><android.support.v4.widget.NestedScrollView xmlns:android="https://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"><ListView xmlns:android="https://schemas.android.com/apk/res/android"android:id="@+id/list"android:layout_width="match_parent"android:layout_height="wrap_content" /></android.support.v4.widget.NestedScrollView>

Let’s see how the application behaves now:

让我们看看应用程序现在的行为:

Whoops, the scrolling is fixed but the ListView is displaying only one row now. Hence a ListView should not be used with our Material Design view types. Let’s fix the application now.

糟糕,滚动是固定的,但ListView现在仅显示一行。 因此,ListView不应与我们的“材料设计”视图类型一起使用。 现在修复该应用程序。

Android TabLayout ViewPager项目结构 (Android TabLayout ViewPager Project Structure)

Android TabLayout ViewPager示例代码 (Android TabLayout ViewPager Example Code)

The activity_main.xml, MainActivity.java and ViewPagerAdapter.java classes are unchanged. Let’s look at the Fragments now.

activity_main.xml,MainActivity.java和ViewPagerAdapter.java类保持不变。 现在让我们看一下碎片。

The layout of the fragments is given below.

片段的布局如下。

fragment.xml

fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView android:id="@+id/recycler_view"android:layout_width="match_parent"android:layout_height="match_parent"xmlns:android="https://schemas.android.com/apk/res/android" />

The FragmentA(/B/C).java is given below

FragmentA(/B/C).java如下所示

package com.journaldev.tablayoutviewpager;import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;public class FragmentA extends Fragment {RecyclerView recyclerView;@Nullable@Overridepublic View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {View rootView = inflater.inflate(R.layout.fragment, container, false);return rootView;}@Overridepublic void onViewCreated(View view, @Nullable Bundle savedInstanceState) {super.onViewCreated(view, savedInstanceState);String[] items = getResources().getStringArray(R.array.tab_A);RecyclerViewAdapter adapter = new RecyclerViewAdapter(items);recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());recyclerView.setLayoutManager(layoutManager);recyclerView.setAdapter(adapter);}
}

We’ve shifted the data to be displayed into the strings.xml file.
It’s defined there as

我们已经将要显示的数据移到了strings.xml文件中。
在这里定义为

<resources><string name="app_name">TabLayoutViewPager</string><string name="action_settings">Settings</string><string-array name="tab_A"><item>Item 1A</item><item>Item 1B</item></string-array><string-array name="tab_B"><item>Item 2A</item></string-array>
</resources>

Note: We’ve optimised our fragment code logic such that it populates the adapter and displays it once the view is created.

注意:我们已经优化了片段代码逻辑,以便它填充适配器并在创建视图后显示适配器。

The RecyclerViewAdapter.java has a string array as the argument.
The code for it is given below.

RecyclerViewAdapter.java具有一个字符串数组作为参数。
其代码如下。

public class RecyclerViewAdapter extends RecyclerView.Adapter {String[] items;public RecyclerViewAdapter(String[] items) {this.items = items;}@Overridepublic TextItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_list_item, parent, false);return new TextItemViewHolder(view);}@Overridepublic void onBindViewHolder(TextItemViewHolder holder, int position) {holder.bind(items[position]);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic int getItemCount() {return items.length;}
}

In the above code we’ve added a custom RecyclerViewHolder class that has a layout similar to list items.

在上面的代码中,我们添加了一个自定义的RecyclerViewHolder类,该类的布局类似于列表项。

The TextItemViewHolder.java class is given below.

下面给出TextItemViewHolder.java类。

public class TextItemViewHolder extends RecyclerView.ViewHolder {private TextView textView;public TextItemViewHolder(View itemView) {super(itemView);textView = (TextView) itemView.findViewById(R.id.list_item);}public void bind(String text) {textView.setText(text);}}

The layout for the above custom ViewHolder is:

上述自定义ViewHolder的布局为:

recycler_view_list_item.xml

recycler_view_list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"><TextViewandroid:id="@+id/list_item"android:textSize="18sp"android:paddingTop="@dimen/activity_vertical_margin"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingRight="8dp"android:paddingLeft="8dp"android:layout_width="match_parent"android:layout_height="wrap_content" /><Viewandroid:id="@+id/separator"android:layout_width="match_parent"android:layout_height="1dp"android:background="#858585" />
</LinearLayout>

The output of the application in action is given below

实际应用程序的输出如下

The layout structure resembles that of the WhatsApp Application. To make it more similar do the following changes:

布局结构类似于WhatsApp应用程序的布局结构。 为了使其更相似,请进行以下更改:

  • Import and add the two menu icon drawables导入并添加两个菜单图标可绘制对象
  • Inflate them in the MainActivity.java in the onCreateOptionsMenu()onCreateOptionsMenu()的MainActivity.java中为它们充气
  • Change the colorPrimary and colorPrimaryDark to #00897B and #00796B respectively将colorPrimary和colorPrimaryDark分别更改为#00897B和#00796B

To inflate the menu layout add the following method in the MainActivity.java.

要增加菜单布局,请在MainActivity.java中添加以下方法。

@Overridepublic boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.menu_main, menu);return super.onCreateOptionsMenu(menu);}

The menu_main.xml looks like this:

menu_main.xml如下所示:

<menu xmlns:android="https://schemas.android.com/apk/res/android"xmlns:app="https://schemas.android.com/apk/res-auto"xmlns:tools="https://schemas.android.com/tools"tools:context="com.journaldev.tablayoutviewpager.MainActivity"><itemandroid:id="@+id/action_settings"android:orderInCategory="100"android:title="@string/action_settings"app:showAsAction="never" /><itemandroid:id="@+id/action_search"android:orderInCategory="100"android:title="@string/action_settings"android:icon="@drawable/search"app:showAsAction="ifRoom" /><itemandroid:id="@+id/action_add"android:orderInCategory="100"android:title="@string/action_settings"android:icon="@drawable/add"app:showAsAction="ifRoom" />
</menu>

On doing the above changes you’ll end up with something like this

完成上述更改后,您将得到如下所示的结果

This brings an end to this tutorial. You can download the Android TabLayoutViewPager Project from the below link.

本教程到此结束。 您可以从下面的链接下载Android TabLayoutViewPager项目。

Download Android TabLayout ViewPager Project下载Android TabLayout ViewPager项目

翻译自: https://www.journaldev.com/12958/android-tablayout-viewpager

Android TabLayout和ViewPager相关推荐

  1. 011 Android TabLayout+ViewPager实现顶部滑动效果(多个页面)

    1.TabLayout介绍 TabLayout提供了一个水平的布局用来展示Tabs,很多应用都有这样的设计,典型的有网易新闻,简书,知乎等.TabLayout就可以很好的完成这一职责,首先TabLay ...

  2. Android TabLayout定制CustomView与ViewPager交互双向联动

     Android TabLayout定制CustomView与ViewPager交互双向联动 我之前写了一些关于Android Material Design TabLayout的文章, (1)& ...

  3. Android MVVM框架搭建(九)TabLayout、ViewPager、城市地图天气切换

    Android MVVM框架搭建(九)TabLayout.ViewPager.城市地图切换 前言 正文 一.父Fragment加载子Fragment ① Fragment适配器 ② TabLayout ...

  4. Android之TabLayout和ViewPager组合跳转到指定页面

    1 问题 TabLayout和ViewPager组合跳转到具体一个页面 2 解决办法 viewPager?.setCurrentItem(index) index为0说明是第一页,如果是1的话就是第二 ...

  5. Android TabLayout(选项卡布局)简单用法实例分析

    本文实例讲述了Android TabLayout(选项卡布局)简单用法.分享给大家供大家参考,具体如下: 我们在应用viewpager的时候,经常会使用TabPageIndicator来与其配合.达到 ...

  6. TabLayout和ViewPager

    这里就说下tablayout+viewpager的实现方式:tablayout是android5.0推出来的一个MaterialDesign风格的控件,是专门用来实现tab栏效果的:功能强大,使用方便 ...

  7. Android两个tab吸顶,Android scrollView和viewpager嵌套 指示器吸顶 根据viewpager每

    Android scrollView和viewpager嵌套 指示器吸顶 根据viewpager每 Android scrollView和viewpager嵌套 指示器吸顶 根据viewpager每个 ...

  8. android tab pageview,Android Fragment在ViewPager中到底经历了什么?

    2017年05月30 最后的懒加载写的不好,推荐请叫我大苏同学写的Fragment懒加载博客, [Android]再来一篇Fragment的懒加载(只加载一次哦) 在大苏同学的博客评论里,看到了另一个 ...

  9. TabLayout+Fragment+ViewPager+FragmentStatePagerAdapter实现Tab标签

    首先来看下实现的效果吧: 最近在项目中实现这个效果的时候.尽管自己磕磕绊绊的实现了,可是知识确实模模糊糊的,今天天气异常的冷,在加上这个知识不太熟练,实在是没有心情进行接下来的计划,干脆借着这个时间, ...

最新文章

  1. RDKit | 基于RDKit和化学信息学探索化学空间
  2. 组件和模块间Activity路由框架
  3. java 怎么中断一个线程
  4. ArrayList 的实现原理
  5. wpf 使子ui元素可视区域不超过父元素_对游戏UI设计的一点思考
  6. hive避免MR的情况
  7. Linux中常用的目录(/home,/etc ,/opt)
  8. MVVM开发模式MVVM Light Toolkit
  9. 《云周刊》69期:开门红利!阿里云2月活动来袭
  10. c++之EXTERN详细讲解
  11. linux系统计时,关于linux:计算机系统中的计时机制
  12. 真鱼游来游去动态壁纸_真鱼动态壁纸
  13. matlab矩阵转置函数
  14. 开始写博客之学习编程的重要性
  15. 什么是keep-alive?
  16. 警惕:互联网上充满了这样的「流量陷阱」
  17. c语言 符号自动换行,单片机串口发送字符为什么会自动换行?
  18. CSS实现汉字与数字底部对齐
  19. oracle crm系统叫什么,目前市场上的CRM系统有哪些
  20. 计算机硬件仿真软件,仿真软件

热门文章

  1. 收缩 虚拟硬盘 shrink vhd
  2. 注册flash.ocx inno setup (转)
  3. 支持iCloud简记
  4. [原创] 图片操作的类(ImageLibrary)-按比例缩放图片
  5. [转载] 树莓派4B使用 Adafruit_PCA9685 报错IOError: [Errno 121] Remote I/O error解决办法
  6. [转载] Python基础:什么是字符串?字符串是用来做什么的?
  7. [转载] 跟着吴恩达学机器学习(Machine Learning) on Coursera 第一天
  8. [转载] 如何使用 Python 生成酷炫的二维码?
  9. day31(GIL锁)
  10. JAVA基础-类型转换