服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - Android编程滑动效果之倒影效果实现方法(附demo源码下载)

Android编程滑动效果之倒影效果实现方法(附demo源码下载)

2021-05-27 15:32阳光岛主 Android

这篇文章主要介绍了Android编程滑动效果之倒影效果实现方法,基于继承BaseAdapter自定义Gallery和ImageAdapter实现倒影的功能,并附带demo源码供读者下载参考,需要的朋友可以参考下

本文实例讲述了android编程滑动效果之倒影效果实现方法。分享给大家供大家参考,具体如下:

前面介绍了使用《android编程实现3d滑动旋转效果的方法》,现在介绍图片倒影实现,先看效果图

Android编程滑动效果之倒影效果实现方法(附demo源码下载)

这里主要通过自定义gallery和imageadapter(继承自baseadapter)实现

1、倒影绘制

imageadapter继承自baseadapter,详细实现可见前面关于android gallery的用法。这里重点介绍倒影原理及实现

倒影原理:

倒影效果是主要由原图+间距+倒影三部分组成,高度大约为原图的3/2(原图为1、倒影为1/2)
原图,就是我们看到了最开始的图片
间距,是原图与倒影之间的间隙,如:reflectiongap = 4;
倒影,是原图下半部分1/2高度,通过矩阵变换matrix.prescale(1, -1); 获取倒立图片,然后再加上线性遮罩和阴影实现

倒影实现:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/** 反射倒影 */
public boolean createreflectedimages() {
  final int reflectiongap = 4;
  int index = 0;
  for (map<string, object> map : list) {
    integer id = (integer) map.get("image");
    bitmap originalimage = bitmapfactory.decoderesource(mcontext.getresources(), id); // 获取原始图片
    int width = originalimage.getwidth();
    int height = originalimage.getheight();
    matrix matrix = new matrix();
    matrix.prescale(1, -1); // 图片矩阵变换(从低部向顶部的倒影)
    bitmap reflectionimage = bitmap.createbitmap(originalimage, 0, height/2, width, height/2, matrix, false); // 截取原图下半部分
    bitmap bitmapwithreflection = bitmap.createbitmap(width, (height + height / 2), config.argb_8888); // 创建倒影图片(高度为原图3/2)
    canvas canvas = new canvas(bitmapwithreflection); // 绘制倒影图(原图 + 间距 + 倒影)
    canvas.drawbitmap(originalimage, 0, 0, null); // 绘制原图
    paint paint = new paint();
    canvas.drawrect(0, height, width, height + reflectiongap, paint); // 绘制原图与倒影的间距
    canvas.drawbitmap(reflectionimage, 0, height + reflectiongap, null); // 绘制倒影图
    paint = new paint();
    lineargradient shader = new lineargradient(0, originalimage.getheight(), 0, bitmapwithreflection.getheight() + reflectiongap, 0x70ffffff, 0x00ffffff, tilemode.clamp);
    paint.setshader(shader); // 线性渐变效果
    paint.setxfermode(new porterduffxfermode(mode.dst_in)); // 倒影遮罩效果
    canvas.drawrect(0, height, width, bitmapwithreflection.getheight() + reflectiongap, paint); // 绘制倒影的阴影效果
    imageview imageview = new imageview(mcontext);
    imageview.setimagebitmap(bitmapwithreflection); // 设置倒影图片
    imageview.setlayoutparams(new mygallery.layoutparams(180, 240));
    imageview.setscaletype(scaletype.matrix);
    mimages[index++] = imageview;
  }
  return true;
}

2、mygallery

自定义gallery来实现倒影图片的浏览与选择

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
public class mygallery extends gallery {
  private camera mcamera = new camera();
  private int mmaxrotationangle = 60; // 最大旋转角度 60
  private int mmaxzoom = -120;
  private int mcoveflowcenter;
  public mygallery(context context) {
    super(context);
    this.setstatictransformationsenabled(true);
  }
  public mygallery(context context, attributeset attrs) {
    super(context, attrs);
    this.setstatictransformationsenabled(true);
  }
  public mygallery(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 int getmaxzoom() {
    return mmaxzoom;
  }
  public void setmaxzoom(int maxzoom) {
    mmaxzoom = maxzoom;
  }
  /** 获取gallery的中心x */
  private int getcenterofcoverflow() {
    return (getwidth() - getpaddingleft() - getpaddingright()) / 2 + getpaddingleft();
  }
  /** 获取view的中心x */
  private static int getcenterofview(view view) {
    return view.getleft() + view.getwidth() / 2;
  }
  @override
  protected void onsizechanged(int w, int h, int oldw, int oldh) {
    mcoveflowcenter = getcenterofcoverflow();
    super.onsizechanged(w, h, oldw, oldh);
  }
  @override
  protected boolean getchildstatictransformation(view child, transformation trans) {
    final int childcenter = getcenterofview(child);
    final int childwidth = child.getwidth();
    int rotationangle = 0;
    trans.clear();
    trans.settransformationtype(transformation.type_both); // alpha 和 matrix 都变换
    if (childcenter == mcoveflowcenter) { // 正中间的childview
      transformimagebitmap((imageview) child, trans, 0);
    } else { // 两侧的childview
      rotationangle = (int) ( ( (float) (mcoveflowcenter - childcenter) / childwidth ) * mmaxrotationangle );
      if (math.abs(rotationangle) > mmaxrotationangle) {
        rotationangle = (rotationangle < 0) ? -mmaxrotationangle : mmaxrotationangle;
      }
      transformimagebitmap((imageview) child, trans, rotationangle);
    }
    return true;
  }
  private void transformimagebitmap(imageview child, transformation trans, int rotationangle) {
    mcamera.save();
    final matrix imagematrix = trans.getmatrix();
    final int imageheight = child.getlayoutparams().height;
    final int imagewidth = child.getlayoutparams().width;
    final int rotation = math.abs(rotationangle);
    // 在z轴上正向移动camera的视角,实际效果为放大图片; 如果在y轴上移动,则图片上下移动; x轴上对应图片左右移动。
    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);
    }
    mcamera.rotatey(rotationangle); // rotationangle 为正,沿y轴向内旋转; 为负,沿y轴向外旋转
    mcamera.getmatrix(imagematrix);
    imagematrix.pretranslate(-(imagewidth / 2), -(imageheight / 2));
    imagematrix.posttranslate((imagewidth / 2), (imageheight / 2));
    mcamera.restore();
  }
}

3、activity

activity中,主要实现自定义gallery的图片填充imageadapter、mygallery选择事件监听、点击事件监听

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private void initres(){
  tvtitle = (textview) findviewbyid(r.id.tvtitle);
  gallery = (mygallery) findviewbyid(r.id.mygallery); // 获取自定义的mygallery控件
  adapter = new imageadapter(this);
  adapter.createreflectedimages(); // 创建倒影效果
  gallery.setadapter(adapter);
  gallery.setonitemselectedlistener(new onitemselectedlistener() { // 设置选择事件监听
    @override
    public void onitemselected(adapterview<?> parent, view view, int position, long id) {
      tvtitle.settext(adapter.titles[position]);
    }
    @override
    public void onnothingselected(adapterview<?> parent) {
    }
  });
  gallery.setonitemclicklistener(new onitemclicklistener() { // 设置点击事件监听
    @override
    public void onitemclick(adapterview<?> parent, view view, int position, long id) {
      toast.maketext(main.this, "img " + (position+1) + " selected", toast.length_short).show();
    }
  });
}

main.xml布局文件中,通过实现自定义的mygallery,来显示图片集合

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="utf-8"?>
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="vertical" >
  <textview
    android:id="@+id/tvtitle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerhorizontal="true"
    android:textsize="16sp" />
  <com.homer.reflect.mygallery
    android:id="@+id/mygallery"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_below="@id/tvtitle"
    android:layout_margintop="10dip" />
</relativelayout>

完整实例代码点击此处本站下载

希望本文所述对大家android程序设计有所帮助。

延伸 · 阅读

精彩推荐
  • AndroidAndroid程序设计之AIDL实例详解

    Android程序设计之AIDL实例详解

    这篇文章主要介绍了Android程序设计的AIDL,以一个完整实例的形式较为详细的讲述了AIDL的原理及实现方法,需要的朋友可以参考下...

    Android开发网4642021-03-09
  • AndroidAndroid中AsyncTask详细介绍

    Android中AsyncTask详细介绍

    这篇文章主要介绍了Android中AsyncTask详细介绍,AsyncTask是一个很常用的API,尤其异步处理数据并将数据应用到视图的操作场合,需要的朋友可以参考下...

    Android开发网7452021-03-11
  • AndroidAndroid CardView+ViewPager实现ViewPager翻页动画的方法

    Android CardView+ViewPager实现ViewPager翻页动画的方法

    本篇文章主要介绍了Android CardView+ViewPager实现ViewPager翻页动画的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    Abby代黎明9602022-03-02
  • AndroidAndroid实现固定屏幕显示的方法

    Android实现固定屏幕显示的方法

    这篇文章主要介绍了Android实现固定屏幕显示的方法,实例分析了Android屏幕固定显示所涉及的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...

    鉴客6192021-03-27
  • AndroidAndroid实现Service获取当前位置(GPS+基站)的方法

    Android实现Service获取当前位置(GPS+基站)的方法

    这篇文章主要介绍了Android实现Service获取当前位置(GPS+基站)的方法,较为详细的分析了Service基于GPS位置的技巧,具有一定参考借鉴价值,需要的朋友可以参考下...

    Ruthless8342021-03-31
  • AndroidAndroid编程解析XML方法详解(SAX,DOM与PULL)

    Android编程解析XML方法详解(SAX,DOM与PULL)

    这篇文章主要介绍了Android编程解析XML方法,结合实例形式详细分析了Android解析XML文件的常用方法与相关实现技巧,需要的朋友可以参考下...

    liuhe68810052021-05-03
  • AndroidAndroid界面效果UI开发资料汇总(附资料包)

    Android界面效果UI开发资料汇总(附资料包)

    android ui界面设计,友好的界面会提高用户体验度;同时也增强了android ui界面设计的难度,本文提供了一些常用开发资料(有下载哦)感兴趣的朋友可以了解下...

    Android开发网4672021-01-03
  • Android汇总Android视频录制中常见问题

    汇总Android视频录制中常见问题

    这篇文章主要汇总了Android视频录制中常见问题,帮助大家更好地解决Android视频录制中常见的问题,需要的朋友可以参考下...

    yh_thu5192021-04-28