旋转木马3D环形特效

根据英文版CarouselDemo改写了其中的部分代码,实现伪3D环形的旋转木马效果,所有条目都可被点击,非最前端条目点击后会先旋转到最前端,再执行点击事件。
源码下载地址:http://download.csdn.net/download/qby_nianjun/9530318
效果展示:条目在3个以上,7个以下最佳
在自己项目中使用时,修改以下代码即可:
MainActivity根据逻辑自行修改,主要可修改代码
Carousel.java中设置图片,绘制阴影:

public void SetImages(TypedArray array, TypedArray names,
                boolean reflected) {

            if (names != null)
                if (array.length() != names.length())
                    throw new RuntimeException("图标数量与名字不符");

            final int reflectionGap = 3;

            Drawable[] drawables = new Drawable[array.length()];
            int[] colors = new int[] { R.color.shape1, R.color.shape2,
                    R.color.shape3, R.color.shape4, R.color.shape5,
                    R.color.shape6 };
            mImages = new CarouselItem[array.length()];

            for (int i = 0; i < array.length(); i++) {
                drawables[i] = array.getDrawable(i);
                // 把gradient drawable转换为Bitmap
                Bitmap originalImage = drawableToBitmap(drawables[i]);

                if (reflected) {
                    int width = originalImage.getWidth();
                    int height = originalImage.getHeight();

                    // 创建一个宽与原始图片一样,高为加上倒影后的高度的图
                    Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
                            (height + height / 8 + reflectionGap),
                            Config.ARGB_8888);

                    // 为新图创建画布
                    Canvas canvas = new Canvas(bitmapWithReflection);
                    // 先画出原始图片
                    canvas.drawBitmap(originalImage, 0, 0, null);

                    // 新建画笔对象,颜色与图片颜色一致
                    Paint paint = new Paint();
                    paint.setColor(getResources().getColor(colors[i]));
                    // 设置透明度为50
                    paint.setAlpha(50);
                    // 设置抗锯齿
                    paint.setAntiAlias(true);
                    // 画椭圆
                    RectF oval = new RectF(width / 6, height + reflectionGap,
                            5 * width / 6, height + height / 8 + reflectionGap);
                    canvas.drawOval(oval, paint);

                    originalImage = bitmapWithReflection;
                }

                CarouselItem item = new CarouselItem(mContext);
                item.setIndex(i);
                item.setImageBitmap(originalImage);
                if (names != null)
                    item.setText(names.getString(i));
                mImages[i] = item;

            }

        }

图片是自己写的shape,修改条目图片大小,只需要修改drawable下item_shapeX.xml即可,如item_shape1.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
    <solid android:color="@color/shape1"/>
    <size android:width="80dp"
        android:height="80dp"/>
    <stroke android:width="4dp"/>
</shape>

这里stroken并无实际意义,如有需要,可以自行设置不同的color;
图片的颜色与倒影的颜色一一对应,所以我在values下写了一个colors.xml,分别定义了与图片数量一致的color:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="shape1">#aaff5566</color>
    <color name="shape2">#aa55ff66</color>
    <color name="shape3">#aa55f6ff</color>
    <color name="shape4">#aa553388</color>
    <color name="shape5">#aa3f86f8</color>
    <color name="shape6">#aaa8cece</color>
</resources>

特别要注意的是,图片与文本的数量要一致,不一致会抛出异常,在attrs中:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">

    <array name="entries">
        <item>@drawable/item_shape1</item>
        <item>@drawable/item_shape2</item>
        <item>@drawable/item_shape3</item>
        <item>@drawable/item_shape4</item>
        <item>@drawable/item_shape5</item>
        <item>@drawable/item_shape6</item>
    </array>
    <array name="names">
        <item>The cat</item>
        <item>The hippo</item>
        <item>The monkey</item>
        <item>The mouse</item>
        <item>The panda</item>
        <item>The rabbit</item>
    </array>
</resources>

最后,由于倒影和原图在同一个ImageView中,如果想要文本信息刚好在原始图片的中心,需要计算,比如,我在shape中设置图片高度为80dp,可设置字体大小为16dp,可算出当TextView的marginTop值为(80/2-16/2)=32dp,所以在条目布局文件item.xml中:

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android" >

    <ImageView
        android:id="@+id/item_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scaleType="fitXY"
        android:src="@drawable/cat" />

    <TextView
        android:id="@+id/item_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:layout_gravity="center_horizontal"
        android:text=""
        android:textColor="#fff" />

</merge>

时间仓促,临时起意,如有疏漏,请多指点!

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值