###1.概述


最近一直都在仿着其他项目的效果在做,仿内涵段子,二手车之家等等。会不会有一天被抓还真是有点心虚,我这分明是给这些APP打广告。等这些效果基本讲完就开始设计模式和系统框架一整套的视频也就会出来了,等总的访问量达到100万之后就会利用空余的时间去录制Java基础和Android基础,请各位多多start和suggest。我们来看一下效果:      

###2.效果实现


2.1 整合上一个实例:

底部Fragment切换以及列表加轮播条都是从上一篇博客Android Fragment 从源码的角度去解析(下)中直接拿过来的效果,我们这里主要实现的是首页ViewPager指示器的变色效果以及切换效果。   其实我早就想写这个效果了,可能是那时候脑子短路了没有去过多的想,后来自己想到了实现方式也没有去写怕绕弯子在网上对比了一下才开始的,那么我们就彻底的来实现一下。    2.2 实现思路:

我们看到这效果之后,就会尼玛网上有没有?不要害怕不要担心其实分析了之后自己写也很简单的:   2.2.1 我们肯定要自定义View但是继承自谁呢?View or TextView 其实这里最好继承自TextView,这分明就是一个TextView,而且不需要测量宽高,你看TextView的onMesure()方法你就知道要比继承自View少多少代码。   2.2.2 怎样才能达到变色?肯定需要去绘制,只要搞两个画笔不断的绘制各自的区域就能出来。   2.2.3 还是不会,但是得动起来才知道,我们先实现一个TextView两种颜色再说。

2.3 实现两种颜色的TextView:   我们先实现一下简单的效果一个TextView两种颜色,黑色和红色吧?大致的思路就是:   2.3.1 根据当前的进度为了演示效果我就默认为0.6f,那么中间的分割位置就是0.6f*控件的宽度   2.3.2 在onDraw()中我们利用计算好的分割位置自己去绘制文字,裁剪绘制内容部分即可   2.3.3 画文字是canvas.drawText(String text, float x, float y, Paint paint) 这些参数不了解的你得自己去google看一下了,温馨提示参数y是文字的基线,给一张图片看看吧:   

/*** Created by Darren on 2016/12/5.* Email: 240336124@qq.com* Description:  文字颜色跟踪的TextView*/public class ColorTrackTextView extends TextView {// 默认的字体颜色的画笔private Paint mOriginPaint;// 改变的字体颜色的画笔private Paint mChangePaint;// 当前的进度private float mCurrentProgress = 0.6f;private String TAG = "CTTV";// 当前文本private String mText;public ColorTrackTextView(Context context) {this(context, null);}public ColorTrackTextView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public ColorTrackTextView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initPaint();}/*** 初始化画笔*/private void initPaint() {mOriginPaint = getPaintByColor(Color.BLACK);mChangePaint = getPaintByColor(Color.RED);}/*** 获取画笔根据不同的颜色*/private Paint getPaintByColor(int color) {Paint paint = new Paint();// 抗锯齿paint.setAntiAlias(true);// 仿抖动paint.setDither(true);paint.setColor(color);// 字体的大小设置为TextView的文字大小paint.setTextSize(getTextSize());return paint;}/*** 这里肯定是自己去画  不能用super*/@Overrideprotected void onDraw(Canvas canvas) {// 获取当前文本mText = getText().toString();// 获取控件宽度int width = getWidth();if (!TextUtils.isEmpty(mText)) {// 根据当前进度计算中间位置int middle = (int) (width * mCurrentProgress);drawOrigin(canvas, middle);drawChange(canvas, middle);}}/*** 画变色的字体部分*/private void drawChange(Canvas canvas, int middle) {drawText(canvas, mChangePaint, 0, middle);}/*** 画不变色的字体部分*/private void drawOrigin(Canvas canvas, int middle) {drawText(canvas, mOriginPaint, middle, getWidth());}/*** 绘制文本根据指定的位置** @param canvas canvas画布* @param paint  画笔* @param startX 开始的位置* @param endX   结束的位置*/private void drawText(Canvas canvas, Paint paint, int startX, int endX) {// 保存画笔状态canvas.save();// 截取绘制的内容,待会就只会绘制clipRect设置的参数部分canvas.clipRect(startX, 0, endX, getHeight());// 获取文字的范围Rect bounds = new Rect();mOriginPaint.getTextBounds(mText, 0, mText.length(), bounds);// 获取文字的Metrics 用来计算基线Paint.FontMetricsInt fontMetrics = mOriginPaint.getFontMetricsInt();// 获取文字的宽高int fontTotalHeight = fontMetrics.bottom - fontMetrics.top;// 计算基线到中心点的位置int offY = fontTotalHeight / 2 - fontMetrics.bottom;// 计算基线位置int baseline = (getMeasuredHeight() + fontTotalHeight) / 2 - offY;canvas.drawText(mText, getMeasuredWidth() / 2 - bounds.width() / 2, baseline, paint);// 释放画笔状态canvas.restore();}
}
复制代码

看上面的代码其实还是挺简单的,我截取了一张效果图   

2.4 实现左右不同方向不断变色:      当一个TextView有了两种文字颜色之后,我们接下来就不断的控制当前的进度mCurrentProgress变量不断的绘制然后给两个朝向从左到右,从右到左,还把写死的两个颜色值变成自定义的属性,自定义属性应该不用说了吧?如果实在不行等周末看视频吧,这里就不做过多的讲解。我这里只贴出修改部分代码,如果觉得有点扯那就下载完整代码吧:

    // 当前朝向private Direction mDirection = DIRECTION_LEFT;// 绘制的朝向枚举public enum Direction {DIRECTION_LEFT, DIRECTION_RIGHT}@Overrideprotected void onDraw(Canvas canvas) {// 获取当前文本mText = getText().toString();// 获取控件宽度int width = getWidth();if (!TextUtils.isEmpty(mText)) {// 根据当前进度计算中间位置int middle = (int) (width * mCurrentProgress);// 根据不同的朝向去画字体if (mDirection == DIRECTION_LEFT) {drawOriginDirectionLeft(canvas, middle);drawChangeDirectionLeft(canvas, middle);}if (mDirection == DIRECTION_RIGHT) {drawOriginDirectionRight(canvas, middle);drawChangeDirectionRight(canvas, middle);}}}/*** 画朝向右边变色字体*/private void drawChangeDirectionRight(Canvas canvas, int middle) {drawText(canvas, mChangePaint, getWidth() - middle, getWidth());}/*** 画朝向左边默认色字体*/private void drawOriginDirectionRight(Canvas canvas, int middle) {drawText(canvas, mOriginPaint, 0, getWidth() - middle);}/*** 画朝向左边变色字体*/private void drawChangeDirectionLeft(Canvas canvas, int middle) {drawText(canvas, mChangePaint, 0, middle);}/*** 画朝向左边默认色字体*/private void drawOriginDirectionLeft(Canvas canvas, int middle) {drawText(canvas, mOriginPaint, middle, getWidth());}/*** 设置当前的进度** @param currentProgress 当前进度*/public void setCurrentProgress(float currentProgress) {this.mCurrentProgress = currentProgress;// 重新绘制invalidate();}/*** 设置绘制方向,从右到左或者从左到右** @param direction 绘制方向*/public void setDirection(Direction direction) {this.mDirection = direction;}
复制代码

接下来我们写一个主Activity做一下测试:

 public class MainActivity extends AppCompatActivity {private ColorTrackTextView mCttv;private String TAG = "MainActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mCttv = (ColorTrackTextView) findViewById(R.id.tv);}// onClick事件写在了不居中  --> android:onClick="left"public void left(View view) {// 设置朝向mCttv.setDirection(ColorTrackTextView.Direction.DIRECTION_LEFT);// 用属性动画来控制,当然也可以用线程去控制ObjectAnimator animator = ObjectAnimator.ofFloat(mCttv, "progress", 0, 1);animator.setDuration(2000).start();// 添加动画的监听,不断的改变当前的进度animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {float progress = (float) animation.getAnimatedValue();Log.e(TAG, "progress --> " + progress);mCttv.setCurrentProgress(progress);}});}// 这与上面类似,只是朝向不一样public void right(View view) {mCttv.setDirection(ColorTrackTextView.Direction.DIRECTION_RIGHT);ObjectAnimator animator = ObjectAnimator.ofFloat(mCttv, "progress", 0, 1);animator.setDuration(2000).start();animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {float progress = (float) animation.getAnimatedValue();Log.e(TAG, "progress --> " + progress);mCttv.setCurrentProgress(progress);}});}
}
复制代码

终极效果:   

2.5 结合ViewPager:

public class MainActivity extends AppCompatActivity {private String[] items = {"直播", "推荐", "视频", "图片", "段子", "精华"};private LinearLayout mIndicatorContainer;private List<ColorTrackTextView> mIndicators;private ViewPager mViewPager;private String TAG = "ViewPagerActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_view_pager);mIndicators = new ArrayList<>();mIndicatorContainer = (LinearLayout) findViewById(R.id.indicator_view);mViewPager = (ViewPager) findViewById(R.id.view_pager);initIndicator();initViewPager();}/*** 初始化ViewPager*/private void initViewPager() {mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {@Overridepublic Fragment getItem(int position) {return ItemFragment.newInstance(items[position]);}@Overridepublic int getCount() {return items.length;}@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {}});/*** 添加一个切换的监听那个setOnPageChangeListener过时了* 这个看源码去吧*/mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {Log.e(TAG, "position --> " + position + " positionOffset --> " + positionOffset);if (positionOffset > 0) {// 获取左边ColorTrackTextView left = mIndicators.get(position);// 设置朝向left.setDirection(ColorTrackTextView.Direction.DIRECTION_RIGHT);// 设置进度  positionOffset 是从 0 一直变化到 1 不信可以看打印left.setCurrentProgress(1-positionOffset);// 获取右边ColorTrackTextView right = mIndicators.get(position + 1);right.setDirection(ColorTrackTextView.Direction.DIRECTION_LEFT);right.setCurrentProgress(positionOffset);}}});// 默认一进入就选中第一个ColorTrackTextView left = mIndicators.get(0);left.setDirection(ColorTrackTextView.Direction.DIRECTION_RIGHT);left.setCurrentProgress(1);}/*** 初始化可变色的指示器*/private void initIndicator() {for (int i = 0; i < items.length; i++) {// 动态添加颜色跟踪的TextViewLinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);params.weight = 1;ColorTrackTextView colorTrackTextView = new ColorTrackTextView(this);// 设置两种颜色colorTrackTextView.setOriginColor(Color.BLACK);colorTrackTextView.setChangeColor(Color.RED);colorTrackTextView.setText(items[i]);colorTrackTextView.setLayoutParams(params);// 把新的加入LinearLayout容器mIndicatorContainer.addView(colorTrackTextView);// 加入集合mIndicators.add(colorTrackTextView);}}
}复制代码

到目前为止应该还是挺简单的,就是变个色而已,有一个棘手的问题就是目前用的指示器是用的LinearLayout。我们可以去网上找一个ViewPagerIndicator的源码测试一下,但是我觉得不是特别好用配置很麻烦,所以决定采用Adapter适配器模式自己造一个轮子。其实自己早期写过一篇,下载的人还有蛮多,可是代码有问题,所以还是录一期视频吧,有问题大家可以自己改一下。

附视频地址:http://pan.baidu.com/s/1jI9PgUE

打造炫酷通用的ViewPager指示器 玩转字体变色相关推荐

  1. 打造炫酷通用的ViewPager指示器 Adapter模式适配所有 1

    ###1.概述 上一期我们已经写了一篇 打造炫酷通用的ViewPager指示器 - 玩转字体变色 可是这种效果虽然绚烂可以装装A和C之间,但是在实际的大多数效果中并不常见,只是在内涵段子中有这个效果而 ...

  2. android 打造炫酷导航栏(仿UC头条)

    年后开始上班甚是清闲,所以想捣鼓一些东西.在翻阅大神杰作Android 教你打造炫酷的ViewPagerIndicator 不仅仅是高仿MIUI 的时候看到下面有一条评论说,如果导航栏能滑动就更好了. ...

  3. c++语言表白超炫图形_教你用C语言加图形库打造炫酷表白连连看

    图1 今天小编用简单的C语言知识写一个连连看的游戏,但是是有含义的哈,游戏玩完之后又是属于一个表白程序,也感觉不错的哦. 下面小编把全部的代码发出来一下,以及效果图发一下,最终的话把涉及的知识点也讲解 ...

  4. 用devc++表白_教你用C语言加图形库打造炫酷表白连连看

    图1 今天小编用简单的C语言知识写一个连连看的游戏,但是是有含义的哈,游戏玩完之后又是属于一个表白程序,也感觉不错的哦. 下面小编把全部的代码发出来一下,以及效果图发一下,最终的话把涉及的知识点也讲解 ...

  5. 小程序源码:炫酷恶趣制作神器-多玩法安装简单

    这是一款强大的恶趣制作小程序源码 ​ 编辑 另外新增加了姓氏头像的制作 另外小编还给添加了几个流量主广告,包含了每一个页面都覆盖了 而且流量主还不是单一种: Banner 激励视频 视频广告 多格子广 ...

  6. 打造炫酷的Proxmox VE 监控界面

    打造炫酷的Proxmox VE 监控界面 今天终于把Proxmox VE(简称PVE)从6.1版本升级到PVE 6.4版本,在Web管理后台对比PVE 6.4与 PVE 6.1,看新增哪些功能?在数据 ...

  7. 怎样用C语言打造炫酷的图形编程

    原文地址: 怎样打造炫酷的图形编程  https://www.toutiao.com/i6400951971158688258/ 怎样打造炫酷的图形编程 C语言小白入门到大神 2017-03-24 1 ...

  8. 【元壤教育AI提示工程】Midjourney神器助力,设计小白3分钟轻松打造炫酷海报!

    前言 关注「元壤教育」公众号,系统学习更多AIGC课程. 看完这篇实操教程,设计师该领盒饭了,哈哈,开个玩笑,各位老板看着办. 本教程针对完全没有设计基础的老板们,手把手教你3分钟利用Midjourn ...

  9. Android 自定义控件玩转字体变色 打造炫酷ViewPager指示器

    转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/44098729,本文出自: [张鸿洋的博客] 1.概述 本篇博客的产生呢,是因为 ...

  10. Android 自定义控件玩转字体变色 打造炫酷ViewPager指示器

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 转载请标 ...

最新文章

  1. django 增加验证邮箱功能
  2. HTTP长连接和短连接以及推送服务原理(转)
  3. 常用数据库连接和diriver以及默认端口
  4. matlab如何找出最小的数据,读取数据并找出全部数据的最大值和最小值
  5. ldap和kerberos整合大数据账号
  6. 关于网上商城开发的随笔记录2
  7. 利用LR做性能测试中出现的常见问题解决方案
  8. 使用海康8700综合平台对ds-6908解码器进行解码上墙大概配置
  9. 深度系统linux deepin如何按装,U盘安装深度操作系统(Deepin)的方法
  10. ROS双线做法(双电信)
  11. 管理学定律三:羊群效应与刺猬法则
  12. 仿Tumblr点赞心破碎动画
  13. 《如何阅读一本书》读书计划
  14. Linux tcp拥塞控制
  15. 在Python中使用Pandas.DataFrame对Excel操作笔记一 - 从Excel里面获取说需要的信息
  16. 酷派手机(Coolpad 8297-T01)在Android开发工具如AndroidStudio、Eclipse中无法打印Log
  17. USB 协议 (三) 基础知识
  18. Windows 11 下 Virtualbox 6.1.34 出现 End kernel panic - not syncing: attempted to kill the idle task
  19. 恶意代码分析实战 9 隐蔽的恶意代码启动
  20. python turtle绘制正多边形

热门文章

  1. CPU负载均衡之WALT学习
  2. 拜托,面试别再问我TopK了!!!
  3. WIN10下搭建vue开发环境
  4. freeswitch 录音录像模块和内核
  5. anroid Remote Service 使用注意事项
  6. 1090 Highest Price in Supply Chain(25 分)
  7. flutter 全选_Android Studio写flutter快捷键
  8. php scrscriptipt,xss跨站脚本攻击 (初级-中级-高级)
  9. 烟台市计算机二级培训机构,烟台市2020年3月计算机二级报名时间|网上报名入口【12月20日9:00开通】...
  10. redist mysql_Windows下安装 MySQL