自定义的带tab的可左右滑动的viewpager之一 简单实现

利用ViewPager实现可左右滑动的Action Tab 1. ViewPager要点: ViewPager 是一个布局管理类(layout manager),用于提供页面的左右滑动功能,类似于ListView,也有为ViewPager提供     数据(Fragment)的 adapter 控制类(FragmentPagerAdapter, FragmentStatePagerAdapter)。ViewPager 经常和 Fragment 一 阅读详情
项目大量使用,所以自己封装的带tab的可左右滑动的viewpager,灵活方便。上部为一个自定义的线性布局,下部为viewpager,点击上部自定义的tab下面的viewpager跟着切换,滑动下部的viewpager,上部的自定义的tab背景也跟着变换。效果如下:


实现:

1、activity_main.xml:使用的时候在你需要的地方加入一个线性布局,id为llTabSwipPager(此处必须,除非你修改,下同)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <LinearLayout
        android:id="@+id/llTabSwipPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:orientation="vertical" >
    </LinearLayout>

</RelativeLayout>

2、custom_tab_view.xml:自定义的Tab页面注释部分写在了代码中

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/llCustomTabView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/llTab"
        android:layout_width="match_parent"
        android:layout_height="42dp"
        android:orientation="horizontal" >

        <!--
             <RelativeLayout
            android:id="@+id/tab0"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/bg_view_pager_scroll_selected" >

            <TextView
                android:id="@+id/tv0"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:gravity="center"
                android:text="TAB0" />
        </RelativeLayout>
        -->

    </LinearLayout>

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

</LinearLayout>


3、还有一些自己用到的fragment布局就不贴了

4、MainActivity.java:使用方法,首先初始化你的fragment,然后拿到llTabSwipPager,最后创建一个TabSwipPager对象,设置第一步创建的fragment为TabSwipPager的数据源即可

package com.ttdevs.customviewpager;

import java.util.ArrayList;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.widget.LinearLayout;

import com.ttdevs.customviewpager.custom.TabSwipPager;

public class MainActivity extends FragmentActivity {

	private LinearLayout llTabSwipPager;
	private TabSwipPager tabSwipPager;

	private ArrayList<Fragment> fragmentsList;
	private String[] tags;

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

	private void initView() {
		initData();

		llTabSwipPager = (LinearLayout) findViewById(R.id.llTabSwipPager);

		tabSwipPager = new TabSwipPager(getApplicationContext(), getSupportFragmentManager(), llTabSwipPager);
		if (!tabSwipPager.setFragmentList(fragmentsList, tags)) {
			System.out.println("初始化失败");
			finish();
		}
	}

	private void initData() {
		fragmentsList = new ArrayList<Fragment>();
		fragmentsList.add(new UserMethedFragment());
		fragmentsList.add(new AFragment());
		fragmentsList.add(new BFragment());
		fragmentsList.add(new CFragment());

		tags = new String[] { "使用方法", "战机A", "战机B", "战机C" };

	}
}

5、自定义部分的代码:

a、TabSwipPager.jaa:

package com.ttdevs.customviewpager.custom;

import java.util.ArrayList;

import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.ViewPager;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;

public class TabSwipPager {

	private CustomViewManager customView;

	private Context context;
	private LinearLayout parentView, llTab;
	private FragmentManager fm;
	private ViewPager viewPager;
	private PagerAdapter pagerAdapter;

	public TabSwipPager(Context context, FragmentManager fm, LinearLayout parentView) {
		this.context = context;
		this.fm = fm;
		this.parentView = parentView;
	}

	public boolean setFragmentList(ArrayList<Fragment> fragmentsList, String[] tags) {
		if (tags.length != fragmentsList.size()) {
			return false;
		}

		customView = new CustomViewManager(context, tags);
		llTab = customView.getTabView();
		viewPager = customView.getViewPager();

		pagerAdapter = new PagerAdapter(fm, fragmentsList, viewPager, llTab);
		viewPager.setAdapter(pagerAdapter);

		parentView.addView(customView.getCustomTabView(), new LayoutParams(LayoutParams.MATCH_PARENT,
				LayoutParams.MATCH_PARENT));
		return true;
	}

}

b、PagerAdapter.java

package com.ttdevs.customviewpager.custom;

import java.util.ArrayList;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.LinearLayout;

import com.ttdevs.customviewpager.R;

public class PagerAdapter extends FragmentPagerAdapter implements OnPageChangeListener, OnClickListener {
	private ArrayList<Fragment> fragmentsList;
	private ViewPager viewPager;
	private LinearLayout llTab;

	public PagerAdapter(FragmentManager fm, ArrayList<Fragment> fragments, ViewPager viewPager, LinearLayout llTab) {
		super(fm);
		this.fragmentsList = fragments;
		this.viewPager = viewPager;
		this.llTab = llTab;

		this.viewPager.setOnPageChangeListener(this);
		
		for (int i = 0; i < llTab.getChildCount(); i++) {
			llTab.getChildAt(i).setOnClickListener(this);
		}
	}

	@Override
	public Fragment getItem(int position) {

		// Fragment fragment = new DummySectionFragment();
		// Bundle args = new Bundle();
		// args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position +
		// 1);
		// fragment.setArguments(args);

		return fragmentsList.get(position);
	}

	@Override
	public int getCount() {
		return fragmentsList.size();
	}

	// ******************OnPageChangeListener***************
	@Override
	public void onPageScrollStateChanged(int state) {
		System.out.println("onPageScrollStateChanged:" + state);
	}

	@Override
	public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
		System.out.println("onPageScrolled:" + position + ">>" + positionOffset + ">>" + positionOffsetPixels);
	}

	@Override
	public void onPageSelected(int position) {
		System.out.println("onPageSelected:" + position);
		for (int i = 0; i < llTab.getChildCount(); i++) {
			if (position == i) {
				llTab.getChildAt(i).setBackgroundResource(R.drawable.bg_view_pager_scroll_selected);
			} else {
				llTab.getChildAt(i).setBackgroundResource(R.drawable.bg_view_pager_scroll_unselect);
			}
		}
	}

	// ******************OnPageChangeListener***************

	@Override
	public void onClick(View view) {
		for (int i = 0; i < llTab.getChildCount(); i++) {
			if (view.equals(llTab.getChildAt(i))) {
				llTab.getChildAt(i).setBackgroundResource(R.drawable.bg_view_pager_scroll_selected);
				viewPager.setCurrentItem(i);
			} else {
				llTab.getChildAt(i).setBackgroundResource(R.drawable.bg_view_pager_scroll_unselect);
			}
		}
	}
}
c、CustomViewManager.java

package com.ttdevs.customviewpager.custom;

import android.content.Context;
import android.graphics.Color;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.WindowManager.LayoutParams;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.ttdevs.customviewpager.R;

public class CustomViewManager {
	private Context context;
	private LinearLayout llCustomTabView, llTab;
	private ViewPager viewPager;
	private String[] tags;

	public CustomViewManager(Context context, String[] tags) {
		this.context = context;
		this.tags = tags;
		// 获取全部布局
		llCustomTabView = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.custom_tab_view, null);
		// 拿到存放TAB的布局
		llTab = (LinearLayout) llCustomTabView.findViewById(R.id.llTab);
		viewPager = (ViewPager) llCustomTabView.findViewById(R.id.pager);
		viewPager.setPageMargin(6);
		viewPager.setPageMarginDrawable(android.R.drawable.divider_horizontal_bright);
		
		createCustomView();
	}

	public LinearLayout getCustomTabView() {
		return llCustomTabView;
	}

	public LinearLayout getTabView() {
		return llTab;
	}

	public ViewPager getViewPager() {
		return viewPager;
	}

	private void createCustomView() {
		// 添加TABS
		for (int i = 0; i < tags.length; i++) {
			RelativeLayout tab = new RelativeLayout(context);
			tab.setId(i);
			if (i == 0) {
				tab.setBackgroundResource(R.drawable.bg_view_pager_scroll_selected);
			} else {
				tab.setBackgroundResource(R.drawable.bg_view_pager_scroll_unselect);
			}

			TextView tv = new TextView(context);
			tv.setId(i);
			tv.setTextColor(Color.BLACK);
			tv.setText(tags[i]);

			RelativeLayout.LayoutParams tvlp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
					LayoutParams.WRAP_CONTENT);
			tvlp.addRule(RelativeLayout.CENTER_IN_PARENT);
			tab.addView(tv, tvlp);

			LinearLayout.LayoutParams tablp = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT);
			tablp.weight = 1;
			llTab.addView(tab, tablp);

		}
	}
}


第一次按照自己的需求写一个暂定义为自定义控件的东西吧,竟然一次通过,自己也是很吃惊,以前总要调试几下,小小的激动一下下。细节写的可能不够好,欢迎指教~~



6、下载:

http://download.youkuaiyun.com/detail/ttdevs/6007485


Android ViewPager与ViewPageIndicator实现高效Tab导航 在Android应用开发中,页面滑动切换是提升用户体验的核心交互模式。ViewPager作为AndroidX的核心组件,通过FragmentPagerAdapter实现了页面动态加载与内存管理,配合页面复用机制确保滑动流畅性。ViewPageIndicator则弥补了原生ViewPager缺乏可视化指示器的缺陷,提供Tab样式、圆点等多种导航样式选择。这对组合特别适合需要高度自定义UI的新闻类、电商类应用场景,既能通过ViewPager的BEHAVIOR_RESUME_ONLY_CURRENT_FRAGME 阅读详情

相关推荐

Android滑动切换页面和底部tab点击切换页面的实现

在Android应用程序中,ViewPager是一个常用的组件,它可以实现在多个页面之间的滑动切换。而底部tab是一种常见的导航方式,用户可以通过点击不同的选项卡来切换页面。接下来,在MainActivity的Java代码中,我们可以使用ViewPager和FragmentPagerAdapter来实现页面的滑动切换。在上述代码中,我们为每个Fragment创建了相应的布局文件(fragment_1.xml、fragment_2.xml、fragment_3.xml),并在其中添加了一个TextView。

2301_79326891的博客 668

Android 之 Fragment 精讲 —— 底部导航栏 + ViewPager 滑动切换页面

一个页面切换的组件,我们可以往里面填充多个View,然后我们可以通过触摸屏幕左右滑动 切换不同的View,和前面学习的ListView一样,我们需要一个Adapter(适配器),将要显示的View和 我们的ViewPager进行绑定,而ViewPager有他自己特定的Adapter——PagerAdapter!另外,Google 官方是建议我们使用Fragment来填充ViewPager的,这样可以更加方便的生成每个Page以及管理 每个Page的生命周期!

leyang0910的博客 1613

Android之TabLayout+ViewPager2+FragmentStateAdapter实现带数字变化的TAB选项

1 问题 TabLayout+ViewPager2实现带数字变化的TAB选项,然后左边滑动或者点击上面的Tab切换fragment不能刷新 2 结果爆照 3 代码实现 layer_tab_indicator.xml <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="ht...

码莎拉蒂 5667

viewpager2+tablayout+fragment 实现 滑动 在fragment 设置两个按钮 可以控制左右能不能滑动

自定义viewpager2。activity 代码。

qq_42795723的博客 338

ViewPager2+TabLayout实现左右滚动效果

最近在自学Android应用开发,想实现类似头条的tab左右滚动切换效果,网上找了好多参考案例都没有成功,要不就是代码贴的不全,要不就是使用的代码接口弃用了,要不就是使用的框架不更新了!好在最后搞出来了,就想把代码贴出来,给后来这一个参考(ViewPager有些API已经弃用了推荐使用ViewPager2)。

houyizi337825770的专栏 439

ViewPage2+TabLayout地表超详总结

ViewPager2+TabLayout能够为用户提供更好体验和导航方式。ViewPager2可以让用户通过滑动来浏览不同的页面,TabLayout提供清晰的标签导航。

全栈 1900

ActionBar + ViewPager实现左右滑动切换Tab页效果

废话不多说,先上一张效果图。

wh109310的专栏 1184

实现自定义可滑动的tab选项卡

ViewPager是Android开发中用于页面浏览的一个组件,通常用于实现左右滑动切换页面的场景。它的设计初衷是为了解决在屏幕上展示多个页面内容时用户交互的便利性,使得用户可以通过简单的滑动动作查看相关内容。ViewPager组件常与Fragment结合使用,每个Fragment充当一个页面,通过ViewPager的滑动切换功能可以非常流畅地在各个Fragment之间进行切换。如果你需要实现一些特殊的过渡效果,或者需要更多的自定义控制,可以通过编程的方式来自定义动画。你可以使用或。

weixin_31620365的博客 843

自定义的HorizontalScrollView与Viewpager组成tab之间的滑动

Android现在实现Tab类型的界面方式越来越多,之前做电商项目时,遇见了类似tab与viewpager之间的左右连带滑动,我查了一些资料这种效果是继承自定义的HorizontalScrollView和viewpager完成的,我认为效果蛮好的,也比较简便。效果图:,这里我是禁止了viewpager原生自带的左右滑动,我上传了一个类文件,里面有禁止viewpager左右滑动和自定义的Horizo

悟-静的博客 2523

自定义Android底部Tab栏控件:支持左右滑动切换界面的BottomTabBar实战

在现代Android应用的UI架构中,底部导航已成为用户交互的核心组件之一。随着移动应用功能日益复杂,用户对界面流畅性、可操作性和视觉体验的要求不断提升。传统的底部导航方案虽能满足基本需求,但在灵活性和交互体验上逐渐显现出局限。graph LRA[原生BottomNavigationView] -->|仅支持点击| B(交互单一)C[主流App实践] -->|微信/抖音: 滑动+点击| D(手势丰富)B --> E[用户体验瓶颈]D --> F[BottomTabBar诞生]

weixin_35756637的博客 1421

自定义的带tab的可左右滑动的viewpager

自定义的带tab的可左右滑动的viewpager 文章来源:http://blog.youkuaiyun.com/ttdevs/article/details/10296277

ViewPager+Fragment实现Tab主界面

毕竟是第一次做项目,所以在每一点上都做得特别认真,接下来我来给大家大致讲述一下用ViewPager+Fragment来实现app Tab主界面,突然想起来LZ居然2天没去上课了......(>.... package com.bob.tabui; import android.support.v4.app.*; import android.os.Bundle; import android.

My life,my way 6526

Comsol单层焊缝焊接数值模拟:温度场与应力场全流程解析

在工程制造领域,有限元模拟是研究焊接热-力行为、优化工艺参数的重要工具。焊接过程涉及强烈的局部加热和快速冷却,材料经历复杂的非线性和相变,必须通过瞬态分析和热-力顺序耦合,才能准确捕捉移动热源作用下的温度演化与应力塑性积累。这一技术广泛应用于压力容器、船舶结构、车辆制造等场景,用以预测残余应力与变形、评估冷裂纹风险,并为工艺设计提供定量支撑。焊接数值模拟能否真正指导实践,关键在于热源校核、随温度变化的材料参数、合理的边界条件与网格策略。单层焊缝作为焊接模拟的基础模型,涵盖了移动热源加载、熔池形成、高温软化与

weixin_30444111的博客 225

Android ViewPager与ViewPageIndicator实现Tab导航详解

在Android开发中,Fragment与ViewPager的组合是实现分页导航的核心技术方案。ViewPager通过预加载机制优化页面切换性能,配合FragmentPagerAdapter实现动态内容加载。这种架构特别适合新闻类App的顶部Tab导航场景,既能保证流畅的手势滑动体验,又能灵活定制指示器样式。ViewPageIndicator作为经典扩展库,提供了标题高亮、下划线动画等丰富的交互效果,其原理是通过重写onDraw方法实现自定义绘制。对于需要复杂动效的项目,可以基于ViewPager2生态进行

weixin_34372728的博客 448

量化交易python代码解析:从狙击手算法到最优限价算法

在金融市场的竞技场上,量化交易如同一位冷静的策略大师,它以数学模型为剑,以计算机程序为盾,精准出击,捕捉市场的微妙波动。本文将深入探讨五种核心量化交易算法:直接委托算法(DMA)、时间加权平均算法(TWAP)、冰山算法(Iceberg)、狙击手算法(Sniper)、条件委托算法(Stop)以及最优限价算法(BestLimit),揭开它们背后的运作机制与实战应用。

木头大左的博客 1892

《四》:LBE,VR 大空间系列——Pico的空间扫描方式

(这里有个选项叫高精度扫描模式,这个功能在下方详细补充)系统会根据绘制的顶点,将区域分割成若干个4X4米的小方格,我们只需要根据提示,首先进入一个方格子空间内部,然后依次凝视每个区域上下左右前后六个面的小方格组,每一面4个,直至全部消失, 消失后地面会出现一个方形行走路径,我们沿着边缘正或反走一圈即可,完成后此块区域即自动消失。不过由于pico有一个高精度扫描圈,如图加粗的圆环,这个圆环的意思是在在内部的区域扫描精度较高,越远离原点的区域误差越大,所以为了更有效的利用,建议原点设置在场地中心区域。

unitygroup的博客 2888

使用ViewPager和FragmentPagerAdapter实现Tab

前面我们分别利用ViewPager和Fragment实现了Tab效果。但是使用Fragment实现的Tab不能够左右滑动。如果我们既想使用Fragment又想让Tab能够滑动,那么怎么办呢?这 就是今天的方法,利用ViewPager和FragmentPagerAdapter来实现Tab。 没看过前两篇文章的读者可以点击下面的地址: http://www.cnb...

bai8005的博客 177

【以太网硬件一】802.3xx标准怎么这么多?它们有什么关系?

IEEE 802.3标准发展历史简介

highman110的博客 5018

ViewPager实现移折通左右滑动引导界面

得到的          实现左右滑动界面的方法有很多种,如以下几种实现方法。     第一、android第三方控件ViewPager实现。     第二、android的ViewFlipper组件实现。     天本文将详细介绍怎样利用第三方控件Viewpager实现移折通欢迎界面,ViewFlipper将在我的其他博文详细介绍。首先,看下效果图: 然后,看下Viewpager在

hrx3627的专栏 3524

ETAS工具导入DBC生成Com协议栈

ETAS工具导入DBC主要也是生成arxml用的,ETAS推荐使用Cobra导入,本文介绍导入过程及注意事项不管是导入DBC还是arxml,本质上都是为了生成对应的com协议栈,目的是为了减少重复的工作量,所以,前期定义好收发的矩阵很重要,一般导入一次之后,后面就可以按变更点手动更改了。

赞的博客 1714

华为OD机试真题 新系统2026-04-08 C++ 实现【直捣黄龙】

小王在玩一款叫做直捣黄龙的小游戏,在该游戏中他需要从入口位置进入敌营,绕过哨兵的层层封锁,达到敌军司令部实施斩首行动。 敌军阵营是一个n*n的矩阵,入口在坐标(0,n/2),敌军司令部在坐标(n-1,n/2),每个 哨兵警戒以自己为中心的9宫格,一旦被哨兵发现则行动失败。

MISAYAONE的博客 263

禁止viewpager左右滑动

package com.example.xinenhuadaka.view; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import androidx.viewpager.widget.ViewPager; //禁止左右滑动的viewpager public class NoScrollViewPager extends ViewPager { .

qq_41985689的博客 1244

Xilinx FPGA平台DDR3设计保姆式教程(3)MIG IP核使用教程及DDR读写时序

干货来了,用DDR搬砖,只需要会用IP就好,Xilinx官方YYDS! ----------------------------------------------------------------------------------------------------------------- 汇总篇: Xilinx平台DDR3设计保姆式教程(汇总篇)——看这一篇就够了 ----------------------------------------------------------...

数字IC/FPGA杂货铺,找一找,或许有你想要的~ 2万+

ActionBar(5) ActionBar+ViewPager+PagerTitleStrip 实现可左右滑动的Tab页布局

ActionBar除了可以本身定制VIEW外,还可以利用ActionBar+ViewPager+Fragment 实现一些好用的效果。 如本次要说的可左右滑动的Tab页布局。     可左右滑动的Tab页布局的好处在于,用单手左右滑动操作即可,而无须去点击切换Tab页。  要实现可于   PagerTitleStrip 用于显示Tab页标题 具体可查: http://developer

拙言的专栏 6570

2022中山大学计算机技术专硕考研初试、复试经验帖

个人简介 推荐几个我自己感觉对考研非常有帮助的小助手吧。可以帮助节省时间! 考研时间规划总览 初试篇 数学 英语 政治 408 复试篇 机试 笔试 面试 关于选导师 个人感言

zik的博客 1万+

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

上一篇: PreferenceFragment的简单使用
下一篇: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an appli
ttdevs
博客等级 码龄15年 388粉丝 91原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值