android listview立体效果,Android 实现ListView 3D效果 - 1
一、有图有真相
二、简单分析
1. ListView 3D实现整体布局使用自定义ListView, 只是继承自ListView父类的父类AdapterView,具体实现可参考之前写的文章:
《Android 自己动手写ListView学习其原理 3 ItemClick,ItemLongClick,View复用》
2. 3D效果其实是伪3D,每个Item绘制两次并存垂直显示就是上面的效果。
三、具体实现步骤分析
1. 预留宽度和高度, 因为每一个Item都需要会滚动,需要宽和高都预留出来一些空间。
/**
* 向当前ListView添加子视图并负责Measure子视图操作
*
* @param child 需要添加的ListView子视图(Item)
* @param layoutMode 在顶部添加上面添加还是在底部下面添加子视图 , LAYOUT_MODE_ABOVE 或 LAYOUT_MODE_BELOW
*/
private void addAndMeasureChild(View child, int layoutMode) {
LayoutParams params = child.getLayoutParams();
if (params == null) {
params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}
// addViewInLayout index?
final int index = layoutMode == LAYOUT_MODE_ABOVE ? 0: -1;
child.setDrawingCacheEnabled(true);
addViewInLayout(child, index, params, true);
final int itemWidth = (int) (getWidth() * ITEM_WIDTH);
child.measure(MeasureSpec.EXACTLY | itemWidth, MeasureSpec.UNSPECIFIED);
}
疑问?
MeasureSpec.EXACTLY | itemWidth 进行位运算,以后可分析下MeasureSpec.EXACTLY等三个模式具体的值相关知识。
private int getChildMargin(View child) {
return (int)(child.getMeasuredHeight() * (ITEM_VERTICAL_SPACE - 1) / 2);
}
private int getChildTop(View child) {
return child.getTop() - getChildMargin(child);
}
private int getChildBottom(View child) {
return child.getBottom() + getChildMargin(child);
}
private int getChildHeight(View child) {
return child.getMeasuredHeight() + 2 * getChildMargin(child);
}
效果图
四、改变移动界面效果
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
// 当前Item左侧顶部坐标值
int left = child.getLeft();
int top = child.getTop();
// 当前Item中部偏移
int centerX = child.getWidth() / 2;
int centerY = child.getHeight() / 2;
// 当前Item针对于ListView居中坐标
float pivotX = left + centerX;
float pivotY = top + centerY;
// 计算离中间位置的距离
float centerScreen = getHeight() / 2;
// ?
float distFromCenter = (pivotY - centerScreen) / centerScreen;
// 计算缩放和旋转
float scale = (float)(1 - SCALE_DOWN_FACTOR * (1 - Math.cos(distFromCenter)));
float rotation = 30 * distFromCenter;
canvas.save();
canvas.rotate(rotation, pivotX, pivotY);
canvas.scale(scale, scale, pivotX, pivotY);
super.drawChild(canvas, child, drawingTime);
canvas.restore();
return false;
}
效果图
疑问,这两个计算公式都不知道为什么要这样写,仅直到什么,怎样用,不知道为什么要这样写?
float distFromCenter = (pivotY - centerScreen) / centerScreen;
float scale = (float)(1 - SCALE_DOWN_FACTOR * (1 - Math.cos(distFromCenter)));
五、添加3D效果
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
final Bitmap bitmap = child.getDrawingCache();
if (bitmap == null) {
return super.drawChild(canvas, child, drawingTime);
}
// 当前Item左侧顶部坐标值
int left = child.getLeft();
int top = child.getTop();
// 当前Item中部偏移
int centerX = child.getWidth() / 2;
int centerY = child.getHeight() / 2;
// 计算离中间位置的距离
float centerScreen = getHeight() / 2;
// 计算缩放
// ?
float distFromCenter = (top + centerY - centerScreen) / centerScreen;
float scale = (float)(1 - SCALE_DOWN_FACTOR * (1 - Math.cos(distFromCenter)));
// 计算旋转
float childRotation = mListRotation - 20 * distFromCenter;
childRotation %= 90;
if (childRotation < 0) {
childRotation += 90;
}
// 绘制当前Item
if (childRotation < 45) {
// 菱角朝上时 - 下侧3D
drawFace(canvas, bitmap, top, left, centerX, centerY, scale, childRotation - 90);
// 正中心显示的Item
drawFace(canvas, bitmap, top, left, centerX, centerY, scale, childRotation);
} else {
// 正中心显示的Item
drawFace(canvas, bitmap, top, left, centerX, centerY, scale, childRotation);
// 菱角朝上时 - 上侧3D
drawFace(canvas, bitmap, top, left, centerX, centerY, scale, childRotation - 90);
}
return false;
}
/**
* 绘制3D界面块
*
* @param canvas drawChild回调提供的Canvas对象
* @param view
* @param top
* @param left
* @param centerX
* @param centerY
* @param scale
* @param rotation
*/
private void drawFace(final Canvas canvas, final Bitmap view, final int top, final int left,
final int centerX, final int centerY, final float scale, final float rotation) {
// 如果之前没有创建新对象
if (mCamera == null) {
mCamera = new Camera();
}
// 保存,以免以下操作对之后系统使用的Canvas造成影响
mCamera.save();
// 平移和旋转Camera
mCamera.translate(0, 0, centerY);
mCamera.rotateX(rotation);
mCamera.translate(0, 0, -centerY);
// 如果之前没有Matrix创建新对象
if (mMatrix == null) {
mMatrix = new Matrix();
}
mCamera.getMatrix(mMatrix);
mCamera.restore();
// 平移和缩放Matrix
mMatrix.preTranslate(-centerX, -centerY);
mMatrix.postScale(scale, scale);
mMatrix.postTranslate(left + centerX, top + centerY);
// 创建和初始化
if (mPaint == null) {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setFilterBitmap(true);
}
//
if (mLightEnabled) {
mPaint.setColorFilter(calculateLight(rotation));
} else {
//
mPaint.setAlpha(0xFF - (int)(2 * Math.abs(rotation)));
}
// 绘制Bitmap
canvas.drawBitmap(view, mMatrix, mPaint);
}
private LightingColorFilter calculateLight(final float rotation) {
final double cosRotation = Math.cos(Math.PI * rotation / 180);
int intensity = AMBIENT_LIGHT + (int)(DIFFUSE_LIGHT * cosRotation);
int highlightIntensity = (int)(SPECULAR_LIGHT * Math.pow(cosRotation, SHININESS));
if (intensity > MAX_INTENSITY) {
intensity = MAX_INTENSITY;
}
if (highlightIntensity > MAX_INTENSITY) {
highlightIntensity = MAX_INTENSITY;
}
final int light = Color.rgb(intensity, intensity, intensity);
final int highlight = Color.rgb(highlightIntensity, highlightIntensity, highlightIntensity);
return new LightingColorFilter(light, highlight);
}
六、扩展学习
1. Canvas与rotate等方法参数含义,作用与使用
2. Camera + Matirx如何使用,与Canvas区别
3. 何时使用Paint
4. 计算公式由来
七、源码下载
八、 参考资料
android listview立体效果,Android 实现ListView 3D效果 - 1相关推荐
- Android手机与vr交互暴风魔镜3D效果显示原理
首先讲到VR,谈谈个人体会,半年前看到淘宝上的vr眼镜盒为了促销标题图片都是非常性感的,还有海量你懂得资源.到最近在淘宝搜索vr暴风魔镜都正规了,而且销售量庞大 还有新闻上很多vr的科技前沿资讯可以看 ...
- android之向Gallery中添加倒影3D效果
step1:新建项目MyGallery3D step2:设计应用的UI界面 /layout/gallery3d.xml <?xml version="1.0" encod ...
- Android OpenGL 仿自如 APP 裸眼 3D 效果
概述 之前看到 自如团队 发布的 自如客APP裸眼3D效果的实现 ,非常有趣,不久后,社区内 Android 的开发者们陆续提供了 Flutter. Android 原生 .Android Jetpa ...
- 卷起来了!Android OpenGL仿自如APP裸眼3D效果
/ 今日科技快讯 / 近日,"乘联会"微信公众号发布消息,2021年12月新能源乘用车市场多元化发力,厂商批发销量突破万辆的企业有14家,较前期大幅增多,其中:比亚迪933 ...
- html立体魔方图片制作,AI软件如何打造立体魔方 Ai如何使用3D效果快速生成三个面贴图立体魔方...
矢量图制作软件Adobe Illustrator如何快速生成立体魔方?魔方是立体.多面的,使用Ai软件自带的3D效果三种之一的凸出和斜角,能创建具有凸出和斜角效果的立体魔方.在3D效果中,选择三个面贴 ...
- 给你的2D游戏添加3D效果
作者:numenzq 原文链接:http://www.j2medev.com/Article/ShowArticle.asp?ArticleID=1135 有两种方法给你的2D游戏添加3D效果.你可以 ...
- windows真正体验3D效果桌面
Yod m 3D V1.20_多国语言绿色免费版_系统桌面呈现3D的效果.真正体验3D效果桌面 软件大小:4.1 MB 软件类型:绿色软件 / 免费软件 运行环境:Win2000/WinXP/Win2 ...
- android gridview item 点击,Android-取消GridView/ListView item被点击时的效果
方法一,在控件被初始化的时候设置 gridView.setSelector(new ColorDrawable(Color.TRANSPARENT)); listView.setSelector(ne ...
- Android 使用NineOldAndroids实现绚丽的ListView左右滑动删除Item效果
转载请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/18311877),请尊重他人的辛勤劳动成果,谢谢! 今天还是 ...
最新文章
- 8.Deep Interest Evolution Network for Click-Through Rate Prediction论文详解
- 大数据时代,如何构建精准用户画像,直击精细化运营
- matlab条形图添加误差线_在Excel图表中添加误差线和对误差线进行设置的技巧
- Python Django 获取多条记录API
- 01_反射_02_反射类的构造方法
- c++《VS2008 快捷键大全》
- JS原型链原理(链表)
- 开源:OpenJDK8 MIPS64(龙芯)
- python-网易云简单爬虫
- 静态多层Map缓存清除
- 盛金公式解一元三次方程_一元三次方程的解法
- 工程经济—技术方案经济效果评价
- 人体内部可视化系统市场深度研究分析报告
- hadoop生态系统的详细介绍-详细一点
- Bootstrap3 Font Awesome 字体图标的基本图标
- 层压结构及参数(PCB板层厚度)收集
- python数据处理——取dataframe的一列或一行
- UART/USRAT协议
- php时间戳与日期格式比大小,比较两个时间戳的大小
- 清理Xcode占用的Mac硬盘空间