展会信息港展会大全

Android开发系列(七) Gallery 3D效果
来源:互联网   发布日期:2015-10-03 10:44:35   浏览:1816次  

导读:昨天没有做更新,原因是一直在看有关Gallery的内容,因为想做一个比较美观的图片浏览器,如果使用系统自带的Gallery类效果非常差,因此根据网上的总结,对Gallery类进行继承,进而对其...

昨天没有做更新,原因是一直在看有关Gallery的内容,因为想做一个比较美观的图片浏览器,如果使用系统自带的Gallery类效果非常差,因此根据网上的总结,对Gallery类进行继承,进而对其中的效果进行自定义,可以实现比较美观的(伪)3D效果。下一节会把ImageSwitcher添加进来,进一步对图片浏览器优化。另外对网上牛人的帖子一并表示感谢。

首先是布局文件:

复制代码

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

android:background="@android:color/background_dark" >

<com.example.android_myowngallery.MyGallery

android:id="@+id/myGallery"

android:layout_width="match_parent"

android:layout_height="match_parent"/>

</LinearLayout>

复制代码

注意这里因为对View控件进行了继承,所以控件的类型应该写成自己定义的那个类类名,否则还会出现ClassCastException

然后是自己创建的MyGallery类

复制代码

package com.example.android_myowngallery;

import android.content.Context;

import android.graphics.Camera;

import android.graphics.Matrix;

import android.util.AttributeSet;

import android.view.View;

import android.view.animation.Transformation;

import android.widget.Gallery;

public class MyGallery extends Gallery{

/**

* 注意Gallery类有三个构造函数,在继承时必须要把这三个构造函数都继承过来,否则会有异常

* @param context

* @param attrs

* @param defStyle

*/

public MyGallery(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

// TODO Auto-generated constructor stub

}

public MyGallery(Context context, AttributeSet attrs) {

super(context, attrs);

// TODO Auto-generated constructor stub

}

public MyGallery(Context context) {

super(context);

// TODO Auto-generated constructor stub

}

/**

* 覆写 getChildStaticTransformation方法,正是通过这个方法对Gallery的效果进行修改

*/

@Override

protected boolean getChildStaticTransformation(View child, Transformation t) {

// TODO Auto-generated method stub

//对转换信息初始化

t.clear();

//setTransformationType();

//获得子控件(ImageView)偏移父控件偏移量 (用比例表示,在-1到1之间)

float offSet=getOffSet(child);

//根据偏移量,子控件,转换信息 进行效果设置

tranformIamgeView(child, t, offSet); //不要忘记调用图像变换方法

return true;

}

/**

* 求出子控件偏移父控件中心的程度

*/

//求出子控件的中心

protected int getCenterOfChild(View view){

return view.getLeft()+view.getWidth()/2;

//这里的getLeft()是求出子控件左边界的横坐标,在加上一半宽度就是中心的横坐标了

}

protected int getCenterOfParent()

{

//有效宽度=宽度-左右边框

//中心横坐标=左边框+有效宽度的一半

return getPaddingLeft()+(getWidth()-getPaddingLeft()-getPaddingRight())/2;

}

protected float getOffSet(View view)

{

float cCenter=getCenterOfChild(view);

float pCenter=getCenterOfParent();

float offSet=(cCenter-pCenter)/pCenter;

if(offSet<-1){

offSet=-1;

}

else if(offSet>1){

offSet=1;

}

return offSet;

}

/**

* 该方法根据给定的参数进行修改图像的显示属性,实际上就是根据子控件偏移父控件中心的偏移量决定不同的显示

* 效果,从而使图片的切换更加好看

*/

protected void tranformIamgeView(View view, Transformation t, float offSet)

{

//这里创建一个Camera对象通过Camera类的translate方法改变“相机”的角度,进而使图片呈现不同的效果

/**

* android.graphics.Camera

*

* @Camera.save();

* @Camera.restore();相机类的这两个方法需要同时出现

*/

Camera mCamera=new Camera();

/**

* 通过Transformation对象获得一个Matrix对象,这个对象的方法用于对于图像坐标变换的属性进行设置

* android.graphics.Matrix

*/

Matrix matrix=t.getMatrix();

mCamera.save();

/**

* z坐标为正时表示“相机”上升,意味着图像将变小,本例中打算将偏离父控件中心的View缩小,、

* 所以z应该是正值

*/

mCamera.translate(0, 0, Math.abs(offSet)*200);

/****

* ERROR!!

*

*

* 将图片对象添加至矩阵中,这个方法必须再preTranslate的前面,否则对于变换中心的设置是无效的!!

*/

mCamera.getMatrix(matrix);

//先宽后高,关于这个方法的意义下文讨论

matrix.preTranslate(-view.getMeasuredWidth()/2, -view.getMeasuredHeight()/2);

matrix.postTranslate(view.getMeasuredWidth()/2, view.getMeasuredHeight()/2);

mCamera.restore();//将相机的状态保存

//设置一下透明度Alpha,要注意这里的透明度是子控件ImageView的,如果透明度为0(不透明)

//那么图片将不会显示,如果透明度为1,图片正常显示

t.setAlpha(1-Math.abs(offSet));

}

}

复制代码

这里matrix.preTranslate(-view.getWidth()/2, -view.getHeight()/2);

是指在矩阵变换之前把View向左上移动,也就是把矩阵变换的中心点由childView的原点(图片左上角)变成childView的中心点

matrix.postTranslate(view.getWidth()/2, view.getWidth()/2);

指在矩阵变换完之后,再把childView向右下方进行平移,移动到原来的位置(即屏幕的中心位置)

另外注意mCamera.getMatrix()方法应该放在preTranslate()方法前面!

如同ListView一样,也要为Gallery设置适配器

复制代码

package com.example.android_myowngallery;

import android.content.Context;

import android.view.View;

import android.view.ViewGroup;

import android.view.ViewGroup.LayoutParams;

import android.widget.BaseAdapter;

import android.widget.Gallery;

import android.widget.ImageView;

public class MyAdapter extends BaseAdapter{

private Context context;

private int[] picRes;

public MyAdapter(Context context, int[] picRes) {

super();

this.context = context;

this.picRes = picRes;

}

@Override

public int getCount() {

// TODO Auto-generated method stub

return picRes.length;

}

@Override

public Object getItem(int position) {

// TODO Auto-generated method stub

return null;

}

@Override

public long getItemId(int position) {

// TODO Auto-generated method stub

return position;

}

@Override

public View getView(int position, View convertView, ViewGroup parent) {

// TODO Auto-generated method stub

/**

* 说明:因为这里只有一个控件ImageView,所以为了简化代码在这里直接创建ImageView对象,

* 在处理每一个GalleryItem中有多个控件时,还是要和ListView一样自定义每个Item的布局文件,

* 一般自定义布局时才会使用LayoutInflater的inflate方法创建convertView,然后再进一步获得子控件的

* ID,这里不用convertView,因为没有定义item的布局文件!

*/

ImageView i=new ImageView(context);

//遗留问题:这里换成Gallery是否可以?感觉MyGallery还是最好!

i.setLayoutParams(new MyGallery.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));//这里必须要创建新对象!并且要使用父控件Gallery的内部类

i.setImageResource(picRes[position]);

return i;

}

}

复制代码

这里注意本适配器中不需要利用convertView ,只有当有子布局文件时才会通过inflate方法创建此view

最后是MainActivity

复制代码

package com.example.android_myowngallery;

import android.os.Bundle;

import android.app.Activity;

import android.view.Menu;

import android.widget.Gallery;

public class MainActivity extends Activity {

protected int[] picRes={R.drawable.ew23,R.drawable.girl0,R.drawable.girl1,R.drawable.girl2,R.drawable.image01,

R.drawable.image02,R.drawable.qwe2,R.drawable.w21};

MyGallery g=null;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

g=(MyGallery)findViewById(R.id.myGallery);

MyAdapter adapter=new MyAdapter(this,picRes);

g.setAdapter(adapter);

}

赞助本站

人工智能实验室

相关热词: android开发 教程

AiLab云推荐
推荐内容
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港