自定义ViewPagerIndicator
1. 简介
学习Android,自定义View不可避免,之前一直忽视这块内容,现在开始学,应该不算太晚。从常见的ViewPagerIndicator开始,当然,万能的Github上包罗万象,好用的indicator也是不胜枚举,旨在学习自定义View的一般操作过程。
2. 大致思路
做一个简单的ViewPagerIndicator,只支持平均大小的TextView,支持点,矩形和三角形。
1. 使用LinearLayout作为父类;
2. 定义indicator的颜色,高度和半径,当然也可以定义其他的属性;
3. 使用到Path,Paint,Canvas等图形绘制的内容;
4. 使用Kotlin
3. 实现
以圆形indicator为例
3.1 定义自定义属性
styles.xml
<attr name="y_indicator_color" format="color"/>
<attr name="y_indicator_radius" format="dimension"/>
<declare-styleable name="YVPDotIndicator">
<attr name="y_indicator_color"/>
<attr name="y_indicator_radius"/>
</declare-styleable>
3.2 代码实现
通过设置ViewPager,然后从Adapter的getPageTitle方法获取TextView的显示内容,然后添加标签,然后绘制圆形指示器,通过ViewPager的滑动回调方法,设置圆形指示器的位置。
class YVPDotIndicator : LinearLayout {
private var mStartPos: Float = 0.0F//indicator开始位置
private var mWidthOffset: Int = 0//初始offset
private var mPaint: Paint? = null
private var mIndicatorColor = Color.parseColor("#FFFFFF")//indicator颜色
private var mIndicatorRadius = 2//圆形indicator半径
private var mVp: ViewPager? = null
private var pageListener = InterPageChangeListener()
private var mTabCount: Int? = 0
private var mTabWidth: Float? = 0.0F
private val defaultLayoutParams = LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f)
constructor(context: Context, attrs: AttributeSet) : this(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
setWillNotDraw(false)
val dm = resources.displayMetrics
val a = context.theme.obtainStyledAttributes(attrs, R.styleable.YVPDotIndicator, defStyle, 0)
mIndicatorRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mIndicatorRadius.toFloat(), dm).toInt()
mIndicatorColor = a.getColor(R.styleable.YVPDotIndicator_y_indicator_color, Color.parseColor("#FFFFFF"))
mIndicatorRadius = a.getDimensionPixelSize(R.styleable.YVPDotIndicator_y_indicator_radius, 2)
a.recycle()
initPaint()
}
/**
* 设置ViewPager
*/
fun setViewPager(vp: ViewPager) {
mVp = vp
if (vp.adapter == null) {
throw IllegalArgumentException()
}
notifyDataSetChanged()
mVp?.addOnPageChangeListener(pageListener)
}
fun notifyDataSetChanged() {
this.removeAllViews()
mTabCount = mVp?.adapter?.count
for (i in 0..mTabCount?.let { it - 1 } as Int) {
addTextTab(i, mVp?.adapter?.getPageTitle(i).toString())
}
}
fun addTextTab(position: Int, title: String) {
var tab = TextView(context)
tab.text = title
tab.gravity = Gravity.CENTER
tab.setSingleLine()
tab.isFocusable = true
tab.setOnClickListener { mVp?.currentItem = position }
this.addView(tab, position, defaultLayoutParams)
}
/**
* 初始化画笔
*/
private fun initPaint() {
mPaint = Paint()
mPaint?.color = mIndicatorColor
mPaint?.isAntiAlias = true
mPaint?.style = Paint.Style.FILL
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
mTabWidth = (w / childCount).toFloat()
mStartPos = mTabWidth?.let { it/2 } as Float
}
override fun dispatchDraw(canvas: Canvas?) {
canvas?.save()
canvas?.translate(0.0F, height.toFloat())
canvas?.drawCircle(mStartPos + mWidthOffset, -mIndicatorRadius.toFloat(), mIndicatorRadius.toFloat(), mPaint)
canvas?.restore()
super.dispatchDraw(canvas)
}
inner class InterPageChangeListener: ViewPager.OnPageChangeListener {
override fun onPageScrollStateChanged(state: Int) {
}
override fun onPageSelected(position: Int) {
}
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
val tabWidth = screenWidth / childCount
mWidthOffset = (tabWidth * position + tabWidth * positionOffset).toInt()
invalidate()
}
}
/**
* 获取屏幕宽度
* @return
*/
private val screenWidth: Int
get() {
val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
val displayMetrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(displayMetrics)
return displayMetrics.widthPixels
}
}
4. 其他Indicator
类似的矩形指示器和三角形指示器,均可按照上面的方式实现。
5. 具体效果
6. 示例源码
请移步Github———-YVPIndicator
自定义ViewPagerIndicator的更多相关文章
- Android 教你打造炫酷的ViewPagerIndicator 不仅仅是高仿MIUI
1.概述 哈,今天给大家带来一个ViewPagerIndicator的制作,相信大家在做tabIndicator的时候,大多数人都用过 TabPageIndicator,并且很多知名APP都使用过这个 ...
- 使用TabPageIndicator的样式问题
在使用TabPageIndicator往往会出现一些样式问题,导致看不到字,下面是总结的步骤: 1.布局<LinearLayout xmlns:android="http://sche ...
- Android之实现ViewPagerIndicator
PS:最近一直忙于学习任务,一直没有时间去写博客.今天周六,终于有时间了. 学习任务: 1.打造一个自己的ViewPagerIndicator 最近被安排了一大堆的学习任务,感觉老板还是很好的,让 ...
- 老猪带你玩转android自定义控件一——打造最简单viewpagerindicator
viewpagerindicator,既使用viewpager翻页时候,标题的指示条随着改变的控件,是常用android控件之一,几乎所有的新闻类APP中都有使用.如下图所示: 今天,我们将从0到1实 ...
- PagerTabStrip及自定义的PagerTab
如图是效果图 开发中经常会用到上面是一个Tab下面是一个ViewPager(ViewPager再包含几个Fragment),当点击Tab或是滑动ViewPager,Tab及ViewPager ...
- Android 使用Fragment,ViewPagerIndicator 制作csdn app主要框架
转载 转载请注明出处:http://blog.csdn.net/lmj623565791/article/details/23513993 本来准备下载个CSDN的客户端放手机上,没事可以浏览浏览资 ...
- android123 zhihuibeijing 新闻中心-新闻 页签 ViewPagerIndicator实现
## ViewPagerIndicator ## 使用导入ViewPagerIndicator库的方式相当于可以改源码,打包编译Eclips可以自动完成. ViewPager指针项目,在使用ViewP ...
- ViewPagerindicator 源码解析
ViewPagerindicator 源码解析 1. 功能介绍 1.1 ViewPagerIndicator ViewPagerIndicator用于各种基于AndroidSupportL ...
- 开源控件ViewPagerIndicator的使用
此文转载自http://www.jianshu.com/p/a2263ee3e7c3 前几天学习了ViewPager作为引导页和Tab的使用方法.后来也有根据不同的使用情况改用Fragment作为Ta ...
随机推荐
- java8工具类使用
1:map的使用 computeIfPresent ,如果键已经存在,将键和值作为参数传到函数式中,计算返回新的值 import java.util.HashMap; import java.util ...
- 两个栈实现队列&两个栈实现队列
为说明思想,假设队列.栈都很大,不会出现满的情况. 1. 两个栈实现队列 //前提已知: struct Stack { int top; //栈顶指针 int stacksize;//栈的大小 int ...
- malloc calloc realloc 区别
(1)C语言跟内存分配方式 <1>从静态存储区域分配. 内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量.static变量.<2> ...
- JPA Spring Data 概述
JPA Spring Data : 致力于减少数据访问层 (DAO) 的开发量. 开发者唯一要做的,就只是声明持久层的接口,其他都交给 Spring Data JPA 来帮你完成! 框架怎么可能代替开 ...
- vim多行注释和取消注释 Ubuntu
多行注释: 1. 进入命令行模式,按ctrl + v进入 visual block模式,然后按d 是选择到最后一行,也可以直接光标上下左右,把需要注释的行标记起来 2. 按大写字母I,再插入注释符,例 ...
- jquery实现ajax跨域请求
1.跨域问题: 是因为浏览器的同源策略是对ajax请求进行阻拦了,但是不是所有的请求都给做跨域,像是一般的href属性,a标签什么的都不拦截. 如: 项目一:p1.html <body> ...
- linux sar命令详解及使用
sar(System Activity Reporter系统活动情况报告)是目前 Linux 上最为全面的系统性能分析工具之一,可以从多方面对系统的活动进行报告,包括:文件的读写情况.系统调用的使用情 ...
- 【知识总结】Java类初始化顺序说明
微信公众号:努力编程的小猪如有问题或建议,请公众号留言 Java类初始化顺序说明 一个类中包含如下几类东西,他们前后是有顺序关系的 静态属性:static 开头定义的属性 静态方法块: static ...
- java第六天
p37 1.java ant详解 练习8 /** * Created by xkfx on 2017/2/26. */ class A { static int i = 47; } public cl ...
- maven nexus私服搭建
1. 下载 wget http://download.sonatype.com/nexus/oss/nexus-2.12.0-01-bundle.tar.gz 2. 解压 tar zxvf nexus ...