Android TabLayout 和 ViewPager

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

Android TabLayout ViewPager概述

可视寻呼机用于在数据页面中滑动。它通常与片断连用。让我们修改上一个教程中的布局,如下所示。active_main.xml

 1<?xml version="1.0" encoding="utf-8"?>
 2<android.support.design.widget.CoordinatorLayout xmlns:android="https://schemas.android.com/apk/res/android"
 3    xmlns:app="https://schemas.android.com/apk/res-auto"
 4    xmlns:tools="https://schemas.android.com/tools"
 5    android:layout_width="match_parent"
 6    android:layout_height="match_parent"
 7    android:fitsSystemWindows="true"
 8    tools:context="com.journaldev.tablayoutviewpager.MainActivity">
 9
10    <android.support.design.widget.AppBarLayout
11        android:layout_width="match_parent"
12        android:layout_height="wrap_content"
13        android:theme="@style/AppTheme.AppBarOverlay">
14
15        <android.support.v7.widget.Toolbar
16            android:id="@+id/toolbar"
17            android:layout_width="match_parent"
18            android:layout_height="?attr/actionBarSize"
19            android:background="?attr/colorPrimary"
20            app:layout_scrollFlags="scroll|enterAlways"
21            app:popupTheme="@style/AppTheme.PopupOverlay" />
22
23        <android.support.design.widget.TabLayout
24            android:id="@+id/tabs"
25            style="@style/MyStyle"
26            android:layout_width="match_parent"
27            android:layout_height="wrap_content"
28            app:tabGravity="fill"
29            app:tabMode="fixed" />
30
31    </android.support.design.widget.AppBarLayout>
32
33    <android.support.v4.view.ViewPager
34        android:id="@+id/viewPager"
35        android:layout_width="match_parent"
36        android:layout_height="wrap_content"
37        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
38
39    <android.support.design.widget.FloatingActionButton
40        android:id="@+id/fab"
41        android:layout_width="wrap_content"
42        android:layout_height="wrap_content"
43        android:layout_gravity="bottom|end"
44        android:layout_margin="@dimen/fab_margin"
45        android:src="@android:drawable/ic_dialog_email" />
46
47</android.support.design.widget.CoordinatorLayout>

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

 1public class ViewPagerAdapter extends FragmentPagerAdapter {
 2
 3    public ViewPagerAdapter(FragmentManager fm) {
 4        super(fm);
 5    }
 6
 7    @Override
 8    public Fragment getItem(int position) {
 9        Fragment fragment = null;
10        if (position == 0)
11        {
12            fragment = new FragmentA();
13        }
14        else if (position == 1)
15        {
16            fragment = new FragmentB();
17        }
18        else if (position == 2)
19        {
20            fragment = new FragmentC();
21        }
22        return fragment;
23    }
24
25    @Override
26    public int getCount() {
27        return 3;
28    }
29
30    @Override
31    public CharSequence getPageTitle(int position) {
32        String title = null;
33        if (position == 0)
34        {
35            title = "Tab-1";
36        }
37        else if (position == 1)
38        {
39            title = "Tab-2";
40        }
41        else if (position == 2)
42        {
43            title = "Tab-3";
44        }
45        return title;
46    }
47}

上述 ViewPagerAdapter 扩展了** FragmentPagerAdapter** 。它调用三个片段,每个页面一个。每个片段都包含一个ListView,如下所示:fragment_list.xml

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

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

 1public class FragmentA extends Fragment {
 2
 3    ListView list;
 4
 5    public FragmentA() {
 6    }
 7
 8    @Override
 9    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
10        View view = inflater.inflate(R.layout.fragment, container, false);
11
12        list = (ListView) view.findViewById(R.id.list);
13        ArrayList stringList= new ArrayList();
14
15        stringList.add("Item 1A");
16        stringList.add("Item 1B");
17        stringList.add("Item 1C");
18        stringList.add("Item 1D");
19        stringList.add("Item 1E");
20        stringList.add("Item 1F");
21        stringList.add("Item 1G");
22        stringList.add("Item 1H");
23        stringList.add("Item 1I");
24        stringList.add("Item 1J");
25        stringList.add("Item 1K");
26        stringList.add("Item 1L");
27        stringList.add("Item 1M");
28        stringList.add("Item 1N");
29        stringList.add("Item 1O");
30        stringList.add("Item 1P");
31        stringList.add("Item 1Q");
32        stringList.add("Item 1R");
33        stringList.add("Item 1S");
34        stringList.add("Item 1T");
35        stringList.add("Item 1U");
36        stringList.add("Item 1V");
37        stringList.add("Item 1W");
38        stringList.add("Item 1X");
39        stringList.add("Item 1Y");
40        stringList.add("Item 1Z");
41
42        CustomAdapter adapter = new CustomAdapter(stringList,getActivity());
43        list.setAdapter(adapter);
44
45        return view;
46    }
47}

上述ListView的CustomAdapter.java类为:

 1public class CustomAdapter extends ArrayAdapter {
 2
 3    private ArrayList dataSet;
 4    Context mContext;
 5
 6    // View lookup cache
 7    private static class ViewHolder {
 8        TextView txtName;
 9
10    }
11
12    public CustomAdapter(ArrayList data, Context context) {
13        super(context, R.layout.row_item, data);
14        this.dataSet = data;
15        this.mContext = context;
16
17    }
18
19    @Nullable
20    @Override
21    public String getItem(int position) {
22        return dataSet.get(position);
23    }
24
25    @Override
26    public View getView(int position, View convertView, ViewGroup parent) {
27
28        ViewHolder viewHolder; // view lookup cache stored in tag
29
30        if (convertView == null) {
31
32            viewHolder = new ViewHolder();
33            LayoutInflater inflater = LayoutInflater.from(getContext());
34            convertView = inflater.inflate(R.layout.row_item, parent, false);
35            viewHolder.txtName = (TextView) convertView.findViewById(R.id.name);
36            convertView.setTag(viewHolder);
37        } else {
38            viewHolder = (ViewHolder) convertView.getTag();
39        }
40
41        viewHolder.txtName.setText(getItem(position));
42        // Return the completed view to render on screen
43        return convertView;
44    }
45}

MainActivity.java 类如下所示

 1public class MainActivity extends AppCompatActivity {
 2
 3    TabLayout tabLayout;
 4    ViewPager viewPager;
 5    ViewPagerAdapter viewPagerAdapter;
 6
 7    @Override
 8    protected void onCreate(Bundle savedInstanceState) {
 9        super.onCreate(savedInstanceState);
10        setContentView(R.layout.activity_main);
11        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
12        setSupportActionBar(toolbar);
13
14        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
15        fab.setOnClickListener(new View.OnClickListener() {
16            @Override
17            public void onClick(View view) {
18                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
19                        .setAction("Action", null).show();
20            }
21        });
22
23        viewPager = (ViewPager) findViewById(R.id.viewPager);
24        viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
25        viewPager.setAdapter(viewPagerAdapter);
26        tabLayout = (TabLayout) findViewById(R.id.tabs);
27        tabLayout.setupWithViewPager(viewPager);
28    }
29
30}

在上面的代码中,setupWithViewPager() 用于连接TabLayout和ViewPager。FragmentPagerAdapter中的** getPageTitle()** 方法用于设置每个标签页的标题。让我们来看看上面代码运行时的输出Android标签布局视图分页程序issue** 问题** :为什么工具栏没有按照scllFlags集进行滚动?这是因为** ListView** 。协调员布局不支持ListView(它不是材料设计的一部分),而且它是滚动手势。因此,建议改用RecclerView。** 注意** :如果分片属于协调员Layout活动,则需要使用NestedScrollView或RecclerView作为父级,才能使滚动手势正常工作。在替换应用程序中的ListView实现之前,让我们用NestedScrollView包装当前片段的布局,如下所示。Fragment_list.xml

 1<?xml version="1.0" encoding="utf-8"?>
 2
 3<android.support.v4.widget.NestedScrollView xmlns:android="https://schemas.android.com/apk/res/android"
 4    android:layout_width="match_parent"
 5    android:layout_height="wrap_content">
 6
 7    <ListView xmlns:android="https://schemas.android.com/apk/res/android"
 8        android:id="@+id/list"
 9        android:layout_width="match_parent"
10        android:layout_height="wrap_content" />
11
12</android.support.v4.widget.NestedScrollView>

让我们看看应用程序现在的行为:Android Tablayout Viewpager issue哇,滚动被修复了,但Listview现在只显示一行。因此,ListView不应与材质设计视图类型一起使用。让我们现在修复应用程序。

Android TabLayout ViewPager项目结构

Android TabLayout ViewPager project

Android TabLayout ViewPager示例代码

Activity_main.xml、MainActivity.java和ViewPagerAdapter.java类保持不变。现在让我们来看看这些碎片。片段的布局如下所示。Fragment.xml

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

下面给出了**FragmentA(/B/C).java**

 1package com.journaldev.tablayoutviewpager;
 2
 3import android.os.Bundle;
 4import android.support.annotation.Nullable;
 5import android.support.v4.app.Fragment;
 6import android.support.v7.widget.LinearLayoutManager;
 7import android.support.v7.widget.RecyclerView;
 8import android.view.LayoutInflater;
 9import android.view.View;
10import android.view.ViewGroup;
11
12public class FragmentA extends Fragment {
13
14    RecyclerView recyclerView;
15
16    @Nullable
17    @Override
18    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
19        View rootView = inflater.inflate(
20                R.layout.fragment, container, false);
21        return rootView;
22    }
23
24    @Override
25    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
26        super.onViewCreated(view, savedInstanceState);
27
28        String[] items = getResources().getStringArray(R.array.tab_A);
29        RecyclerViewAdapter adapter = new RecyclerViewAdapter(items);
30        recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
31        LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
32        recyclerView.setLayoutManager(layoutManager);
33        recyclerView.setAdapter(adapter);
34
35    }
36}

我们已经将要显示的数据转换到strings.xml文件中。它在那里定义为

 1<resources>
 2    <string name="app_name">TabLayoutViewPager</string>
 3    <string name="action_settings">Settings</string>
 4
 5    <string-array name="tab_A">
 6        <item>Item 1A</item>
 7        <item>Item 1B</item>
 8    </string-array>
 9
10    <string-array name="tab_B">
11        <item>Item 2A</item>
12    </string-array>
13</resources>

注意:我们已经优化了我们的片段代码逻辑,以便它填充适配器并在创建视图后显示它。RecillerViewAdapter.java 参数为字符串数组。其代码如下所示。

 1public class RecyclerViewAdapter extends RecyclerView.Adapter {
 2
 3    String[] items;
 4
 5    public RecyclerViewAdapter(String[] items) {
 6        this.items = items;
 7    }
 8
 9    @Override
10    public TextItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
11        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_list_item, parent, false);
12        return new TextItemViewHolder(view);
13    }
14
15    @Override
16    public void onBindViewHolder(TextItemViewHolder holder, int position) {
17        holder.bind(items[position]);
18    }
19
20    @Override
21    public long getItemId(int position) {
22        return position;
23    }
24
25    @Override
26    public int getItemCount() {
27        return items.length;
28    }
29}

在上面的代码中,我们添加了一个定制的RecclerViewHolder类,它的布局类似于列表项。TextItemViewHolder.java 类如下所示。

 1public class TextItemViewHolder extends RecyclerView.ViewHolder {
 2    private TextView textView;
 3
 4    public TextItemViewHolder(View itemView) {
 5        super(itemView);
 6        textView = (TextView) itemView.findViewById(R.id.list_item);
 7    }
 8
 9    public void bind(String text) {
10        textView.setText(text);
11    }
12
13}

上述自定义ViewHolder的布局为:Rececumer_view_list_item.xml

 1<?xml version="1.0" encoding="utf-8"?>
 2<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
 3    android:orientation="vertical"
 4    android:layout_width="match_parent"
 5    android:layout_height="wrap_content">
 6    <TextView
 7        android:id="@+id/list_item"
 8        android:textSize="18sp"
 9        android:paddingTop="@dimen/activity_vertical_margin"
10        android:paddingBottom="@dimen/activity_vertical_margin"
11        android:paddingRight="8dp"
12        android:paddingLeft="8dp"
13        android:layout_width="match_parent"
14        android:layout_height="wrap_content" />
15    <View
16        android:id="@+id/separator"
17        android:layout_width="match_parent"
18        android:layout_height="1dp"
19        android:background="#858585" />
20</LinearLayout>

运行中的应用程序的输出如下所示Android Tablayout Viewpager output布局结构类似于WhatsApp应用程序。要使其更相似,请执行以下更改:

  • 导入并添加两个菜单图标可绘制项
  • onCreateOptionsMenu()** 中的MainActivity.java中膨胀它们
  • 将ColorPrimary和ColorPrimaryDark分别更改为# 00897B和 00796B

要扩大菜单布局,请在MainActivity.Java中添加以下方法。

1@Override
2    public boolean onCreateOptionsMenu(Menu menu) {
3
4        getMenuInflater().inflate(R.menu.menu_main, menu);
5
6        return super.onCreateOptionsMenu(menu);
7    }

menu_main.xml看起来像这样:

 1<menu xmlns:android="https://schemas.android.com/apk/res/android"
 2    xmlns:app="https://schemas.android.com/apk/res-auto"
 3    xmlns:tools="https://schemas.android.com/tools"
 4    tools:context="com.journaldev.tablayoutviewpager.MainActivity">
 5    <item
 6        android:id="@+id/action_settings"
 7        android:orderInCategory="100"
 8        android:title="@string/action_settings"
 9        app:showAsAction="never" />
10
11    <item
12        android:id="@+id/action_search"
13        android:orderInCategory="100"
14        android:title="@string/action_settings"
15        android:icon="@drawable/search"
16        app:showAsAction="ifRoom" />
17
18    <item
19        android:id="@+id/action_add"
20        android:orderInCategory="100"
21        android:title="@string/action_settings"
22        android:icon="@drawable/add"
23        app:showAsAction="ifRoom" />
24</menu>

进行上述更改后,您将得到如下所示的结果:Android Tablayout ViewPager Simple whatsapp这将结束本教程。您可以从下面的链接下载Android TabLayoutViewPager项目。

DowloadAndroidTabrodTabs/Dayout Manager项目

Published At
Categories with 技术
Tagged with
comments powered by Disqus