3D画廊

摘要:
3D画廊之前我都是写的学习的内容,我在写这些教程时遇到有趣的炫酷的小例子也会专门拿出来写一篇文章,今天就写一个酷炫的小例子,叫3D画廊,它是属于ViewPage的进阶版。效果图3D画廊的实现首先是布局文件18917183132代码中的ViewPagerIndicator是用于实现下方的指示器,这个我们在最后在进行解释;首先布局使用帧布局,内部用到ViewPager控件,注意在ViewPager控件的父布局中我们要添加android:clipChildren="false"属性,它的作用是定义它的子控件是否要在它应有的边界内进行绘制,默认值为true。

3D画廊

之前我都是写的学习的内容,我在写这些教程时遇到有趣的炫酷的小例子也会专门拿出来写一篇文章,今天就写一个酷炫的小例子,叫3D画廊,它是属于ViewPage的进阶版。

此项目下载地点:https://github.com/qySvip/3D-gallery

下面的指示器是使用的一大神的第三方库,会在文章下方简单讲述一下。

效果图

3D画廊第1张

3D画廊的实现

首先是布局文件

1 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 android:layout_width="match_parent"
3 android:layout_height="match_parent"
4 xmlns:app="http://schemas.android.com/apk/res-auto"
5 android:clipChildren="false"
6 android:background="@android:color/black"
7 android:id="@+id/frame_layout">
8 
9     <android.support.v4.view.ViewPager
10         android:layout_width="match_parent"
11 android:layout_height="450dp"
12 android:layout_gravity="center"
13 android:id="@+id/gallery"
14 android:clipChildren="false"
15 android:layout_marginLeft="85dp"
16 android:layout_marginRight="85dp" />
17 
18         <com.lwj.widget.viewpagerindicator.ViewPagerIndicator
19             android:id="@+id/indicator_circle_line"
20 android:layout_width="match_parent"
21 android:layout_height="50dp"
22 android:layout_gravity="bottom"
23 android:background="#efefef"
24 app:vpi_default_color="#FF239AF5"
25 app:vpi_distance="60dp"
26 app:vpi_distanceType="BY_LAYOUT"
27 app:vpi_indicatorType="CIRCLE_LINE"
28 app:vpi_radius="10dp"
29 app:vpi_selected_color="#FF239AF5"
30             />
31 
32 </FrameLayout>

代码中的ViewPagerIndicator是用于实现下方的指示器,这个我们在最后在进行解释;

首先布局使用帧布局,内部用到ViewPager控件,注意在ViewPager控件的父布局中我们要添加android:clipChildren="false"属性,它的作用是定义它的子控件是否要在它应有的边界内进行绘制,默认值为true。我们这里要用false。

然后在ViewPager中用到android:layout_marginLeft和android:layout_marginRight属性,值不能太大,过大会导致看不到两边的图像,具体根据自己满意进行调整。高度属性为图片和倒影的加起来的高度,自己进行调整。

GalleryPageTransformer类

1 packagesample.sdk.qy.com.demo;
2 
3 importandroid.support.v4.view.ViewPager;
4 importandroid.view.View;
5 
6 public class GalleryPageTransformer implementsViewPager.PageTransformer {
7     private static final float MAX_ROTATION=20.0f;
8     private static final float MIN_SCALE=0.75f;
9     private static final float MAX_TRANSLATE=20.0f;
10 
11 @Override
12     public void transformPage(View page, floatposition) {
13         if(position<-1) {
14 page.setTranslationX(MAX_TRANSLATE);
15 page.setScaleX(MIN_SCALE);
16 page.setScaleY(MIN_SCALE);
17             page.setRotationY(-MAX_ROTATION);
18 }
19         else if(position<=0) {
20             page.setTranslationX(-MAX_TRANSLATE*position);
21             float scale=MIN_SCALE+(1-MIN_SCALE)*(1.0f+position);
22 page.setScaleX(scale);
23 page.setScaleY(scale);
24             page.setRotationY(MAX_ROTATION*position);
25 }
26         else if(position<=1) {
27             page.setTranslationX(-MAX_TRANSLATE*position);
28             float scale=MIN_SCALE+(1-MIN_SCALE)*(1.0f-position);
29 page.setScaleX(scale);
30 page.setScaleY(scale);
31             page.setRotationY(MAX_ROTATION*position);
32 }
33         else{
34             page.setTranslationX(-MAX_TRANSLATE);
35 page.setScaleX(MIN_SCALE);
36 page.setScaleY(MIN_SCALE);
37 page.setRotationY(MAX_ROTATION);
38 }
39 }
40 }

PageTransformer是ViewPager内部定义的接口,这个接口主要用于控制ViewPager中item view的滑动效果。

  • setTranslationX 设置view相对原始位置的水平偏移量
  • setScaleX 设置水平缩放的基准点
  • setScaleY 设置竖直缩放的基准点
  • setRotationY 设置竖直的选择的基准点

ImageUtils类

1 packagesample.sdk.qy.com.demo;
2 
3 importandroid.content.Context;
4 importandroid.graphics.Bitmap;
5 importandroid.graphics.BitmapFactory;
6 importandroid.graphics.Canvas;
7 importandroid.graphics.Color;
8 importandroid.graphics.LinearGradient;
9 importandroid.graphics.Matrix;
10 importandroid.graphics.Paint;
11 importandroid.graphics.PorterDuff;
12 importandroid.graphics.PorterDuffXfermode;
13 importandroid.graphics.Shader;
14 
15 public classImageUtils {
16     public static Bitmap getReverseBitmapById(Context context, int resId, floatpercent) {
17         //get the source bitmap
18         Bitmap srcBitmap=BitmapFactory.decodeResource(context.getResources(), resId);
19         //get the tow third segment of the reverse bitmap
20         Matrix matrix=newMatrix();
21         matrix.setScale(1, -1);
22         Bitmap rvsBitmap=Bitmap.createBitmap(srcBitmap, 0, (int) (srcBitmap.getHeight()*(1-percent)),
23                 srcBitmap.getWidth(), (int) (srcBitmap.getHeight()*percent), matrix, false);
24         //combine the source bitmap and the reverse bitmap
25         Bitmap comBitmap=Bitmap.createBitmap(srcBitmap.getWidth(),
26                 srcBitmap.getHeight()+rvsBitmap.getHeight()+20, srcBitmap.getConfig());
27         Canvas gCanvas=newCanvas(comBitmap);
28         gCanvas.drawBitmap(srcBitmap, 0, 0, null);
29         gCanvas.drawBitmap(rvsBitmap, 0, srcBitmap.getHeight()+20, null);
30         Paint paint=newPaint();
31         LinearGradient shader=new LinearGradient(0, srcBitmap.getHeight()+20, 0, comBitmap.getHeight(),
32 Color.BLACK, Color.TRANSPARENT, Shader.TileMode.CLAMP);
33 paint.setShader(shader);
34         paint.setXfermode(newPorterDuffXfermode(PorterDuff.Mode.DST_IN));
35         gCanvas.drawRect(0, srcBitmap.getHeight()+20, srcBitmap.getWidth(), comBitmap.getHeight(), paint);
36         returncomBitmap;
37 }
38 }

这是做图片倒影的方法,内部使用了Canvas和Bitmap类,这些后面会进行讲述。

ViewAdapter类

1 packagesample.sdk.qy.com.demo;
2 
3 importandroid.support.v4.view.PagerAdapter;
4 importandroid.view.View;
5 importandroid.view.ViewGroup;
6 
7 importjava.util.List;
8 
9 public class ViewAdapter extendsPagerAdapter {
10     private List<View>datas;
11 
12     public ViewAdapter(List<View>list) {
13         datas=list;
14 }
15 
16 @Override
17     public intgetCount() {
18         returndatas.size();
19 }
20 
21 @Override
22     public booleanisViewFromObject(View view, Object object) {
23         return view==object;
24 }
25 
26 @Override
27     public Object instantiateItem(ViewGroup container, intposition) {
28         View view=datas.get(position);
29 container.addView(view);
30         returnview;
31 }
32 
33 @Override
34     public void destroyItem(ViewGroup container, intposition, Object object) {
35 container.removeView(datas.get(position));
36 }
37 }

适配器类,这里的适配方式为图片和倒影一同进行适配。

MainActivity类

1 packagesample.sdk.qy.com.demo;
2 
3 importandroid.app.Activity;
4 importandroid.os.Bundle;
5 importandroid.support.v4.view.PagerAdapter;
6 importandroid.support.v4.view.ViewPager;
7 importandroid.view.MotionEvent;
8 importandroid.view.View;
9 importandroid.widget.FrameLayout;
10 importandroid.widget.ImageView;
11 
12 importcom.lwj.widget.viewpagerindicator.ViewPagerIndicator;
13 
14 importjava.lang.reflect.Field;
15 importjava.util.ArrayList;
16 importjava.util.List;
17 
18 public class MainActivity extendsActivity {
19 
20     private List<View>pages;
21     privateFrameLayout layout;
22     privateViewPager pager;
23     privateViewPagerIndicator mIndicatorCircleLine;
24 
25 @Override
26     protected voidonCreate(Bundle savedInstanceState) {
27         super.onCreate(savedInstanceState);
28 setContentView(R.layout.activity_main);
29 
30         pages=getPages();
31         pager=(ViewPager) findViewById(R.id.gallery);
32         PagerAdapter adapter=newViewAdapter(pages);
33 pager.setAdapter(adapter);
34         pager.setPageMargin(20);
35         pager.setOffscreenPageLimit(3);
36         pager.setPageTransformer(true, newGalleryPageTransformer());
37 
38         layout=(FrameLayout) findViewById(R.id.frame_layout);
39         layout.setOnTouchListener(newView.OnTouchListener() {
40 @Override
41             public booleanonTouch(View v, MotionEvent event) {
42                 returnpager.dispatchTouchEvent(event);
43 }
44 });
45 
46         mIndicatorCircleLine =(ViewPagerIndicator) findViewById(R.id.indicator_circle_line);
47         mIndicatorCircleLine.setViewPager(pager,9);
48 }
49 
50     private List<View>getPages() {
51         List<View> pages=new ArrayList<>();
52         Field[] fields=R.drawable.class.getDeclaredFields();
53         try{
54             for(Field field : fields) {
55                 if (field.getName().startsWith("page")) {
56                     ImageView view = new ImageView(this);
57                     view.setImageBitmap(ImageUtils.getReverseBitmapById(this, field.getInt(null), 0.5f));
58 pages.add(view);
59 }
60 }
61         } catch(IllegalAccessException e) {
62 e.printStackTrace();
63 }
64         returnpages;
65 }
66 }

主界面方法,主要用于填充入图片、适配器适配。这里填充图片的方法为在drawable文件中查找以page开头的图片进行填充。

到这里3D画廊就完成了。。。。。。。。。

指示器

下面来说一下指示器的做法,用的是网上一大神的第三方类。

使用方法:

1、在 project的build.gradle 添加:

allprojects { repositories { ... maven { url "https://jitpack.io" } } }

2、在module的build.gradle 添加:

dependencies {implementation'com.github.LinweiJ:ViewPagerIndicator:0.1.0' }

注意这里要用implementation,compile现在已被废弃,官方显示将在2018年年底删除。

3、将ViewPagerIndicator控件添加到布局文件。

属性:

  • app:vpi_selected_color
  • app:vpi_default_color(如果 indicatorType=CIRCLE_LINE default_color 为指示器唯一颜色 ,selected_color 不起作用)
  • app:vpi_radius(点的大小,在indicatorType= CIRCLE_LINE 的情况下 radius 是点的高)
  • app:vpi_length(只作用在 indicatorType=CIRCLE_LINE 的情况下,为 指示器点的长度)
  • app:vpi_distance(只作用在 distanceType=BY_DISTANCE 的情况下)
  • app:vpi_num
  • app:vpi_indicatorType(LINE; CIRCLE; CIRCLE_LINE; BEZIER;SPRING)LINE:线 ; CIRCLE:圆点(默认) ; CIRCLE_LINE:圆角矩形; BEZIER:弹性球 ; SPRING: 弹簧粘性球
  • app:vpi_distanceType(BY_RADIUS; BY_DISTANCE ; BY_LAYOUT )BY_RADIUS:3倍radius ; BY_DISTANCE :定义固定距离 ;BY_LAYOUT :根据layout_width均分得到距离
  • app:vpi_animation(默认为true:动画开启 ; false:关闭动画)

4、在java文件中初始化该控件

使用mIndicatorCircleLine.setViewPager(pager,9);,第一个参数为适配器,第二个参数为图片的个数。

免责声明:文章转载自《3D画廊》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇怎么恢复win8的开始菜单51nod1437 迈克步下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Gears Android WIFI/基站定位源代码分析

Gears Android WIFI/基站定位源代码分析转载时请注明出处和作者联系方式文章出处:http://www.limodev.cn/blog作者联系方式:李先静 <xianjimli at hotmail dot com>Broncho A1还不支持基站和WIFI定位,Android的老版本里是有NetworkLocationProvi...

QML 修改TableView和TreeView滚动条样式

TreeView控件: 1 import QtQuick 2.9 2 import QtQuick.Controls 1.4 3 import QtQuick.Controls.Styles 1.4 4 import QtQml.Models 2.2 5 import QtQuick.Controls 2.12 6 7 TreeView { 8 id:c...

百度地图、ECharts整合HT for Web网络拓扑图应用

直击现场 百度地图、ECharts整合HT for Web网络拓扑图应用发表于3周前(2015-03-23 01:32) 阅读(1320)|评论(5)78人收藏此文章,我要收藏 赞8 慕课网,程序员升职加薪神器,点击免费学习 摘要前一篇谈及到了ECharts整合HT for Web的网络拓扑图应用,后来在ECharts的Demo中看到了有关空气质...

z-index 应用简单总结

做过页面布局的同学对z-index属性应该是很熟悉了,z-index是针对网页显示中的一个特殊属性。因为显示器是显示的图案是一个二维平面,拥有x轴和y轴来表示位置属性。为了表示三维立体的概念如显示元素的上下层的叠加顺序引入了z-index属性来表示z轴的区别。表示一个元素在叠加顺序上的上下立体关系。 z-index值较大的元素将叠加在z-index值较小的...

Elasticsearch安装ik中文分词插件(四)

一、IK简介   IK Analyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。从2006年12月推出1.0版开始,IKAnalyzer已经推出了4个大版本。最初,它是以开源项目Luence为应用主体的,结合词典分词和文法分析算法的中文分词组件。从3.0版本开 始,IK发展为面向Java的公用分词组件,独立于Lucene项目,同时提供了...

突袭HTML5之Javascript API扩展2 地理信息服务

      现在比较火的一类服务叫做基于位置的服务(location-based service, LBS),这一类服务就是企业利用某点(例如用户所在的位置)坐标附近的区域提供服务的信息,比如常见的地图相关服务。在HTML5中,加入了新的地理位置API用来确定和分享地理位置。 隐私申明      在与远程Web服务器共享物理位置时,隐私是一个需要关注的问题...