Android:垂直 3d 列表视图 [英] Android: vertical 3d listview

查看:23
本文介绍了Android:垂直 3d 列表视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想制作垂直 3d 列表视图 就像这里,但对于 ImageButtons 和免费.是否有任何库或示例代码?我是 Android 开发新手,所以我不知道如何为这样的东西制作动画

I would like to make vertical 3d list view like here, but for ImageButtons and for free. Is there any library or sample code for that? I am new in Android development, so I don't know how to animate such thing

推荐答案

其实很简单.您需要扩展 ListView 并覆盖 onDrawChild().在那里你可以应用 3d 变换矩阵来获得你想要的效果.我的 github 上有一个工作示例或者你可以看看这个问题类似.

its actually pretty simple. You need to extend ListView and override onDrawChild(). In there you can apply 3d transformation matrices to get the effect you want. I have a working example on my github Or you can have a look at this question which is quite similar.

为方便起见,这是我对 3d ListView 的实现:

For your convenience this is my implementation of a 3d ListView:

public class ListView3d extends ListView {

    /** Ambient light intensity */
    private static final int AMBIENT_LIGHT = 55;
    /** Diffuse light intensity */
    private static final int DIFFUSE_LIGHT = 200;
    /** Specular light intensity */
    private static final float SPECULAR_LIGHT = 70;
    /** Shininess constant */
    private static final float SHININESS = 200;
    /** The max intensity of the light */
    private static final int MAX_INTENSITY = 0xFF;

    private final Camera mCamera = new Camera();
    private final Matrix mMatrix = new Matrix();
    /** Paint object to draw with */
    private Paint mPaint;

    public ListView3d(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
        // get top left coordinates
        final int top = child.getTop();
        final int left = child.getLeft();
        Bitmap bitmap = child.getDrawingCache();
        if (bitmap == null) {
            child.setDrawingCacheEnabled(true);
            child.buildDrawingCache();
            bitmap = child.getDrawingCache();
        }

        final int centerY = child.getHeight() / 2;
        final int centerX = child.getWidth() / 2;
        final int radius = getHeight() / 2;
        final int absParentCenterY = getTop() + getHeight() / 2;
        final int absChildCenterY = child.getTop() + centerX;
        final int distanceY = absParentCenterY - absChildCenterY;
        final int absDistance = Math.min(radius, Math.abs(distanceY));

        final float translateZ = (float) Math.sqrt((radius * radius) - (absDistance * absDistance));

        double radians = Math.acos((float) absDistance / radius);
        double degree = 90 - (180 / Math.PI) * radians;

        mCamera.save();
        mCamera.translate(0, 0, radius - translateZ);
        mCamera.rotateX((float) degree); // remove this line..
        if (distanceY < 0) {
            degree = 360 - degree;
        }
        mCamera.rotateY((float) degree); // and change this to rotateX() to get a
                                            // wheel like effect
        mCamera.getMatrix(mMatrix);
        mCamera.restore();

        // create and initialize the paint object
        if (mPaint == null) {
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setFilterBitmap(true);
        }
        //highlight elements in the middle
        mPaint.setColorFilter(calculateLight((float) degree));

        mMatrix.preTranslate(-centerX, -centerY);
        mMatrix.postTranslate(centerX, centerY);
        mMatrix.postTranslate(left, top);
        canvas.drawBitmap(bitmap, mMatrix, mPaint);
        return false;
    }

    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);
    }
}

干杯

这篇关于Android:垂直 3d 列表视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆