自定义View之仿虾米音乐TabLayout
写在开头
最近有点忙,好久没写文章了。最近公司App有个仿虾米音乐高大上tablayout的需求,网上百度了些没啥好的轮子,于是自己撸了一发。效果已实现,发出来,欢迎大家批评指正。
效果如下:
不太清楚,如何您正好有这个需求,欢迎下载提问题。
https://github.com/loveAndroidAndroid/XiaMiTablayout
实现思路
首先这个效果系统的tablayout是无法实现的,至少我没发现合适的方式,所以就想着自定义一个tablayout来实现此方式。我们可以看源码的tablayout实现方式,他其实就是一个自定义HorizontalScrollView,所以我们也来根据我们的业务需求实现一个自定义HorizontalScrollView。
主要就是以下几方面:
初始化自定义属性及一些初始化操作。
设置数据源。
关联viewpager及更新界面,添加方法设置当前显示tab。
重要: PageChangeListener实现各种渐变效果
初始化自定义属性及一些初始化操作
public XiaMiTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initStyle(context, attrs);setFillViewport(true);setHorizontalScrollBarEnabled(false);mTabContainer = new LinearLayout(context);addView(mTabContainer, 0, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));mDataList = new ArrayList<>();}private void initStyle(Context context, AttributeSet attrs) {TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.XiaMiTabLayout, 0, 0);mNormalTextSize = typedArray.getDimensionPixelSize(R.styleable.XiaMiTabLayout_tab_normal_textSize, DEFAULT_NORMAL_TEXT_SIZE_SP);mSelectTextSize = typedArray.getDimensionPixelSize(R.styleable.XiaMiTabLayout_tab_select_textSize, DEFAULT_SELECT_TEXT_SIZE_SP);typedArray.recycle();}
设置数据源。
/*** 设置数据源*/public void setDataList(List<String> dataList) {this.mDataList.clear();this.mDataList.addAll(dataList);}
关联viewpager及更新界面,添加方法设置当前显示tab。
/*** 关联viewpager*/public void setupWithViewPager(ViewPager viewPager) {this.mViewPager = viewPager;if (viewPager == null) {throw new IllegalArgumentException("viewpager not is null");}PagerAdapter pagerAdapter = viewPager.getAdapter();if (pagerAdapter == null) {throw new IllegalArgumentException("pagerAdapter not is null");}this.mViewPager.addOnPageChangeListener(new TabPagerChanger());mTabCount = pagerAdapter.getCount();mCurrentTabPosition = viewPager.getCurrentItem();notifyDataSetChanged();}/*** 更新界面*/public void notifyDataSetChanged() {mTabContainer.removeAllViews();for (int i = 0; i < mTabCount; i++) {final int currentPosition = i;TextView tabTextView = createTextView();tabTextView.setText(mDataList.get(i));tabTextView.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View view) {mViewPager.setCurrentItem(currentPosition);}});mTabContainer.addView(tabTextView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT));}setSelectedTabView(mCurrentTabPosition);}/*** 第一次设置选中tab效果** @param position*/protected void setSelectedTabView(int position) {this.mCurrentTabPosition = position;for (int i = 0; i < mTabCount; i++) {View view = mTabContainer.getChildAt(i);if (view instanceof TextView) {TextView textView = (TextView) view;textView.setSelected(position == i);textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, position == i ? mSelectTextSize : mNormalTextSize);textView.setTypeface(position == i ? Typeface.DEFAULT_BOLD : Typeface.DEFAULT);textView.setTextColor(position == i ? DEFAULT_SELECT_TEXT_COLOR : DEFAULT_NORMAL_TEXT_COLOR);if (mCurrentTabPosition == i) {textView.setPadding(ScreenUtils.dipToPx(getContext(), 5), 0, ScreenUtils.dipToPx(getContext(), 5), ScreenUtils.dipToPx(getContext(), 6));} else {textView.setPadding(ScreenUtils.dipToPx(getContext(), 5), 0, ScreenUtils.dipToPx(getContext(), 5), ScreenUtils.dipToPx(getContext(), 10));}}}}
PageChangeListener实现各种渐变效果
//利用估值器实现渐变private ArgbEvaluator argbEvaluator = new ArgbEvaluator();private IntEvaluator intEvaluator = new IntEvaluator();
/*** pager监听*/private class TabPagerChanger implements ViewPager.OnPageChangeListener {@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {final TextView selectedChild = (TextView) mTabContainer.getChildAt(position);final TextView nextChild = position + 1 < mTabContainer.getChildCount()? (TextView) mTabContainer.getChildAt(position + 1): null;if (selectedChild != null) {selectedChild.setTextSize(TypedValue.COMPLEX_UNIT_PX, mSelectTextSize - (mSelectTextSize - mNormalTextSize) * positionOffset);//初始颜色值int bgColor = DEFAULT_SELECT_TEXT_COLOR;if (positionOffset == 0) {//显示初始透明颜色bgColor = DEFAULT_SELECT_TEXT_COLOR;} else if (positionOffset > 1) {//滚动到一个定值后,颜色最深,而且不再加深bgColor = DEFAULT_NORMAL_TEXT_COLOR;} else {//滚动过程中渐变的颜色bgColor = (int) argbEvaluator.evaluate(positionOffset, DEFAULT_SELECT_TEXT_COLOR, DEFAULT_NORMAL_TEXT_COLOR);}selectedChild.setTextColor(bgColor);int pad = 6;if (positionOffset == 0) {//显示初始透明颜色pad = 6;} else if (positionOffset > 1) {//滚动到一个定值后,颜色最深,而且不再加深pad = 10;} else {//滚动过程中渐变的paddingpad = intEvaluator.evaluate(positionOffset, 6, 10);}selectedChild.setPadding(ScreenUtils.dipToPx(getContext(), 5), 0, ScreenUtils.dipToPx(getContext(), 5), ScreenUtils.dipToPx(getContext(), pad));if (positionOffset > 0.5) {selectedChild.setTypeface(Typeface.DEFAULT);} else {selectedChild.setTypeface(Typeface.DEFAULT_BOLD);}}if (nextChild != null) {nextChild.setTextSize(TypedValue.COMPLEX_UNIT_PX, mNormalTextSize + (mSelectTextSize - mNormalTextSize) * positionOffset);//初始颜色值int bgColor = DEFAULT_NORMAL_TEXT_COLOR;if (positionOffset == 0) {//显示初始透明颜色bgColor = DEFAULT_NORMAL_TEXT_COLOR;} else if (positionOffset > 1) {//滚动到一个定值后,颜色最深,而且不再加深bgColor = DEFAULT_SELECT_TEXT_COLOR;} else {//滚动过程中渐变的颜色bgColor = (int) argbEvaluator.evaluate(positionOffset, DEFAULT_NORMAL_TEXT_COLOR, DEFAULT_SELECT_TEXT_COLOR);}nextChild.setTextColor(bgColor);int pad = 10;if (positionOffset == 0) {pad = 10;} else if (positionOffset > 1) {pad = 6;} else {//滚动过程中渐变的paddingpad = intEvaluator.evaluate(positionOffset, 10, 6);}nextChild.setPadding(ScreenUtils.dipToPx(getContext(), 5), 0, ScreenUtils.dipToPx(getContext(), 5), ScreenUtils.dipToPx(getContext(), pad));if (Math.abs(positionOffset) > 0.5) {nextChild.setTypeface(Typeface.DEFAULT_BOLD);} else {nextChild.setTypeface(Typeface.DEFAULT);}}}@Overridepublic void onPageSelected(int position) {}@Overridepublic void onPageScrollStateChanged(int state) {}
写在末尾
欢迎下载Demo批评指正,如您对指示器也有要求但无思路,也可私信联系,共同探讨(已实现)。
自定义View之仿虾米音乐TabLayout相关推荐
- android幻灯片效果自定义,Android自定义View实现仿网易音乐唱片播放效果
本文实例为大家分享了Android实现仿网易音乐唱片播放效果的具体代码,供大家参考,具体内容如下 效果图: 在values中创建attrs.xml文件 //中间图片的半径 //图片 //唱片旋转的速度 ...
- android 自定义取色器,【Android自定义View】仿Photoshop取色器ColorPicker(二)
ColorPicker 一款仿Photoshop取色器的Android版取色器. 前言 上一篇已经简单介绍了ColorPicker的项目结构以及两种颜色空间,接下来我们详细解析一下ColorPicke ...
- 自定义xy组 android,Android自定义view之仿支付宝芝麻信用仪表盘示例
自定义view练习 仿支付宝芝麻信用的仪表盘 对比图: 首先是自定义一些属性,可自己再添加,挺基础的,上代码 接着在构造方法里初始化自定义属性和画笔: private void initAttr(At ...
- Android自定义View之仿QQ运动步数进度效果
文章目录 前言 先看效果图 ![在这里插入图片描述](https://img-blog.csdnimg.cn/6e4ddec17933496ea4830fa08d8ffbe5.png?x-oss-pr ...
- 自定义View之仿淘宝详情页
自定义View之仿淘宝详情页 转载请标明出处: http://blog.csdn.net/lisdye2/article/details/52353071 本文出自:[Alex_MaHao的博客] 项 ...
- WordPress主题:仿虾米音乐CMS模板
这次分享一款虾米音乐老款主题,感觉放到2020年也不觉得有什么过时的感觉! 虾米音乐虽然没有往日的风光,但是今朝许多伴侣还是觉得不错的,刚好站长发现了一款高仿虾米音乐的主题.这款主题是原作者花了一个半 ...
- Android自定义view之仿支付宝芝麻信用仪表盘 ---by ccy
自定义view练习 仿支付宝芝麻信用的仪表盘 对比图: 首先是自定义一些属性,可自己再添加,挺基础的,上代码 <?xml version="1.0" encoding=&qu ...
- Android自定义View分享——仿网易云音乐留声机效果
写在前面 这是笔者自学习自定义View以来,分享的第五篇效果,之前分享过一篇动态时钟效果的自定义View,如果有兴趣的可以看看: Android自定义View分享--一个时钟 之前的博客笔者一般都会说 ...
- android 音乐播放器的状态栏通知,Android仿虾米音乐播放器之通知栏notification解析...
通知栏notification是Android中一个很重要的组件,可以在顶部状态栏中存在,用户也可以通过此来操作应用,在Android中只有3.0以上的版本才加入了notification的按钮点击功 ...
- 自定义View:秀一个音乐app的歌词变色TextView
前言 从2014年开始从事安卓的工作,就一直关注郭霖大神的博客,慢慢的到微信公众号,再到第三行代码.不得不说书中介绍的非常详细,帮助我们把平时接触到的碎片知识整合到一起,书中摒弃了市面上大部分Andr ...
最新文章
- 普适方案|资管新规落地,资管领域存量市场竞争激烈。专家:得转型(附产品推广)
- LeetCode第 146 号问题: LRU 缓存机制
- Boost:字符串替换的测试程序
- 边缘计算如何实现海量IoT数据就地处理
- 结果显示窗口如何缩小_Proe草绘时提示“截面再生失败。不合适的尺寸”如何处理?...
- 【JQGRID DOCUMENTATION】.学习笔记.5.Form Editing
- 如何在ubuntu上用c++串口通信_让你搞懂PLC串口通讯和通讯接口,这东西估计没几个能说清楚~...
- Linux命令 - unzip命令
- java实现生命游戏
- 关于amd cpu超频 个人心得
- java 将pdf文件转成高清图片(多张合并成一张)
- iOS 仿YY直播心形动画 烟花动画
- 【杂七杂八】excel中根据RTL信号位宽生成拼接取位
- MySQL中的auto_increment
- LFM雷达实现及USRP验证【章节2:LFM雷达测距】
- Jzoj4896 兔子
- 国产小家电品牌如何用dtc模式打造新中产超爆款?
- 白翔团队新作:借助CLIP完成场景文字检测
- not compiled to use: SSE4.1 SSE4.2 AVX AVX2 FMA
- 唐老院长振绪追悼会感言