Android仿今日头条滑动页面导航效果

一、介绍

在Android开发中,实现滑动页面导航效果是比较常见的需求之一。本文针对如何实现仿今日头条的页面滑动导航效果进行详细讲解。

二、实现步骤

1.在布局文件中定义ViewPager和TabLayout控件,用于展示滑动页面和导航栏;

2.在Java代码中定义FragmentPagerAdapter,ViewPager的适配器;通过适配器承载Fragment实现滑动页面的展示;

3.在Java代码中设置TabLayout与ViewPager关联,实现滑动页面导航的效果;

4.通过自定义View为TabLayout设置下划线并提供属性接口,实现滑动条的效果。

三、示例说明

1.布局文件

在布局文件中,需要定义ViewPager和TabLayout两个控件。其中ViewPager用于展示滑动页面,而TabLayout用于展示导航栏。示例代码如下:

<android.support.design.widget.TabLayout
    android:id="@+id/tab_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:tabGravity="center"
    app:tabMode="fixed"
    app:tabSelectedTextColor="#000000"
    app:tabTextColor="#666666" />

<android.support.v4.view.ViewPager
    android:id="@+id/view_pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

2.Java代码

在Java代码中,需要定义FragmentPagerAdapter适配器,并在TabLayout中与ViewPager关联。同时,为了实现滑动条的效果,需要定义一个自定义View继承自View并实现onDraw方法,用于绘制TabLayout下方的滑动条。示例代码如下:

public class MainActivity extends AppCompatActivity {

    private TabLayout mTabLayout;
    private ViewPager mViewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTabLayout = findViewById(R.id.tab_layout);
        mViewPager = findViewById(R.id.view_pager);

        FragmentPagerAdapter adapter = new FragmentPagerAdapter(getSupportFragmentManager()) {

            private String[] mTitles = {"推荐", "热点", "视频", "社会", "娱乐", "科技", "汽车", "体育"};

            @Override
            public Fragment getItem(int position) {
                return PlaceholderFragment.newInstance(position);
            }

            @Override
            public int getCount() {
                return mTitles.length;
            }

            @Override
            public CharSequence getPageTitle(int position) {
                return mTitles[position];
            }
        };

        mViewPager.setAdapter(adapter);
        mTabLayout.setupWithViewPager(mViewPager);
        mTabLayout.setSelectedTabIndicatorColor(getResources().getColor(R.color.colorAccent));
        mTabLayout.post(() -> {
            int width = mTabLayout.getWidth() / mViewPager.getAdapter().getCount();
            DisplayMetrics metrics = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(metrics);
            int screenW = metrics.widthPixels;
            int tabWidth = width + mTabLayout.getTabSelectedIndicator().getIntrinsicWidth();
            int marginLeft = (screenW / mViewPager.getAdapter().getCount() - tabWidth) / 2;
            mTabLayout.setPadding(marginLeft, mTabLayout.getPaddingTop(), marginLeft, mTabLayout.getPaddingBottom());
        });
        mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                mTabLayout.scroll(position, positionOffset);
            }
        });
        mViewPager.setCurrentItem(0);
    }
}

public class TabLayoutIndicatorView extends View {

    private Paint mPaint;
    private int mIndicatorColor;
    private int mIndicatorHeight;
    private float mIndicatorCenterX = 0;
    private float mIndicatorPullOutDistance = 0;

    public TabLayoutIndicatorView(Context context) {
        this(context, null);
    }

    public TabLayoutIndicatorView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TabLayoutIndicatorView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mIndicatorColor = Color.BLACK;
        mIndicatorHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, getResources().getDisplayMetrics());
    }

    public void setIndicatorColor(int color) {
        mIndicatorColor = color;
    }

    public void setIndicatorHeight(int height) {
        mIndicatorHeight = height;
    }

    public void setIndicatorPosition(float center, float pullOut) {
        mIndicatorCenterX = center;
        mIndicatorPullOutDistance = pullOut;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setColor(mIndicatorColor);
        canvas.drawRect(
                mIndicatorCenterX - mIndicatorPullOutDistance,
                getHeight() - mIndicatorHeight,
                mIndicatorCenterX + mIndicatorPullOutDistance,
                getHeight(),
                mPaint);
    }
}

四、总结

通过以上步骤,我们可以实现仿今日头条的滑动页面导航效果。其中,在Java代码中需要注意ViewPager及TabLayout的适配和关联,以及自定义View的使用,这是实现该效果的关键。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android仿今日头条滑动页面导航效果 - Python技术站

(0)
上一篇 2023年6月20日
下一篇 2023年6月20日

相关文章

  • Linux中文件的五个查找命令总结

    下面是详细讲解“Linux中文件的五个查找命令总结”的完整攻略。 前言 在 Linux 操作系统中,我们常常需要查找文件。Linux中有五个命令可以帮助我们进行文件查找,分别是 find、locate、whereis、which 和 type 命令。本文将为大家分别介绍这五个命令的使用方法。 一、find命令 find 命令是Linux下最常用的查找文件命令…

    other 2023年6月26日
    00
  • Android进程保活之提升进程优先级

    现在我来详细讲解一下”Android进程保活之提升进程优先级”的攻略,文本将包含以下内容: 什么是进程优先级 进程优先级的分类 如何提升进程优先级 示例说明 总结 1. 什么是进程优先级 Android中的进程是指运行的应用程序,每个应用程序都有自己的进程。Android系统按照一定的规则分配进程优先级,优先级越高的进程越有可能优先被系统调度执行。当系统资源…

    other 2023年6月27日
    00
  • Java Spring WEB应用实例化如何实现

    Java Spring是一个非常流行的企业级应用开发框架,它支持快速、可靠和易于维护的Web应用程序的开发。在这里,我们将提供一个完整的攻略来说明如何实现Java Spring WEB应用的实例化。 首先,我们需要准备好Spring框架的基础环境。我们可以通过Maven或Gradle等构建工具快速构建Spring项目,选择适当的依赖项,并在pom.xml或b…

    other 2023年6月26日
    00
  • 64位 win10系统安装绿色版mysql-5.7.16-winx64的教程

    下面是详细的攻略: 1. 下载MySQL-5.7.16-winx64绿色版安装包 首先,在MySQL官网中找到MySQL-5.7.16-winx64绿色版的下载链接,下载到本地。 2. 安装MySQL-5.7.16-winx64 接着,找到下载后的压缩包,解压到本地某一文件夹,比如 D:\mysql-5.7.16-winx64。 进入解压后的文件夹,双击运行…

    other 2023年6月27日
    00
  • Jmeter 中 CSV 如何参数化测试数据并实现自动断言示例详解

    JMeter中参数化测试数据并实现自动断言的完整攻略 以下是使用JMeter实现参数化测试数据并实现自动断言的完整攻略: 步骤1:准备CSV文件 首先,您需要准备一个包含测试数据的CSV文件。该文件将包含您要使用的参数化数据。确保CSV文件的格式正确,并且每行数据对应一个测试用例。 步骤2:配置CSV数据集配置元件 在JMeter中,您可以使用CSV数据集配…

    other 2023年10月16日
    00
  • Redis链表底层实现及生产实战

    Redis链表底层实现及生产实战 Redis链表是一种基于指针的双向链表,每个节点都包含指向前一个节点和后一个节点的指针。链表是Redis的重要数据结构,常用于实现有序集合(sorted set)和列表(list)等数据类型。本文将详细讲解Redis链表的底层实现及生产实战。 Redis链表的实现方式 Redis链表是一个非常典型的双向链表,节点包括prev…

    other 2023年6月27日
    00
  • long转换为integer

    以下是详细讲解“long转换为integer的完整攻略”的标准Markdown格式文本,包含两个示例说明: long转换为integer的完整攻略 在Java中,long和integer是两种不同的数据类型。有时候需要将long类型的数据转换为integer类型的数据。本攻略将介绍如何将long类型的数据转换为integer类型的数据。 步骤一:使用强制类型…

    other 2023年5月10日
    00
  • wpf中使用cefsharp

    以下是关于“WPF中使用CefSharp”的完整攻略,包括基本概念、解决方法、示例说明和注意事项。 基本概念 CefSharp是一个基于Chromium的.NET开源项目,可以在WPF应用程序中嵌入Chromium浏览器。使用CefSharp实现在WPF应用程序中显示网页、执行JavaScript代码等功能。 解决方法 以下是在WPF中使用CefSharp的…

    other 2023年5月7日
    00
合作推广
合作推广
分享本页
返回顶部