转载请注明出处:http://blog.csdn.net/u014608640/article/details/52472370

前言:因为要做一个设置开机画面的功能,主要是让用户可以设置自己的开机画面,应用层需要做让用户选择开机画面图片的功能。所以需要做一个简单的图片浏览选择程序。最后选用Gallery作为基本控件。加入了一些炫一点的元素,做成3D滑动效果。下面是Demo例子截图:

效果网上已经很多人做出来了,只是这次需要用到,所以自己也实践了一下(这里例子我也是根据网上一些资料编写)。特下面针对一些关键代码进行简要说明,需要做这方面东西的朋友可以看看。这篇文章是实用性文章,理论分析不多。

下面说下具体的类作用:

一:这个是主页:操作的内容不多,可以具体看一下

public class MainActivity extends Activity {DisplayImageOptions options;private ImageLoader imageLoader;private FancyCoverFlow fancyCoverFlow;private List<FilmInfo> filmList;private ImageAdapter adapter;private int cur_index = 0;private int count_drawble;private static int MSG_UPDATE = 1;// 定时任务private ScheduledExecutorService scheduledExecutorService;// 通过handler来更新主界面private Handler handler = new Handler() {public void handleMessage(Message msg) {if (msg.what == MSG_UPDATE) {fancyCoverFlow.setSelection(cur_index);}}};public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);filmList = FilmInfoTest.getfilmInfo();Log.i("INFO", filmList.size()+"条目数");// 配置optionoptions = new DisplayImageOptions.Builder().showStubImage(R.drawable.logo).showImageForEmptyUri(R.drawable.logo).showImageOnFail(R.drawable.ic_error).cacheInMemory(true).cacheOnDisc(true).bitmapConfig(Bitmap.Config.RGB_565).build();imageLoader = ImageLoader.getInstance();adapter = new ImageAdapter(this, filmList, options, imageLoader);fancyCoverFlow = (FancyCoverFlow) findViewById(R.id.fancyCoverFlow);// item之间的间隙可以近似认为是imageview的宽度与缩放比例的乘积的一半fancyCoverFlow.setSpacing(-180);fancyCoverFlow.setAdapter(adapter);fancyCoverFlow.setSelection(1002);
//      fancyCoverFlow.setActionDistance(10);fancyCoverFlow.setOnItemSelectedListener(new OnItemSelectedListener() {@Overridepublic void onItemSelected(AdapterView<?> parent, View view,int position, long id) {cur_index = position;}@Overridepublic void onNothingSelected(AdapterView<?> parent) {}});// 点击事件fancyCoverFlow.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view,int position, long id) {// TODO Auto-generated method stubToast.makeText(MainActivity.this,filmList.get(position % filmList.size()).getFilmName(),0).show();}});//        // 开启自动轮播
//      count_drawble = adapter.getCount();
//      startPlay();}/*** 开始轮播图切换*/private void startPlay() {scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();scheduledExecutorService.scheduleAtFixedRate(new AutoPlayTask(), 1, 4,TimeUnit.SECONDS);}/*** 停止轮播图切换*/private void stopPlay() {scheduledExecutorService.shutdown();}/*** 执行轮播图切换任务* */private class AutoPlayTask implements Runnable {@Overridepublic void run() {//            cur_index = cur_index % count_drawble; // 图片区间[0,count_drawable)
//          Message msg = handler.obtainMessage(MSG_UPDATE);
//          handler.sendMessage(msg);
//          cur_index++;}}@Overrideprotected void onStop() {imageLoader.stop();super.onStop();}

二:适配器

这里我主要是用本地资源进行测试了一下,设置了倒影等等,当然,你也可以改为xml布局设置图片的

public class ImageAdapter extends FancyCoverFlowAdapter {private Context context;private List<FilmInfo> filmList;
//  private ImageLoader imageLoader;
//  private DisplayImageOptions options;public ImageAdapter(Context context, List<FilmInfo> filmList,DisplayImageOptions options, ImageLoader imageLoader) {this.context = context;this.filmList = filmList;
//      this.options = options;
//      this.imageLoader = imageLoader;}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn Integer.MAX_VALUE;}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn filmList.get(position);
//      return position;}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position % filmList.size();
//      return position;}@Overridepublic View getCoverFlowItem(int position, View reusableView,ViewGroup parent) {ImageView imageView = (ImageView) reusableView;if (imageView == null) {imageView = new ImageView(context);}Resources re = context.getResources();InputStream is = re.openRawResource(filmList.get(position%filmList.size()).getRs());
//      InputStream is = re.openRawResource(mImagesId[position%mImagesId.length]);BitmapDrawable mapdraw = new BitmapDrawable(is);Bitmap bitmap = mapdraw.getBitmap();imageView.setImageBitmap(BitmapUtil.createReflectedBitmap(bitmap));
//      imageView.setImageBitmap(bitmap);// ps.电影海报宽高比例一般为3:4imageView.setLayoutParams(new Gallery.LayoutParams(410, 713));//        // 异步加载图片
//      imageLoader.displayImage(filmList.get(position % filmList.size())
//              .getFilmImageLink(), imageView, options);imageView.setScaleType(ScaleType.CENTER_CROP);return imageView;}public Integer[] getImagesId(){return mImagesId;}public void setImagesId(Integer[] mImagesId){this.mImagesId = mImagesId;}private Integer mImagesId[] = {R.drawable.ic_1,R.drawable.ic_3,R.drawable.ic_2,       R.drawable.ic_4,R.drawable.ic_5};

三:gallery 控件类

缩放,还有透明,等等都在这里设置

public class FancyCoverFlow extends Gallery {public static final int ACTION_DISTANCE_AUTO = Integer.MAX_VALUE;/*** 图片向上突出,可以通过代码控制,也可以在xml上控制*/public static final float SCALEDOWN_GRAVITY_TOP = 0.0f;/*** 图片中间突出*/public static final float SCALEDOWN_GRAVITY_CENTER = 0.5f;/*** 图片向下突出*/public static final float SCALEDOWN_GRAVITY_BOTTOM = 1.0f;private float reflectionRatio = 0.3f;private int reflectionGap = 4;private boolean reflectionEnabled = false;private float unselectedAlpha;private Camera transformationCamera;private int maxRotation = 0;private float unselectedScale;private float scaleDownGravity = SCALEDOWN_GRAVITY_CENTER;private int actionDistance;private float unselectedSaturation;public FancyCoverFlow(Context context) {super(context);this.initialize();}public FancyCoverFlow(Context context, AttributeSet attrs) {super(context, attrs);this.initialize();this.applyXmlAttributes(attrs);}@SuppressLint("NewApi")public FancyCoverFlow(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);if (Build.VERSION.SDK_INT >= 11) {this.setLayerType(LAYER_TYPE_SOFTWARE, null);}this.initialize();this.applyXmlAttributes(attrs);}private void initialize() {this.transformationCamera = new Camera();this.setSpacing(0);}private void applyXmlAttributes(AttributeSet attrs) {TypedArray a = getContext().obtainStyledAttributes(attrs,R.styleable.FancyCoverFlow);this.actionDistance = a.getInteger(R.styleable.FancyCoverFlow_actionDistance,ACTION_DISTANCE_AUTO);this.scaleDownGravity = a.getFloat(R.styleable.FancyCoverFlow_scaleDownGravity, 0.5f);this.maxRotation = a.getInteger(R.styleable.FancyCoverFlow_maxRotation,0);this.unselectedAlpha = a.getFloat(R.styleable.FancyCoverFlow_unselectedAlpha, 0.5f);this.unselectedSaturation = a.getFloat(R.styleable.FancyCoverFlow_unselectedSaturation, 0.0f);this.unselectedScale = a.getFloat(R.styleable.FancyCoverFlow_unselectedScale, 0.75f);}public float getReflectionRatio() {return reflectionRatio;}public void setReflectionRatio(float reflectionRatio) {if (reflectionRatio <= 0 || reflectionRatio > 0.5f) {throw new IllegalArgumentException("reflectionRatio may only be in the interval (0, 0.5]");}this.reflectionRatio = reflectionRatio;if (this.getAdapter() != null) {((FancyCoverFlowAdapter) this.getAdapter()).notifyDataSetChanged();}}public int getReflectionGap() {return reflectionGap;}public void setReflectionGap(int reflectionGap) {this.reflectionGap = reflectionGap;if (this.getAdapter() != null) {((FancyCoverFlowAdapter) this.getAdapter()).notifyDataSetChanged();}}public boolean isReflectionEnabled() {return reflectionEnabled;}public void setReflectionEnabled(boolean reflectionEnabled) {this.reflectionEnabled = reflectionEnabled;if (this.getAdapter() != null) {((FancyCoverFlowAdapter) this.getAdapter()).notifyDataSetChanged();}}@Overridepublic void setAdapter(SpinnerAdapter adapter) {if (!(adapter instanceof FancyCoverFlowAdapter)) {throw new ClassCastException(FancyCoverFlow.class.getSimpleName()+ " only works in conjunction with a "+ FancyCoverFlowAdapter.class.getSimpleName());}super.setAdapter(adapter);}public int getMaxRotation() {return maxRotation;}public void setMaxRotation(int maxRotation) {this.maxRotation = maxRotation;}public float getUnselectedAlpha() {return this.unselectedAlpha;}public float getUnselectedScale() {return unselectedScale;}public void setUnselectedScale(float unselectedScale) {this.unselectedScale = unselectedScale;}public float getScaleDownGravity() {return scaleDownGravity;}public void setScaleDownGravity(float scaleDownGravity) {this.scaleDownGravity = scaleDownGravity;}public int getActionDistance() {return actionDistance;}public void setActionDistance(int actionDistance) {this.actionDistance = actionDistance;}@Overridepublic void setUnselectedAlpha(float unselectedAlpha) {super.setUnselectedAlpha(unselectedAlpha);this.unselectedAlpha = unselectedAlpha;}public float getUnselectedSaturation() {return unselectedSaturation;}public void setUnselectedSaturation(float unselectedSaturation) {this.unselectedSaturation = unselectedSaturation;}public int preLeftOffset = 0;public int count = 0;public boolean isPlayDraw = true;@Overrideprotected boolean getChildStaticTransformation(View child, Transformation t) {FancyCoverFlowItemWrapper item = (FancyCoverFlowItemWrapper) child;preLeftOffset = getChildAt(0).getLeft();if (android.os.Build.VERSION.SDK_INT >= 16) {item.postInvalidate();}final int coverFlowWidth = this.getWidth();final int coverFlowCenter = coverFlowWidth / 2;final int childWidth = item.getWidth();final int childHeight = item.getHeight();final int childCenter = item.getLeft() + childWidth / 2;final int actionDistance = (this.actionDistance == ACTION_DISTANCE_AUTO) ? (int) ((coverFlowWidth + childWidth) / 2.0f): this.actionDistance;float effectsAmount = Math.min(1.0f,Math.max(-1.0f, (1.0f / actionDistance)* (childCenter - coverFlowCenter)));t.clear();t.setTransformationType(Transformation.TYPE_BOTH);if (this.unselectedAlpha != 1) {final float alphaAmount = (this.unselectedAlpha - 1)* Math.abs(effectsAmount) + 1;t.setAlpha(alphaAmount);}if (this.unselectedSaturation != 1) {// Pass over saturation to the wrapper.final float saturationAmount = (this.unselectedSaturation - 1)* Math.abs(effectsAmount) + 1;item.setSaturation(saturationAmount);}final Matrix imageMatrix = t.getMatrix();// 旋转角度不为0则开始图片旋转.if (this.maxRotation != 0) {final int rotationAngle = (int) (-effectsAmount * this.maxRotation);this.transformationCamera.save();this.transformationCamera.rotateY(rotationAngle);this.transformationCamera.getMatrix(imageMatrix);this.transformationCamera.restore();}// 缩放.if (this.unselectedScale != 1) {final float zoomAmount = 1f / 2f * (1 - Math.abs(effectsAmount))* (1 - Math.abs(effectsAmount))* (1 - Math.abs(effectsAmount)) + 0.5f;final float translateX = childWidth / 2.0f;final float translateY = childHeight * this.scaleDownGravity;imageMatrix.preTranslate(-translateX, -translateY);imageMatrix.postScale(zoomAmount, zoomAmount);imageMatrix.postTranslate(translateX, translateY);if (effectsAmount != 0) {double point = 0.4;double translateFactor = (-1f / (point * point)* (Math.abs(effectsAmount) - point)* (Math.abs(effectsAmount) - point) + 1)* (effectsAmount > 0 ? 1 : -1);imageMatrix.postTranslate((float) (ViewUtil.Dp2Px(getContext(), 25) * translateFactor),0);}}return true;}// 绘制顺序,先从左到中间,再从右到中间@Overrideprotected int getChildDrawingOrder(int childCount, int i) {int selectedIndex = getSelectedItemPosition()- getFirstVisiblePosition();if (i < selectedIndex) {return i;} else if (i >= selectedIndex) {return childCount - 1 - i + selectedIndex;} else {return i;}}private boolean isTouchAble = true;public void disableTouch() {isTouchAble = false;}public void enableTouch() {isTouchAble = true;}public boolean isTouchAble() {return isTouchAble;}@Overridepublic boolean onTouchEvent(MotionEvent event) {count = 0;for (int i = 0; i < getChildCount(); i++) {getChildAt(i).invalidate();}if (isTouchAble) {return super.onTouchEvent(event);} else {return false;}}@Overridepublic boolean onInterceptTouchEvent(MotionEvent event) {if (isTouchAble) {return super.onInterceptTouchEvent(event);} else {return true;}}//// @Override// public boolean onSingleTapUp(MotionEvent e) {// return false;// }// 使快速滑动失效@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) {return false;}

四:倒影

reflectionGap 处理图片和倒影之间的间距。
/*** grallery 倒影放大操作类*/
public class MyImgView {/*** 添加倒影,原理,先翻转图片,由上到下放大透明度** @param originalImage* @return*/public static Bitmap createReflectedImage(Bitmap originalImage) {// The gap we want between the reflection and the original imagefinal int reflectionGap = 4;int width = originalImage.getWidth();int height = originalImage.getHeight();// This will not scale but will flip on the Y axisMatrix matrix = new Matrix();matrix.preScale(1, -1);// Create a Bitmap with the flip matrix applied to it.// We only want the bottom half of the imageBitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,height / 2, width, height / 2, matrix, false);// Create a new bitmap with same width but taller to fit reflectionBitmap bitmapWithReflection = Bitmap.createBitmap(width,(height + height /4), Config.ARGB_8888);// Create a new Canvas with the bitmap that's big enough for// the image plus gap plus reflectionCanvas canvas = new Canvas(bitmapWithReflection);// Draw in the original imagecanvas.drawBitmap(originalImage, 0, 0, null);// Draw in the gapPaint defaultPaint = new Paint();canvas.drawRect(0, height, width, height + reflectionGap, defaultPaint);// Draw in the reflectioncanvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);// Create a shader that is a linear gradient that covers the reflectionPaint paint = new Paint();LinearGradient shader = new LinearGradient(0,originalImage.getHeight(), 0, bitmapWithReflection.getHeight()+ reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP);// Set the paint to use this shader (linear gradient)paint.setShader(shader);// Set the Transfer mode to be porter duff and destination in 倒影底部颜色深浅变化paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));// Draw a rectangle using the paint with our linear gradientcanvas.drawRect(0, height, width, bitmapWithReflection.getHeight()+ reflectionGap, paint);return bitmapWithReflection;}//drawable 类型转化为bitmappublic static Bitmap drawableToBitmap(Drawable drawable) {Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight(),drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888: Bitmap.Config.RGB_565);Canvas canvas = new Canvas(bitmap);// canvas.setBitmap(bitmap);drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());drawable.draw(canvas);return bitmap;}

Ps:主要就是这些个类,大家可以修改成为自己想要的效果,如有问题,可以评论问我!

具体下载地址:Android 控制3D酷炫效果

Android控件开发之Gallery3D酷炫效果(带源码)相关推荐

  1. Android 控件开发之ToggleButton

    ToggleButton有两种状态:选中和未选择状态,并且需要为不同的状态设置不同的显示文本 ToggleButton效果: 本程序main.xml源码   <?xml version=&quo ...

  2. 仿酷狗音乐播放器开发日志二十三 修复Option控件显示状态不全的bug(附源码)...

    转载请说明原出处,谢谢~~ 整个仿酷狗工程的开发将近尾声,现在还差选项设置窗体的部分,显然在设置窗体里用的最多的就是OptionUI控件,我在写好大致的布局后去测试效果,发现Option控件的显示效果 ...

  3. 【博主推荐】星空版的九宫格酷炫抽奖HTML源码

    文章目录 1.星空版的九宫格酷炫抽奖 1.1 效果图 1.2 源码展示 1.2.1 全部代码示意图 1.2.1 主界面html 完整源码下载 文章说明,抽奖界面,应用比较广泛 , 所以今天博主就带领大 ...

  4. (自适应手机端)响应式高端摄影网站pbootcms模板 黑色酷炫数码摄影网站源码下载

    (自适应手机端)响应式高端摄影网站pbootcms模板 黑色酷炫数码摄影网站源码下载 PbootCMS内核开发的网站模板,该模板适摄影网站.数码摄影网站等企业,当然其他行业也可以做,只需要把文字图片换 ...

  5. 仿酷狗音乐播放器开发日志十八——换肤功能的实现二:改变控件和窗体透明度(附挂件类源码)...

    转载请说明原出处,谢谢~~ 昨天把大致布局分析了一下,昨天晚上把布局写好实现了,今天把大致的功能完成了一下,现在的外观已经和原酷狗的换肤界面完全一样,其中的调整播放列表透明度和设置整个软件透明度的代码 ...

  6. 仿酷狗音乐播放器开发日志十八——换肤功能的实现二:改变控件和窗体透明度(附挂件类源码)

    转载请说明原出处,谢谢~~ 昨天把大致布局分析了一下,昨天晚上把布局写好实现了,今天把大致的功能完成了一下,现在的外观已经和原酷狗的换肤界面完全一样,其中的调整播放列表透明度和设置整个软件透明度的代码 ...

  7. Android开发之Theme、Style探索及源码浅析

    1 背景 前段时间群里有伙伴问到了关于Android开发中Theme与Style的问题,当然,这类东西在网上随便一搜一大把模板,所以关于怎么用的问题我想这里也就不做太多的说明了,我们这里把重点放在理解 ...

  8. Discuz!NT控件剖析 之 DataGrid(数据列表) [原创: 附源码]

    自从 9月未开始写关于"ICONIX方法"的系列文章以来,到今天已有两个多月了,当初因为兴趣点的转移才划一 段落的Discuz!NT 系列文章,从今天开始又要开始续写了.这写这个系 ...

  9. [HTML5CSS3]20 个酷炫 应用及源码

     1.HTML5视频破碎重组特效,强大视觉冲击 HTML5视频播放器很多,但是HTML5视频特效还是很少见的,这款HTML5视频破碎重组特效非常刺激,给人强大的视觉冲击.点击视频任意地方,HTML ...

  10. Android控件美化Shape

    Android控件美化Shape你会用吗?   -- 未审核 编辑文档  如果你对Android系统自带的UI控件感觉不够满意,可以尝试下自定义控件,我们就以Button为例,很早以前Android1 ...

最新文章

  1. 网站禁止复制怎样操作
  2. configure: error: no acceptable C compiler found in $PATH
  3. python hibernate_将Java/MVC/Hibernate webapp移植到Python
  4. #51CTO学院四周年#其实、其实,我就是来吐槽的”
  5. Java读取指定路径下的文件列表
  6. java实验33 类的继承2_java实验2 类的继承性
  7. 「独家」五面阿里P6:Java开发面试题及答案
  8. 简明 XHTML 1.0 参考手册
  9. activitemq与spring的整合
  10. Docker中的Nginx搭建HTTPS环境
  11. php 查找键名,array_key_exists()函数搜索数组键名步骤详解
  12. 【英语学习】【WOTD】abstruse 释义/词源/示例
  13. ad软件侵权律师函_专业版,无AD无限制,建议收藏~
  14. 三菱modbusRTU通讯实例_PLC编程实例 | 讲解食品和药品成型案例程序!
  15. Excel表格常用函数
  16. windows设置路径Path
  17. mysql 中caption_ACCESS数据库中Field对象的caption属性读写
  18. 练习3 - 铲雪车(snow)
  19. Leetcode.365 水壶问题
  20. 好社群的选择标准是什么?如何创建付费社群渠道?

热门文章

  1. Tomcat下载——tomcat7、tomcat8、tomcat9官网下载链接
  2. 论学好数学对机器学习的重要性
  3. 如何安装Pycharm和汉化包(包括安装软件,无广告)
  4. mac原版镜像下载 macos官方镜像下载
  5. 前端根据银行卡号或银行的简码动态显示logo图标
  6. 微信小程序接入海康威视萤石云直播
  7. 计算机网络面试题总结
  8. 一文搞懂利用Flask-Babel实现网页多语言翻译切换
  9. 使用LibreOffice的Draw取代Microsoft visio
  10. 用html制作简易网页