android自定义View之3D索引效果
效果图:
我的小霸王太卡了。
最近工作比较忙,今天搞了一下午才搞出来这个效果,这种效果有很多种实现方式,最常见的应该是用贝塞尔曲线实现的。今天我们来看另一种不同的实现方式,只需要用到 canvas.scale(),有没有很好奇是怎么实现的呢。
首先来说一下思路,只要有了思路剩下的就是往里面套代码了。
通过观察上面的效果图我们发现可以把右边的字母分为三种类型
1、 手指没触摸的地方显示正常的样式
2、手指触摸的位置 显示最大且完全不透明
3、手指触摸位置的上下附近位置 有放大且有透明度变化
对这个效果有了直观的认识后,我们就可以在ondraw里面根据不同的条件来分别画出这三种状态,这里主要难理解的就是这些条件。这需要结合代码看下。
so 我们开始撸码吧,
1、先初始化一些需要的变量
private void init(Context context) {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.GRAY);
mLetters = context.getResources().getStringArray(R.array.letter_list);
mPaint.setTextAlign(Paint.Align.CENTER);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
mDensity = getContext().getResources().getDisplayMetrics().density;
setPadding(0,dip2px(20),0,dip2px(20));
}
private int dip2px(int dipPx){
return (int)(dipPx*mDensity+0.5);
}
相信上面这些应该没什么难度吧。
另外把一些需要的宽高属性赋值一下,因为下面会用到它们
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mHeight = h - getPaddingTop() - getPaddingBottom();
mWidth = w - dip2px(16);
mLetterHeight = mHeight / mLetters.length;
int textSize = (int)(mLetterHeight*0.7);
mPaint.setTextSize(textSize);
mIsDownRect.set(w-dip2px(32),0,w,h);
}
这里主要就是mIsDownRect这个要注意一下它是索引列表的范围,但是我们并不需要画出它。
2、在ontouch方法中对触摸事件进行必要的处理
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
switch (action){
case MotionEvent.ACTION_DOWN:
mIsBeingDragger = false;
float initDownY = event.getY();
if(!mIsDownRect.contains(event.getX(),event.getY())){
return false;
}
mInitDownY = initDownY;
break;
case MotionEvent.ACTION_MOVE:
float y = event.getY();
float diff = Math.abs(y - mInitDownY);
if(diff>mTouchSlop&&!mIsBeingDragger){
mIsBeingDragger = true;
}
if(mIsBeingDragger){
mY = y;
float moveY = y - getPaddingTop();
int chartIndex = (int) (moveY / mHeight * mLetters.length);//获取索引位置的index
if(mChoose!=chartIndex){
if(chartIndex>=0&&chartIndex<mLetters.length) {
if (slidViewListener != null) {
Log.i("lly","chartIndex = "+chartIndex);
slidViewListener.onChange(mLetters[chartIndex]);
}
mChoose = chartIndex;
}
}
invalidate();
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mIsBeingDragger = false;
mChoose = -1;
invalidate();
break;
}
return true;
}
这里面也很简单,首先当手指按下时记录下按下位置的Y坐标,然后判断按下的位置是否在索引列表的区域范围内(索引的区域在初始化赋值的时候已经确定过了)如果不在就没必要执行下去了 直接返回false即可,
然后在手指移动的时候判断下是否是在移动是的话就把mIsBeingDragger置为true,如果mIsBeingDragger为true说明正在移动 ,这时候就计算出当前手指所在的索引位置,并通过回调方式通知外面当前的位置,最后把索引位置赋给全局变量mChoose,并刷新UI。
手指抬起时进行一些复位操作。
以上就是ontouch的全部方法。
3、在ondraw方法里面画出索引字母
这里要画出那三种类型的字母索引,我们先从简单的来
float lettersPos= mLetterHeight*(i+1)+getPaddingTop(); //下一个字母的Y值坐标
float diffY; // Y 方向的偏移量
float diffX;//X 方向的偏移量
float diff;//缩放比例
if (mChoose == i&&i!=0&&i!=mLetters.length-1) {
diff = 2.2f;
diffX=0f;
diffY=0f;
}
mChoose 是在ontouch中我们记录的索引位置,当上面条件成立时说明当前就是选中的字母,这时候让它缩放比例最大,偏移量我们会在下面统一处理。
接下来处理不是选中的情况
float distanseDiff = Math.abs((mY - lettersPos)/mHeight);//计算手指触摸位置的上下附近位置
float maxPos = distanseDiff * 7;//乘7是因为这个系数太小了需要给他一个放大
if(distanseDiff<0.174){
diff = 2.2f - maxPos;
}else {
diff = 1f;
}
if(!mIsBeingDragger){
diff =1;
}
diffX = maxPos * 50;
if(mY>lettersPos){
diffY = maxPos*50;
}else {
diffY = - maxPos*50;
}
这里主要就是那个缩放系数比较难算 需要多试下。
X Y方向的偏移量如下图
这些都计算好后就可以画了
canvas.save();
canvas.scale(diff,diff,mWidth*1.2f+diffX,lettersPos+diffY);
if(diff ==1){
mPaint.setAlpha(255);
mPaint.setTypeface(Typeface.DEFAULT);
}else {
int alpha = (int) (255*(1-Math.min(0.9,diff -1)));
if(mChoose == i){
alpha = 255;
}
mPaint.setAlpha(alpha);
mPaint.setTypeface(Typeface.DEFAULT_BOLD);
}
Log.i("lly","mLetters["+i+"] = " +mLetters[i] );
canvas.drawText(mLetters[i],mWidth,lettersPos,mPaint);
canvas.restore();
可以发现canvas.scale(diff,diff,mWidth*1.2f+diffX,lettersPos+diffY); 这一句才是整个自定义view的关键 它前两个参数是x轴和y轴的缩放系数,后两个参数是x轴和y轴的锚点,我主要是试出来的,这两个参数比较难理解,还需要多家学习。到这里就已经实现了我们最上面的效果了。
android自定义View之3D索引效果的更多相关文章
- Android 自定义view实现水波纹效果
http://blog.csdn.net/tianjian4592/article/details/44222565 在实际的开发中,很多时候还会遇到相对比较复杂的需求,比如产品妹纸或UI妹纸在哪看了 ...
- android自定义view实现progressbar的效果
一键清理是很多Launcher都会带有的功能,其效果也比较美观.实现方式也许有很多中,其中常见的是使用图片drawable来完成的,具体可以参考这篇文章:模仿实现360桌面水晶球式的一键清理特效.本文 ...
- Android自定义View——刮刮卡效果
想要红包的实现效果的可以关注我的博客,仿饿了么红包 下层图片:我们的红包的图片 上层图片:有两部分 一部分是灰色背景 一部分是拥有透明度为0,并且模式为交集的画笔 使用滑动监听,滑动时,用透明度为0的 ...
- Android自定义View 画弧形,文字,并增加动画效果
一个简单的Android自定义View的demo,画弧形,文字,开启一个多线程更新ui界面,在子线程更新ui是不允许的,但是View提供了方法,让我们来了解下吧. 1.封装一个抽象的View类 B ...
- Android自定义View(LimitScrollerView-仿天猫广告栏上下滚动效果)
转载请标明出处: http://blog.csdn.net/xmxkf/article/details/53303872 本文出自:[openXu的博客] 1分析 2定义组合控件布局 3继承最外层控件 ...
- Android 自定义View合集
自定义控件学习 https://github.com/GcsSloop/AndroidNote/tree/master/CustomView 小良自定义控件合集 https://github.com/ ...
- Android自定义View和控件之一-定制属于自己的UI
照例,拿来主义.我的学习是基于下面的三篇blog.前两是基本的流程,第三篇里有比较细致的绘制相关的属性.第4篇介绍了如何减少布局层次来提高效率. 1. 教你搞定Android自定义View 2. 教你 ...
- Android自定义View(CustomCalendar-定制日历控件)
转载请标明出处: http://blog.csdn.net/xmxkf/article/details/54020386 本文出自:[openXu的博客] 目录: 1分析 2自定义属性 3onMeas ...
- 简单说说Android自定义view学习推荐的方式
这几天比较受关注,挺开心的,嘿嘿. 这里给大家总结一下学习自定义view的一些技巧. 以后写自定义view可能不会写博客了,但是可以开源的我会把源码丢到github上我的地址:https://git ...
随机推荐
- monogodb3.4安装修改,权限设置
下载地址:https://www.mongodb.com/download-center#community 这里的方法只对应3.4,别的有没有效果请自行判断. 下载后按默认下一步. 默认安装地址 ...
- 【转】cookielib模块
cookielib模块 cookielib模块的主要作用是提供可存储cookie的对象,以便于与urllib2模块配合使用来访问Internet资源.例如可以利用本模块 的CookieJar类的对象来 ...
- 用 k8s 管理机密信息 - 每天5分钟玩转 Docker 容器技术(155)
应用启动过程中可能需要一些敏感信息,比如访问数据库的用户名密码或者秘钥.将这些信息直接保存在容器镜像中显然不妥,Kubernetes 提供的解决方案是 Secret. Secret 会以密文的方式存储 ...
- python 函数“四剑客”的使用和介绍
python函数四剑客:lambda.map.filter和reduce. 一.lambda(匿名函数) 1. 学习lambda要注意一下几点: lambda语句被用来创建新的函数对象,并且在运行的时 ...
- Spring MVC基础学习
SpringMVC是Spring框架的一个模块,无需通过中间层整合在一起.SpringMVC是一个基于MVC设计模式web框架,MVC-model-view-controller:MVC将服务器端分为 ...
- 利用JS去做响应式布局
利用JS去做响应式布局 js动态改变布局方式 // 取浏览器可视区高宽 var lw = $(window).width(); var lh = $(window).height();// 页面加载完 ...
- Centos常用命令之:文件操作
在centos中,常用的文件操作命令有: ◇touch:建置新文件或者修改文件时间◇cat:从第一行开始显示文件内容◇tac:从最后一行开始显示文件内容,和cat相反◇nl:显示的时候,顺道输出行号◇ ...
- [BZOJ]2017省队十连测推广赛1 T2.七彩树
题目大意:给你一棵n个点的树,每个点有颜色,m次询问,每次询问一个点x的子树内深度不超过depth[x]+d的节点的颜色数量,强制在线.(n,m<=100000,多组数据,保证n,m总和不超过5 ...
- bzoj1877
1877: [SDOI2009]晨跑 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 2660 Solved: 1424[Submit][Status][ ...
- 在 TensorFlow 中实现文本分类的卷积神经网络
在TensorFlow中实现文本分类的卷积神经网络 Github提供了完整的代码: https://github.com/dennybritz/cnn-text-classification-tf 在 ...