`
luckliu521
  • 浏览: 259058 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

自定义控件-----CoverFlow

阅读更多
CoverFlow--我也不知道为什么要叫这个名字,貌似是从iphone上继承过来的?

随便了,反正就是这个样子了





此控件的设计和实现思路和部分代码同样是剽窃某网站上的,因为时间太久了,找不到原文地址了..杯具,所以我才来做备份的.

此类是从Gallery继承过来的,用法自然也就和Gallery一样了

程序的背景是一个xml陪的渐变背景,具体可以参看另外一篇"渐变背景"的文章

图片的倒影效果是适用了ReflectionImage控件,具体可以参看上一篇博文.

先看代码吧,看了代码什么都明白了

view plaincopy to clipboardprint?
package com.myview; 
import android.content.Context; 
import android.graphics.Camera; 
import android.graphics.Matrix; 
import android.util.AttributeSet; 
import android.view.View; 
import android.view.animation.Transformation; 
import android.widget.Gallery; 
import android.widget.ImageView; 
public class CoverFlow extends Gallery { 
     
    private Camera mCamera = new Camera(); 
    private int mMaxRotationAngle = 50; 
    private int mMaxZoom = -380; 
    private int mCoveflowCenter; 
    private boolean mAlphaMode = true; 
    private boolean mCircleMode = false; 
    public CoverFlow(Context context) { 
        super(context); 
        this.setStaticTransformationsEnabled(true); 
    } 
    public CoverFlow(Context context, AttributeSet attrs) { 
        super(context, attrs); 
        this.setStaticTransformationsEnabled(true); 
    } 
    public CoverFlow(Context context, AttributeSet attrs, int defStyle) { 
        super(context, attrs, defStyle); 
        this.setStaticTransformationsEnabled(true); 
    } 
    public int getMaxRotationAngle() { 
        return mMaxRotationAngle; 
    } 
    public void setMaxRotationAngle(int maxRotationAngle) { 
        mMaxRotationAngle = maxRotationAngle; 
    } 
    public boolean getCircleMode() { 
        return mCircleMode; 
    } 
    public void setCircleMode(boolean isCircle) { 
        mCircleMode = isCircle; 
    } 
    public boolean getAlphaMode() { 
        return mAlphaMode; 
    } 
    public void setAlphaMode(boolean isAlpha) { 
        mAlphaMode = isAlpha; 
    } 
    public int getMaxZoom() { 
        return mMaxZoom; 
    } 
    public void setMaxZoom(int maxZoom) { 
        mMaxZoom = maxZoom; 
    } 
    private int getCenterOfCoverflow() { 
        return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2 
                + getPaddingLeft(); 
    } 
    private static int getCenterOfView(View view) { 
        return view.getLeft() + view.getWidth() / 2; 
    } 
    protected boolean getChildStaticTransformation(View child, Transformation t) { 
        final int childCenter = getCenterOfView(child); 
        final int childWidth = child.getWidth(); 
        int rotationAngle = 0; 
        t.clear(); 
        t.setTransformationType(Transformation.TYPE_MATRIX); 
        if (childCenter == mCoveflowCenter) { 
            transformImageBitmap((ImageView) child, t, 0); 
        } else { 
            rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle); 
            if (Math.abs(rotationAngle) > mMaxRotationAngle) { 
                rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle 
                        : mMaxRotationAngle; 
            } 
            transformImageBitmap((ImageView) child, t, rotationAngle); 
        } 
        return true; 
    } 
    /**
     * This is called during layout when the size of this view has changed. If
     * you were just added to the view hierarchy, you're called with the old
     * values of 0.
     * 
     * @param w
     *            Current width of this view.
     * @param h
     *            Current height of this view.
     * @param oldw
     *            Old width of this view.
     * @param oldh
     *            Old height of this view.
     */ 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
        mCoveflowCenter = getCenterOfCoverflow(); 
        super.onSizeChanged(w, h, oldw, oldh); 
    } 
    /**
     * Transform the Image Bitmap by the Angle passed
     * 
     * @param imageView
     *            ImageView the ImageView whose bitmap we want to rotate
     * @param t
     *            transformation
     * @param rotationAngle
     *            the Angle by which to rotate the Bitmap
     */ 
    private void transformImageBitmap(ImageView child, Transformation t, 
            int rotationAngle) { 
        mCamera.save(); 
        final Matrix imageMatrix = t.getMatrix(); 
        final int imageHeight = child.getLayoutParams().height; 
        final int imageWidth = child.getLayoutParams().width; 
        final int rotation = Math.abs(rotationAngle); 
        mCamera.translate(0.0f, 0.0f, 100.0f); 
        // As the angle of the view gets less, zoom in 
        if (rotation <= mMaxRotationAngle) { 
            float zoomAmount = (float) (mMaxZoom + (rotation * 1.5)); 
            mCamera.translate(0.0f, 0.0f, zoomAmount); 
            if (mCircleMode) { 
                if (rotation < 40) 
                    mCamera.translate(0.0f, 155, 0.0f); 
                else 
                    mCamera.translate(0.0f, (255 - rotation * 2.5f), 0.0f); 
            } 
            if (mAlphaMode) { 
                ((ImageView) (child)).setAlpha((int) (255 - rotation * 2.5)); 
            } 
        } 
        mCamera.rotateY(rotationAngle); 
        mCamera.getMatrix(imageMatrix); 
        imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2)); 
        imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2)); 
        mCamera.restore(); 
    } 



这个就是CoverFlow类,说明几点

1. 成员函数

    mCamera是用来做类3D效果处理,比如z轴方向上的平移,绕y轴的旋转等

    mMaxRotationAngle是图片绕y轴最大旋转角度,也就是屏幕最边上那两张图片的旋转角度

    mMaxZoom是图片在z轴平移的距离,视觉上看起来就是放大缩小的效果.

    其他的变量都可以无视

2. 构造函数里面的setStaticTransformationsEnabled



protected void setStaticTransformationsEnabled (boolean enabled)
When this property is set to true, this ViewGroup supports static transformations on children; this causes getChildStaticTransformation(View, android.view.animation.Transformation) to be invoked when a child is drawn. Any subclass overriding getChildStaticTransformation(View, android.view.animation.Transformation) should set this property to true.

Parameters
enabled True to enable static transformations on children, false otherwise.
也就是说把这个属性设成true的时候每次viewGroup(看Gallery的源码就可以看到它是从ViewGroup间接继承过来的)在重新画它的child的时候都会促发getChildStaticTransformation这个函数,所以我们只需要在这个函数里面去加上旋转和放大的操作就可以了

其他的getter和setter函数都可以无视

view plaincopy to clipboardprint?
package com.hello; 
import com.hello.R; 
import com.myview.*; 
import android.app.Activity; 
import android.content.Context; 
import android.graphics.drawable.BitmapDrawable; 
import android.os.Bundle; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.BaseAdapter; 
import android.widget.ImageView; 
public class HelloAndroid extends Activity { 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
         
        CoverFlow cf = new CoverFlow(this);  
        cf.setBackgroundResource(R.drawable.shape); 
        cf.setAdapter(new ImageAdapter(this));  
        ImageAdapter imageAdapter = new ImageAdapter(this); 
        cf.setAdapter(imageAdapter); 
//      cf.setAlphaMode(false);  
//      cf.setCircleMode(false); 
//      cf.setSelection(3, true);   
        cf.setAnimationDuration(1000); 
        setContentView(cf); 
    } 
     
     
     
    public class ImageAdapter extends BaseAdapter { 
        int mGalleryItemBackground; 
        private Context mContext; 
        private Integer[] mImageIds = {  
                R.drawable.a,  
                R.drawable.b, 
                R.drawable.d, 
                R.drawable.e, 
                R.drawable.c}; 
         
        public ImageAdapter(Context c) { 
            mContext = c; 
        } 
        public int getCount() { 
            return mImageIds.length; 
        } 
        public Object getItem(int position) { 
            return position;  
        } 
        public long getItemId(int position) { 
            return position; 
        } 
        public View getView(int position, View convertView, ViewGroup parent) { 
            ReflectionImage i = new ReflectionImage(mContext); 
             
            i.setImageResource(mImageIds[position]); 
            i.setLayoutParams(new CoverFlow.LayoutParams(96, 76)); 
            i.setScaleType(ImageView.ScaleType.CENTER_INSIDE); 
            // Make sure we set anti-aliasing otherwise we get jaggies 
            BitmapDrawable drawable = (BitmapDrawable) i.getDrawable(); 
            drawable.setAntiAlias(true); 
            return i; 
        } 
  
        public float getScale(boolean focused, int offset) { 
            return Math.max(0, 1.0f / (float) Math.pow(2, Math.abs(offset))); 
        } 
    } 



BitmapDrawable drawable = (BitmapDrawable) i.getDrawable();

drawable.setAntiAlias(true);

是保证图片绕Y旋转了以后不会出现锯齿
  • 大小: 86.3 KB
分享到:
评论
1 楼 zxxcos 2011-09-03  
实现是实现了,可是写的太死,什么事件和Adapter都用不了,没多大的用处。

相关推荐

    wp7上coverflow控件

    在WP7应用开发中,虽然.NET Framework本身并不直接提供内置的Coverflow控件,但开发者可以通过第三方库或者自定义控件实现这一功能。 Coverflow控件的核心设计在于其动画效果,通过滑动和平移操作,使内容看起来...

    炫酷 自定义控件 3D绘制 画廊效果

    CoverFlow这个文件名通常用于表示类似苹果Cover Flow效果的控件,这是一种流行的设计,其中元素沿着弧形轨迹排列,用户滚动时会有一个类似唱片封面翻转的效果。在Android平台上,开发者通常会复用或自定义此类控件,...

    Android中实现coverflow效果

    总之,Android中的Coverflow效果是通过结合Gallery控件、自定义Adapter、动画处理以及事件监听来实现的。随着Android版本的更新,开发者需要不断学习新的技术和组件来保持应用的先进性和用户体验。

    Android实现CoverFlow效果控件的实例代码

    Gallery3DActivity是承载自定义控件的Activity,用于展示CoverFlow效果控件。在Gallery3DActivity中,需要将自定义控件添加到布局中,然后设置控件的属性,以便正确地显示图片。 Android实现CoverFlow效果控件的...

    iOS中的CoverFlow展示,效果还行

    对于 CoverFlow 效果,开发者通常需要自定义UI控件或者利用现有的第三方库来实现。在这个例子中,描述中提到的"FlowCover"可能是一个自定义的视图类,用于创建CoverFlow效果。 实现CoverFlow的核心在于处理每个元素...

    Android改进版CoverFlow效果控件无限循环

    在原生Android SDK中,并没有内置的CoverFlow控件,因此需要通过自定义ViewGroup,如Gallery或HorizontalScrollView来实现。这个改进版的控件可能是在此基础上进行了优化,解决了原始实现中可能存在的性能问题,并...

    WPF下的CoverFlow效果

    "WPF下的CoverFlow效果"指的是在WPF应用中实现类似苹果iPod的Cover Flow翻页效果,它允许用户以视觉上吸引人的方式浏览图像或项目集合。这个效果通常用于音乐播放器、电子相册或产品展示等应用场景。 要实现Cover ...

    CoverFlow仿苹果超炫

    在本文中,我们将深入探讨如何...总的来说,实现一个仿苹果的CoverFlow特效涉及到对WPF的深度理解,包括3D图形、数据绑定、自定义控件模板以及动画技术。通过实践和学习,开发者可以创建出既美观又互动性强的用户体验。

    Android版仿iOS的CoverFlow效果

    `GalleryFlow`可能是一个专门为Android设计的开源项目,它模仿了iOS的CoverFlow,并提供了自定义选项以适应不同的应用场景。 要使用`GalleryFlow`,你需要按照以下步骤操作: 1. 添加依赖:在你的`build.gradle`...

    收集的scorllview和coverflow效果

    ScrollView通常用于实现可滚动的内容区域,而CoverFlow则是一种具有翻页效果的控件,模仿了苹果iOS中的类似功能,使得展示内容更加生动和吸引人。 **ScrollView**: 1. **基本概念**:ScrollView是Android提供的一...

    安卓的伪3D实现,用galler控件实现coverflow,里面都是可以运行的demo

    在早期的Android版本中,Gallery控件是实现Cover Flow效果的一个常见选择,尽管在Android 5.0(API级别21)之后,它已被废弃,但通过一些自定义和优化,仍然可以在现代Android系统上实现类似的效果。 首先,要实现...

    使用Android自带的Gallery控件实现CoverFlow

    总结,实现`CoverFlow`效果需要对Android的`Gallery`控件有深入理解,并能够自定义视图和处理动画。虽然Android已不再推荐使用`Gallery`控件,但通过以上步骤和技巧,仍然可以在兼容性良好的项目中实现类似效果。...

    Android实现CoverFlow效果

    总的来说,实现Android的CoverFlow效果需要结合自定义View的绘制、动画处理、性能优化以及用户交互等多个方面。通过以上步骤,开发者可以创建出一个美观且交互性强的CoverFlow组件,提升应用的整体体验。

    iOS coverFlow源代码

    CoverFlow的核心是通过自定义视图控件来创建,它通常继承自`UIScrollView`,因为`UIScrollView`已经内置了滚动和平移的手势识别。在源代码中,开发者可能会使用CATransform3D来实现视图的旋转和缩放,以达到立体翻转...

    Android Coverflow Sample

    在Android应用开发中,Coverflow是一个视觉上吸引人的控件,可以用于展示一系列图像或者卡片,用户可以流畅地左右滑动浏览,给人一种立体翻页的感觉。 在Android开发中,UI设计是至关重要的部分,而Coverflow效果...

    WP7上实现苹果coverflow效果

    通过上述步骤,我们可以创建一个自定义的Coverflow控件,它可以被轻松地嵌入到任何WP7应用程序中。文件名为“wpdever_WP7CoverFlow”的压缩包很可能是包含了实现这一功能的源代码、样例项目以及相关的资源文件,供...

    cover Flow

    在"AlexCoverFlow"这个示例项目中,开发者可能已经封装了一个自定义的Cover Flow控件,包含了上述提到的各种技术。通过研究源代码,我们可以学习如何在Android应用中集成和自定义OpenGL组件,以实现类似Cover Flow的...

    android实现Iphone的coverFlow图片浏览效果

    总结来说,要实现iPhone的CoverFlow图片浏览效果,开发者需要利用Android的`Gallery`控件,结合自定义适配器填充图片数据,可能还需要对`Gallery`进行一定程度的自定义以达到预期的3D视觉效果。同时,利用监听器可以...

Global site tag (gtag.js) - Google Analytics