前言

在项目中遇到了一个画廊展示照片墙效果 支持左右滑动 看起来效果不错!
今天就把这个效果做出来展示一下!

Gallery介绍

/*** A view that shows items in a center-locked, horizontally scrolling list.* <p>* The default values for the Gallery assume you will be using* {@link android.R.styleable#Theme_galleryItemBackground} as the background for* each View given to the Gallery from the Adapter. If you are not doing this,* you may need to adjust some Gallery properties, such as the spacing.* <p>* Views given to the Gallery should use {@link Gallery.LayoutParams} as their* layout parameters type.* * @attr ref android.R.styleable#Gallery_animationDuration* @attr ref android.R.styleable#Gallery_spacing* @attr ref android.R.styleable#Gallery_gravity* * @deprecated This widget is no longer supported. Other horizontally scrolling* widgets include {@link HorizontalScrollView} and {@link android.support.v4.view.ViewPager}* from the support library.*/

在使用这个组件的时候 官方API注明
该类已被弃用,其他水平滚动窗口小部件包括HorizontalScrollView和ViewPager从支持库。
因为这个类是里面的,时间比较久了。虽说被弃用,也只是不再支持后续的更新。


Gallery 是用来水平滚动的显示一系列项目。Gallery组件可以横向显示一个图像列表,当单击当前图像的后一个图像时,这个图像列表会向左移动一格,当单击当前 图像的前一个图像时,这个图像列表会向右移动一样。也可以通过拖动的方式来向左和向右移动图像列表在使用Gallery的时候,我们应指定他的背景,不然 它的项目会紧凑的贴在一起,不会产生画廊的效果了。但是,你也可以通过指定Gallery的属性来设置距离,高度等参数来产生画廊的效果。显然这样做比较 麻烦,除非自定义一些其他效果!


Gallery组件主要用于横向显示图像 列表,不过按常规做法。Gallery组件只能有限地显示指定的图像。也就是说,如果为Gallery组件指定了10张图像,那么当Gallery组件显 示到第10张时,就不会再继续显示了。这虽然在大多数时候没有什么关系,但在某些情况下,我们希望图像显示到最后一张时再重第1张开始显示,也就是循环显 示。要实现这种风格的Gallery组件,就需要对Gallery的Adapter对象进行一番改进。

Gallery使用

想要预期の效果 那就动手完成它吧
自定义View MyGallery 继承画廊类 把我们想要的属性设置一下

public class MyGallery extends Gallery {private int centerPoint;private static final String TAG = "MyGalleryHAHA";private Camera mCamera;private int maxRoate = 60;//旋转的最大角度public MyGallery(Context context) {super(context);mCamera = new Camera();setStaticTransformationsEnabled(true);}public MyGallery(Context context, AttributeSet attrs) {super(context, attrs);mCamera = new Camera();setStaticTransformationsEnabled(true);}public MyGallery(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mCamera = new Camera();setStaticTransformationsEnabled(true);}@Overrideprotected boolean getChildStaticTransformation(View child, Transformation t) {int viewCenterPoint = getItemViewCenterPoint(child);   // item的中心点int rotateAngle = 0;      // 默认旋转角度为0// 如果当前的View的中心点不等于gallery的中心点, 就是两边的图片, 需要计算旋转角度if (viewCenterPoint != centerPoint) {// gallery中心点 - 图片中心点 = 差值int diff = centerPoint - viewCenterPoint;// 差值 / 图片的宽度 = 比值float scale = (float) diff / (float) child.getWidth();// 比值 * 最大旋转角度 = 最终的旋转角度rotateAngle = (int) (scale * maxRoate);if (Math.abs(rotateAngle) > maxRoate) {    // 当前角度超过了50, 需要赋值到50 或者 -50rotateAngle = rotateAngle > 0 ? maxRoate : -maxRoate;}}// 设置变换效果之前, 需要把Transformation中的上一个item的变换效果清楚t.clear();t.setTransformationType(Transformation.TYPE_MATRIX);   // 设置变换效果的类型为矩阵类型setItemStartAnim((ImageView) child, rotateAngle, t);return true;}/*** 设置变换效果** @param iv          gallery的item* @param rotateAngle 旋转的角度* @param t           变换的对象*/private void setItemStartAnim(ImageView iv, int rotateAngle, Transformation t) {mCamera.save();       // 保存状态int absRotateAngle = Math.abs(rotateAngle);    // 取旋转角度的绝对值// 放大效果mCamera.translate(0, 0, 100f);    // 给摄像机定位int zoom = -240 + (absRotateAngle * 2);mCamera.translate(0, 0, zoom);// 透明度(中间的图片是完全显示, 两边有一定的透明度)int alpha = (int) (255 - (absRotateAngle * 2.5));iv.setAlpha(alpha);       // 透明度取值范围: 0 ~ 255, 0 就是完全隐藏, 255 完全显示// 旋转(在中间的图片没有旋转角度, 只要不在中间就有旋转角度)mCamera.rotateY(rotateAngle);Matrix matrix = t.getMatrix();     // 变换的矩阵, 需要把变换的效果添加到矩阵中// 给matrix赋值mCamera.getMatrix(matrix);    // 把matrix矩阵给camera对象, camera对象就会把上面添加的效果转换成矩阵添加到matrix对象中// 矩阵前乘matrix.preTranslate(-iv.getWidth() >> 1, -iv.getHeight() >> 1);// 矩阵后乘matrix.postTranslate(iv.getWidth() >> 1, iv.getHeight() >> 1);mCamera.restore(); // 恢复到之前保存的状态}/*** 获取gallery的中心点** @return*/public int getCenterPoint() {return getWidth() / 2;}/*** 获取item  view的中心点*/public int getItemViewCenterPoint(View itemView) {if (itemView != null) {return itemView.getWidth() / 2 + itemView.getLeft();}return 0;}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);centerPoint = getCenterPoint();}
}

完成自定义View MyGallery 后

如何使用?
如果为Gallery组件指定了10张图像,那么当Gallery组件显 示到第10张时,就不会再继续显示了。这虽然在大多数时候没有什么关系,但在某些情况下,我们希望图像显示到最后一张时再重第1张开始显示,也就是循环显示。

public class InviteShareActivity extends AppCompatActivity {private int[] ids = {R.mipmap.image_1, R.mipmap.image_2, R.mipmap.image_3, R.mipmap.image_4, R.mipmap.image_5,R.mipmap.image_6, R.mipmap.image_7, R.mipmap.image_8, R.mipmap.image_9, R.mipmap.image_10};private Unbinder mUnbinder;@BindView(R.id.toolbar)Toolbar mToolbar;@BindView(R.id.gallery)MyGallery gallery;private int screenWidth;private int screenHeigh;private int count;//记录画廊图数@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_invite_share);StatusBarUtils.transparencyBar(this);mUnbinder = ButterKnife.bind(this);setSupportActionBar(mToolbar);Objects.requireNonNull(getSupportActionBar()).setDisplayShowTitleEnabled(false);ActivityUtils.addToolbarTitle(this, mToolbar, "仿3D画廊");mToolbar.setNavigationOnClickListener(v -> onBackPressed());getScreenWidthAndHeight();MyAdapter adapter = new MyAdapter();gallery.setAdapter(adapter);gallery.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {ToastUtils.showShort(InviteShareActivity.this, "您点击了第" + position + "张画廊图");}});}/*** 内部Adapter*/class MyAdapter extends BaseAdapter {public MyAdapter() {count = ids.length;//用于照片循环滑动}@Overridepublic int getCount() {return Integer.MAX_VALUE;//用于循环滑动}@Overridepublic Object getItem(int position) {return position;}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ImageView iv = null;position = position % count;if (convertView == null) {iv = new ImageView(InviteShareActivity.this);} else {iv = (ImageView) convertView;}Bitmap bitmap = AppUtils.compoundBitmap(getResources(), ids[position]);BitmapDrawable bd = new BitmapDrawable(bitmap);bd.setAntiAlias(true);    // 消除锯齿iv.setImageDrawable(bd);Gallery.LayoutParams params = new Gallery.LayoutParams(screenWidth / 2, screenHeigh / 2);iv.setLayoutParams(params);return iv;}}/*** 获取屏幕的宽和高*/public void getScreenWidthAndHeight() {DisplayMetrics dm = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(dm);screenWidth = dm.widthPixels;screenHeigh = dm.heightPixels;}@Overrideprotected void onDestroy() {super.onDestroy();mUnbinder.unbind();}
}

总结

重新学习了一下自定义View 把自定义的属性又用了一次
效果还可以的 完成后 心情还是很高兴地!

共勉

我要一步一步往上爬
在最高点乘着叶片往前飞
任风吹干流过的泪和汗
我要一步一步往上爬
等待阳光静静看着它的脸
小小的天有大大的梦想
我有属于我的天
任风吹干流过的泪和汗
总有一天我有属于我的天

Android 使用Gallery仿3D画廊效果实现相关推荐

  1. Android自带组件之Gallery 实现3D画廊效果

    1: 首先我们要了解到这个该控件的常用属性: 如图: 2:通过该组件定义属于我们自己的组件 iphone 中的coverflow中图片切换是有旋转和缩放效果的,而自带的gallery中并没有实现.因此 ...

  2. Android实现动态贴纸,Android开发之仿微博贴纸效果实现——进阶篇

    上个月写了一篇<Android开发之仿微博贴纸效果实现--基础篇>,文章中提到还有一篇进阶篇要写,很早就想动笔了,因中途去维护了开源库<高仿微信图片选择器2.0版本>,导致耽搁 ...

  3. [原创]自定义ViewPager实现3D画廊效果

    经常在群里看到有些开发者在提问:怎么实现3D画廊效果,没思路. 有人出谋划策,你重写onTouch,在里面去判断:或者你去重写滑动监听事件,滑动的时候去动态设置左右两边的图片的大小和缩放效果.可能你们 ...

  4. android+仿iphone,Android编程实现仿iphone抖动效果的方法(附源码)

    Android编程实现仿iphone抖动效果的方法(附源码) 时间:2021-05-20 本文实例讲述了Android编程实现仿iphone抖动效果的方法.分享给大家供大家参考,具体如下: 布局文件: ...

  5. android左右旋转动画效果图,Android新姿势:3D翻转效果原理

    首先,android里是没有3D翻转的动画效果的,但是呢,android有提供一个Camera的类,可以利用这个类来实现. 先看代码,Rotate3d是继承了Animation的一个动画类,多余的代码 ...

  6. 使用RecyclerView实现旋转3D画廊效果

    3D旋转画廊效果实现有哪些方式? 1.Gallery实现(官方已不推荐使用). 2.RecyclerView通过自定义LayoutManager实现. 一.简介 RecyclerView是google ...

  7. android画廊效果的轮播图,轮播图(3d画廊效果)

    首先需要将轮播图的依赖导入 implementation 'com.github.xiaohaibin:XBanner:1.6.1' 接下来就是在项目目录下bulidgradle中导入(allproj ...

  8. android 高仿ios开关,Android自定义view仿IOS开关效果

    本文主要讲解如何在 Android 下实现高仿 iOS 的开关按钮,并非是在 Android 自带的 ToggleButton 上修改,而是使用 API 提供的 onDraw.onMeasure.Ca ...

  9. XBanner实现3D画廊效果

    导依赖 在工程的build.gradle中allprojects {repositories {google()jcenter()maven { url 'https://jitpack.io' }} ...

  10. Gallery的基本使用(实现了3D画廊的效果)

    Gallery是一个内部元素可以水平滚动,并且可以把当前选择的子元素定位在它中心的布局组件.下面是一个实现3D画廊的小demo MainActivity.class package com.czh.g ...

最新文章

  1. 活动排序工具之双代号网络(AOA)与单代号网络(AON)[cont.]
  2. 从千万级数据查询来聊一聊索引结构和数据库原理
  3. 面试题php2018,2018php最新面试题之PHP核心技术
  4. C++学习之路—继承与派生(四)拓展与总结
  5. 通宵加班的产品经理,为什么我不建议你买保险?
  6. 张一鸣:优秀年轻人的五个特点
  7. 3分钟让你轻松了解CRM
  8. 【bzoj 十连测】[noip2016十连测第三场]Problem C: 序列(静态主席树)
  9. XP共享拒绝访问,全面解决
  10. qc是什么职位_质量管理部门该干什么?又该怎么干?
  11. Merge into的使用详解-你Merge了没有【转】
  12. 【神经网络】基于RBF神经网络的六关节机械臂无模型控制
  13. android sdk环境配置_Mac 配置adb环境的方法
  14. .NET 中的对象序列化
  15. HTML5七夕情人节表白网页(全屏七夕表白页面滚动模板) HTML+CSS+JavaScript
  16. 南京大学计算机学硕博士,2019年南京大学计算机软件研究所招收研究生说明
  17. [html5游戏开发]数独游戏-完整算法-开源讲座
  18. 【PC页面设计项目】宠物物流页面设计(源码+图示)
  19. 培养创造性思维的20个技巧!
  20. 基于sinc的音频重采样(一):原理

热门文章

  1. 常用网络测试的命令的实验报告计算机网络,实验一常用网络命令的使用实验报告-20210409133504.docx-原创力文档...
  2. redis击穿、redis雪崩、redis穿透
  3. Excel将汉字与英文分开
  4. codecombat极客战记森林61-70通关代码
  5. imresize函数进行图像缩放及利用imrotate进行图像旋转
  6. html新年倒计时特效,js实现新年倒计时效果
  7. DirectX11--HR宏关于dxerr库的替代方案
  8. 光纤通信是不是计算机类的,光纤通信专业属于什么门类
  9. 机房(计算机室)管理制度,湖南石油化工职业技术学院-信息资源中心-管理制度-计算机机房管理制度...
  10. 计算机操作系统有几种基本管理,操作系统有哪些管理功能