Android自定义ViewPager指示器
作者:z240336124 发布时间:2023-11-29 03:30:31
标签:Android,ViewPager,指示器
本文实例为大家分享了Android ViewPager指示器的制作方法,供大家参考,具体内容如下
1.概述
ViewPageIndicator这个开源框架大家都接触过,个人感觉还不错就是用起来比较麻烦,需要这里配置那里配置效果定制起来也不方便。我第一次使用的时候就一直出不来效果,后来找了很久发现是activity的主题没有配置好。今天我们自己来造个轮子实现一把,其中用到了Adapter模式,如果不清楚这个模式的请看我的Android源码设计模式分析:https://www.jb51.net/article/96291.htm,下面看一下效果:
2.实现
1).实现基本效果自定义HorizontalScrollView extends HorizontalScrollView,设置ViewPager根据个数不断遍历添加子View。
public class ViewPagerIndicator extends HorizontalScrollView{
public ViewPagerIndicator(Context context) {
this(context, null);
}
public ViewPagerIndicator(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ViewPagerIndicator(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext = context;
}
@Override
public void setViewPager(ViewPager viewPager) {
if (viewPager == null) {
throw new NullPointerException("viewPager is null...");
}
this.mViewPager = viewPager;
int count = mViewPager.getAdapter().getCount();
mContanierGroup.removeAllViews();
// 循环添加tabView(TextView)
for (int i = 0; i < count; i++) {
final TextView itemTv = new TextView(mContext);
itemTv.setText(this.mViewPager.getAdapter().getPageTitle(i));
setItemClickEvent(itemTv, i);
mContanierGroup.addTabView(itemTv);
setItemClickEvent(itemTv, i);
mContanierGroup.addTabView(itemTv);
}
setItemParams();
mAdapter.highLightTabView(mContanierGroup.getTabView(mCureentItem));
this.mViewPager.setOnPageChangeListener(this);
}
private void setItemParams() {
if (mVisibleTabCount != 0) {
final int childCount = mViewPager.getAdapter().getCount();
mRunnable = new Runnable() {
@Override
public void run() {
int tabWidth = getWidth() / mVisibleTabCount;
// 循环遍历设置Tab宽度
for (int index = 0; index < childCount; index++) {
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mContanierGroup
.getTabView(index).getLayoutParams();
params.width = tabWidth;
}
// 设置宽度,高度,和角标指示器
mContanierGroup.setTabWidth(tabWidth);
mContanierGroup.getContainer().getLayoutParams().height = getHeight();
mContanierGroup.setIndicatorView(mAdapter.getIndexView());
mRunnable = null;
}
};
post(mRunnable);
}
}
}
2).设置ViewPager的滚动监听,使ViewPager和TabView一起联动
@Override
public void onPageScrollStateChanged(int position) {
if (position == 0) {
// 设置为不是点击
mIsClick = false;
}
if (mPageChangeListener != null)
mPageChangeListener.onPageScrollStateChanged(position);
}
@Override
public void onPageScrolled(int position, float offset, int arg2) {
scroll(position, offset);
if (mPageChangeListener != null)
mPageChangeListener.onPageScrolled(position, offset, arg2);
}
@Override
public void onPageSelected(int position) {
mCureentItem = position;
if (mPageChangeListener != null)
mPageChangeListener.onPageSelected(position);
}
/**
* 指示器跟随手指进行滚动
*/
public void scroll(int position, float offset) {
int tabWidth = mContanierGroup.getTabView(0).getWidth();
// 让选中Tab的一直在最中间
int total = (int) ((position + offset) * tabWidth);
int green = (getWidth() - tabWidth) / 2;
// 滚动的距离
int scroll = total - green;
if (!mIsClick) {
this.scrollTo(scroll, 0);
mContanierGroup.scrollIndicator(position, offset);
}
}
3).最后我们采用适配器Adapter模式,完成高亮和下标指示器。
public abstract class IndicatorAdapter<T extends View> {
/**
* 获取Tab View
*/
public abstract T getTabView(int position);
/**
* 获取角标View
*/
public View getIndexView() {
return null;
}
/**
* 高亮当前Tab
*/
public void highLightTabView(T tabView) {
}
/**
* 恢复当前Tab
*/
public void restoreTabView(T tabView) {
}
}
4).最后我们来看在activity中怎么使用,在IndicatorAdapter有四个方法,我们只需要实现一个方法,其余三个方法如果不使用可以不复写。以Adapter的形式暴露出来,那么用户可以自己去实现而不必受局限。
mIndicator.setAdapter(mViewpager, new IndicatorAdapter<TextView>() {
@Override
public TextView getTabView(int position) {
TextView tabView = new TextView(getBaseContext());
tabView.setTextColor(Color.WHITE);
tabView.setText(mTitles.get(position));
tabView.setPadding(20, 20, 20, 20);
tabView.setGravity(Gravity.CENTER);
return tabView;
}
@Override
public View getIndexView() {
ImageView view = new ImageView(getBaseContext());
view.setImageResource(R.drawable.corners_login_nomral);
view.setPadding(25, 0, 25, 0);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, 6);
view.setLayoutParams(params);
return view;
}
@Override
public void highLightTabView(TextView tabView) {
final TextView itemView = (TextView) tabView;
itemView.setTextColor(Color.RED);
}
@Override
public void restoreTabView(TextView tabView) {
final TextView itemView = (TextView) tabView;
itemView.setTextColor(Color.WHITE);
}
});
不需配置的ViewPagerIndicator 的源码下载:http://xiazai.jb51.net/201611/yuanma/AndroidViewPager(jb51.net).rar
0
投稿
猜你喜欢
- 本篇实例内容是关于C#读取CAD文件的,直接看代码//在不使用任务插件的情况下读取DWG文件的缩略图,以便在没有安装AutoCAD的计算机上
- 本文实例讲述了Android编程之分辨率处理相关代码段。分享给大家供大家参考,具体如下:1. 通常我们所说的屏幕分辨率如800x480、96
- MyBatis-plus模糊查询在使用MyBatis-plus的时候,一些基础的增删改查可以不用再自己写sql了:public interf
- 本文实例为大家分享了C# SqlHelper应用技巧,供大家参考,具体内容如下使用App.config配置文件封装连接字符串,方便重复使用-
- 本文实例讲述了Java实现的3des加密解密工具类。分享给大家供大家参考,具体如下:package com.gcloud.common;im
- 将IDEA的默认快捷键设置 设置成为 Eclipse的默认快捷键设置题意有些拗口,但没关系,就是将idea中的快捷键转为自己刚学Java时使
- 本文实例为大家分享了Java基于Socket实现简易版多人聊天室的具体代码,供大家参考,具体内容如下一、 聊天室需求1、一个服务端,多个客户
- 示例代码:class BoxIntInteger {public static void main(String[] args) {Inte
- 本文实例讲述了在C#中实现多线程中调用winform窗体控件的方法,对于C#程序设计的学习有着很好的借鉴参考价值。具体方法如下:首先,由于W
- 1.首先,八种基本数据类型分别是:int、short、float、double、long、boolean、byte、char; &
- 先看MVC模式流程图(其实MVC设计模式就是java中的model2。): &nb
- 本文实例讲述了C#事件用法。分享给大家供大家参考。具体分析如下:EventHandler<TEventArgs>的定义如下pub
- Java线程池并发执行多个任务Java在语言层面提供了多线程的支持,线程池能够避免频繁的线程创建和销毁的开销,因此很多时候在项目当中我们是使
- 本文实例讲述了Aspectj框架。分享给大家供大家参考,具体如下:一 环境变量配置CLASSPATH配置为:.;d:\aspectj1.8\
- 我们先来了解一下数组,因为数组在C#中是最早出现的。数组数组有很多的优点,比如说数组在内存中是连续存储的,所以它的索引速度是非常的快,而且赋
- 本文实例讲述了C#解决SQlite并发异常问题的方法。分享给大家供大家参考,具体如下:使用C#访问sqlite时,常会遇到多线程并发导致SQ
- 一、内容实操实现APP门户界面框架设计,至少包含4个tab页,能实现tab页之间的点击切换二、技术使用布局(layouts)和分段(frag
- 首先,良好的编码规范非常重要。在 java 程序中,访问速度、资源紧张等问题的大部分原因,都是代码不规范造成的。单例的使用场景单例模式对于减
- 这是本人大一第二学期初C语言课程设计的作品,嘿嘿,本来以为已经找不到原稿了,今天无意中竟然在QQ网络硬盘中找到了当初的teta版,发布于此,
- Java继承方法重写是Java语言多态的特性,必须满足以下条件在子类中,方法名称与父类方法名称完全相同方法的参数个数和类型完全相同,返回类型