前言

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

Gallery介绍

/** * A view that shows items in a center-locked, horizontally scrolling list. * 

* 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. *

* 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);    }    @Override    protected 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 或者 -50                rotateAngle = 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;    }    @Override    protected 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;//记录画廊图数    @Override    protected 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() {            @Override            public 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;//用于照片循环滑动        }        @Override        public int getCount() {            return Integer.MAX_VALUE;//用于循环滑动        }        @Override        public Object getItem(int position) {            return position;        }        @Override        public long getItemId(int position) {            return position;        }        @Override        public 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;    }    @Override    protected void onDestroy() {        super.onDestroy();        mUnbinder.unbind();    }}

总结

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

共勉

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

更多相关文章

  1. 面试例题6:两种方法将图像显示在View上
  2. ListView的一些属性
  3. Android(安卓)动画效果 --Animation 动画专题研究
  4. android开发之给LinearLayout增加点击效果
  5. Android(安卓)导航条效果实现(四) ViewPager+自定义导航条
  6. Android——SpannableString上标,下标垂直对齐
  7. Android的CheckBox控件的点击效果布局文件
  8. 设置ProgressBar的颜色
  9. Android(安卓)九宫格图片展示的实现

随机推荐

  1. 1024 小鹿自费给读者送书啦!
  2. COVID-19每日数据|04-09
  3. 【决战西二旗】|理解标准模板库STL(一)
  4. 我常用的10个Python实用小Trick
  5. 图解:什么是 JS 原型和原型链?
  6. Pandas进阶修炼120题同步视频现已登陆
  7. 【决战西二旗】|你真的懂快速排序?
  8. 词云图的几种制作方法评测,你pick哪款
  9. 动画:用动画给女朋友讲解 TCP 四次分手过
  10. 浅谈集群版Redis和Gossip协议