Android 原生实现Tap切换字体变色下划线移动

前言

我们知道,现在实现Tab切换之类的效果都是android TabLayout+ViewPager配合使用。刚开始开发那段时期,第一次看见某app滑动tap标题变色下划线移动效果,当时非常喜欢,于是从网上找资料,发现它是一个用自定义view绘制画图实现的。本人不是对这种实现有偏见,只是觉得它太繁琐复杂,但是我的个性是有些功能搞懂Viewpager的原理后,自己动手就能实现了。

好了,废话不说了,上源码和效果图Tap切换字体变色下划线移动

实现逻辑

首先,效果看起来还是蛮棒的,代码怎么写呢?源码已经发了, 下面粘贴出来,关键点都在代码中讲解了。首先,从整体控件布局上看,它包含三个部分,分别是一个FragmentActivity(v4.app.fragment 需要宿主继承)、2个fragment、一个viewpager。

其次,是下划线的测量和计算。

最后,主要看viewpager的页面切换监听。

 

实现代码

public class MainActivity extends FragmentActivity implements View.OnClickListener, ViewPager.OnPageChangeListener{

    private TextView mTextViews1;
    private TextView mTextViews2;
    private ViewPager mViewpager;
    /*
     * tab下划线
     */
    private LinearLayout.LayoutParams params;
    private int width;
    private LinearLayout tabView;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initUi();
    }
    //初始化
    private void initUi() {
        mTextViews1= (TextView) findViewById(R.id.news_tab);
        mTextViews2=(TextView) findViewById(R.id.daily_tab);
        tabView= (LinearLayout)findViewById(R.id.tab_view);
        mViewpager =(ViewPager) findViewById(R.id.viewpager);
        mViewpager.addOnPageChangeListener(this);
        mTextViews1.setOnClickListener(this);
        mTextViews2.setOnClickListener(this);
        initTabLine();

        List<Fragment> mList=new ArrayList<Fragment>();
        mList.add(new OneFragment());
        mList.add(new OneFragment());
        mViewpager.setAdapter(new MissonPagerAdapter(getSupportFragmentManager(),mList));
        mViewpager.setOffscreenPageLimit(0);//设置页面缓存数量  默认为2表示当前页左右的缓存个数  加当前页其实3个页面
    }
    /**
     * 初始化tab下划线
     * 实现步骤:
     * 1、获取屏幕大小 比例设置宽度
     * 2、然后有几个tab就分几份  移动时改变外边距参数
     */
    private void initTabLine() {
        params = (LinearLayout.LayoutParams) tabView.getLayoutParams();
        DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);
        width = metrics.widthPixels / 2;
        params.width = width;
        tabView.setLayoutParams(params);
    }

    /**
     * 滑动监听
     * @param position 第一个页面索引为0
     * @param positionOffset  从左向右 0-0.99  反之 0.99-0 (主要跟右边页面有关系) 当0.5以上下一页 反之回到滑动前
     * @param positionOffsetPixels 整数值
     */
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        if(positionOffset!=0){
            mTextViews2.setTextColor(Color.argb(255, (int) (255*positionOffset), (int) (115*positionOffset),0));
            mTextViews1.setTextColor(Color.argb(255, (int) (255*(1-positionOffset)), (int) (115*(1-positionOffset)),0));
            params.leftMargin =  (int)(width*positionOffset);
            tabView.setLayoutParams(params);
        }
    }
    //滑动结束
    @Override
    public void onPageSelected(int position) {
        if (position==0){
            mTextViews1.setTextColor(Color.argb( 255, 255, 115, 0));
            mTextViews2.setTextColor(Color.argb( 255, 0, 0, 0));
            params.leftMargin=0;
            tabView.setLayoutParams(params);
        }else if (position==1){
            params.leftMargin = width;
            tabView.setLayoutParams(params);
            mTextViews1.setTextColor(Color.argb(255,0,0,0));
            mTextViews2.setTextColor(Color.argb( 255, 255, 155, 0));
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }

    /**
     * 点击切换
     */
    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.news_tab:
                mViewpager.setCurrentItem(0,true);
                params.leftMargin=width/2;
                tabView.setLayoutParams(params);
                break;

            case R.id.daily_tab:
                mViewpager.setCurrentItem(1,true);
                params.leftMargin = width*2+width/2;
                tabView.setLayoutParams(params);
                break;
        }
    }

布局文件就补贴出来了,很简单。欢迎大家下载demo。

 

源码下载:Tap切换字体变色下划线移动

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
React中实现Tap切换有多种方法,我将为你介绍其中一种常见的实现方式。 首先,你可以使用React的状态管理来控制Tap栏的切换。你可以创建一个父组件,该组件包含多个Tap栏选项以及需要根据选项显示的内容。通过设置一个状态来跟踪当前选中的Tap栏选项,然后根据选项的状态来显示对应的内容。 以下是一个示例代码: ```jsx import React, { useState } from 'react'; const Tab = ({ label, content, activeTab, onClick }) => { const isActive = activeTab === label; return ( <div className={`tab ${isActive ? 'active' : ''}`} onClick={() => onClick(label)} > {label} </div> ); }; const TabContent = ({ content, activeTab }) => { return ( <div className="tab-content"> {content[activeTab]} </div> ); }; const TapBar = ({ tabs }) => { const [activeTab, setActiveTab] = useState(tabs[0].label); const handleTabClick = (label) => { setActiveTab(label); }; return ( <div> <div className="tab-bar"> {tabs.map(tab => ( <Tab key={tab.label} label={tab.label} content={tab.content} activeTab={activeTab} onClick={handleTabClick} /> ))} </div> <TabContent content={tabs.reduce((obj, tab) => ({ ...obj, [tab.label]: tab.content }), {})} activeTab={activeTab} /> </div> ); }; const App = () => { const tabs = [ { label: 'Tab 1', content: 'Content for Tab 1' }, { label: 'Tab 2', content: 'Content for Tab 2' }, { label: 'Tab 3', content: 'Content for Tab 3' } ]; return ( <div> <h1>Tabs Demo</h1> <TapBar tabs={tabs} /> </div> ); }; export default App; ``` 在上面的代码中,我们创建了一个`TapBar`组件,它接受一个`tabs`数组作为参数,并通过`map`方法渲染了多个`Tab`组件。每个`Tab`组件都有一个点击事件,当点击时,会调用`handleTabClick`函数来更新当前选中的Tap栏选项。同时,我们还创建了一个`TabContent`组件来根据选中的Tap栏选项显示对应的内容。 请记得在样式文件中添加相应的样式以实现Tap栏的外观和交互效果。 希望能对你有所帮助!如有其他问题,请随时提问。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

艾阳Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值