Gallery组件主要用于横向显示图像列表,不过按常规做法。Gallery组件只能有限地显示指定的图像。也就是说,如果为Gallery组件指定了10张图像,那么当Gallery组件显示到第10张时,就不会再继续显示了。
代码里带注释,欢迎相互讨论
Layout里的main.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/background_port"
>
<ImageButton android:src="@drawable/login"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/login"
android:background="#0000"/>
<com.king.showgallery.GameGallery android:id="@+id/imgGallery"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
res/menu/menu.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_update" android:title="程序升级" android:icon="@drawable/icon_appupdate"/>
<item android:id="@+id/menu_download" android:title="下载中心" android:icon="@drawable/icon_download_center"/>
<item android:id="@+id/menu_feedback" android:title="用户反馈" android:icon="@drawable/icon_feedback"/>
<item android:id="@+id/menu_recommend" android:title="好友推荐" android:icon="@drawable/icon_recommend"/>
<item android:id="@+id/menu_about" android:title="关于我们" android:icon="@drawable/icon_about"/>
</menu>
id标签,title是当前菜单的描述,icon是当前菜单的图片
package com.king.showgallery;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
public class GalleryActivity extends MenuActivity {
//imgList里装载需要显示的图片
private Integer[] imgList={R.drawable.tab_selected_1,R.drawable.tab_selected_1,R.drawable.tab_selected_1,R.drawable.tab_selected_1,R.drawable.tab_selected_1,R.drawable.tab_selected_1,R.drawable.tab_selected_1,R.drawable.tab_selected_1};
private Toast toast;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//设置全屏
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main);
ImageAdapter adapter = new ImageAdapter(this, imgList);
adapter.createReflectedImages();
GameGallery gameGallery = (GameGallery) findViewById(R.id.imgGallery);
gameGallery.setAdapter(adapter);
gameGallery.setOnItemClickListener(new OnItemClickListener() {
//AdapterView<?> arg0代表向spinner中加载的一系列字符串或其它事物,是一个适配器,是字符串和Spinner之间的桥梁!而View代表Spinner,int arg2代表ItemId, long arg3代表Item的position!
public void onItemClick(AdapterView<?> arg0, View view, int position,
long arg3) {
switch (position) {
case 0:
//点击每个图片,根据图片的position,显示不同的内容
toast.makeText(GalleryActivity.this, "this is zero", Toast.LENGTH_SHORT).show();
break;
case 1:
toast.makeText(GalleryActivity.this, "this is one", Toast.LENGTH_SHORT).show();break;
case 2:
toast.makeText(GalleryActivity.this, "this is two", Toast.LENGTH_SHORT).show();break;
case 3:
toast.makeText(GalleryActivity.this, "this is three", Toast.LENGTH_SHORT).show();break;
case 4:
//程序退出事件
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
System.exit(0);
break;
case 5:
toast.makeText(GalleryActivity.this, "this is five", Toast.LENGTH_SHORT).show();break;
case 6:
toast.makeText(GalleryActivity.this, "this is six", Toast.LENGTH_SHORT).show();break;
case 7:
toast.makeText(GalleryActivity.this, "this is seven", Toast.LENGTH_SHORT).show();break;
default:
break;
}
}
});
}
}
对于Android开发我们可以做的尽量MVC化,UI界面和Code逻辑代码分离方式,除了常规的Activity布局可以用xml实现外,菜单Menu也可以通过MenuInflater来映射一个布局文件,相关的创建菜单方法有些不同。
package com.king.showgallery;
import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
public class MenuActivity extends Activity{
public boolean onCreateOptionsMenu(Menu menu){
super.onCreateOptionsMenu(menu);
//MenuInflater 是用来解析定义在menu 目录下的菜单布局文件
MenuInflater inflater=new MenuInflater(getApplicationContext());
inflater.inflate(R.menu.menu, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item){
String info="";
switch (item.getItemId()) {
case R.id.menu_about:
//点击当前菜单后显示效果
info="isabout";
break;
case R.id.menu_download:
info="isdownload";
break;
case R.id.menu_feedback:
info="isfeedback";
break;
case R.id.menu_recommend:
info="isrecommend";
break;
case R.id.menu_update:
info="isupdate";
break;
default:
info="null";
break;
}
Toast toast=Toast.makeText(this, info, Toast.LENGTH_SHORT);
toast.show();
return super.onOptionsItemSelected(item);
}
protected void setMenuBackground(){
MenuActivity.this.getLayoutInflater().setFactory(new android.view.LayoutInflater.Factory() {
@Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
if(name.equalsIgnoreCase("com.android.internal.view.menu.IconMenuItemView")){
try{
LayoutInflater f=getLayoutInflater();
final View view=f.createView(name, null, attrs);
new Handler().post(new Runnable(){
public void run(){
view.setBackgroundResource(R.drawable.menu_background);
}
});
return view;
}catch(InflateException e){
e.printStackTrace();
}catch(ClassNotFoundException e){
e.printStackTrace();
}
}
return null;
}
});
}
}
package com.king.showgallery;
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;
import android.widget.ImageView;
public class GameGallery extends Gallery{
public GameGallery(Context context){
super(context);
this.setStaticTransformationsEnabled(true);
}
public GameGallery(Context context,AttributeSet attrs){
super(context,attrs);
this.setStaticTransformationsEnabled(true);
}
public GameGallery(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.setStaticTransformationsEnabled(true);
}
//mCamera是用来做类3D效果处理,比如z轴方向上的平移,绕y轴的旋转等
private Camera mCamera = new Camera();
//mMaxRotationAngle是图片绕y轴最大旋转角度,也就是屏幕最边上那两张图片的旋转角度
private int mMaxRotationAngle = 60;
//mMaxZoom是图片在z轴平移的距离,视觉上看起来就是放大缩小的效果.
private int mMaxZoom = -120;
private int mCoveflowCenter;
public int getMaxRotationAngle() {
return mMaxRotationAngle;
}
public void setMaxRotationAngle(int maxRotationAngle) {
mMaxRotationAngle = maxRotationAngle;
}
public int getMaxZoom() {
return mMaxZoom;
}
public void setMaxZoom(int maxZoom) {
mMaxZoom = maxZoom;
}
private int getCenterOfCoverflow() {
return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2
+ getPaddingLeft();
}
private static int getCenterOfView(View view) {
return view.getLeft() + view.getWidth() / 2;
}
protected boolean getChildStaticTransformation(View child, Transformation t) {
final int childCenter = getCenterOfView(child);
final int childWidth = child.getWidth();
int rotationAngle = 0;
t.clear();
t.setTransformationType(Transformation.TYPE_MATRIX);
if (childCenter == mCoveflowCenter) {
transformImageBitmap((ImageView) child, t, 0);
} else {
rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);
if (Math.abs(rotationAngle) > mMaxRotationAngle) {
rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle
: mMaxRotationAngle;
}
transformImageBitmap((ImageView) child, t, rotationAngle);
}
return true;
}
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mCoveflowCenter = getCenterOfCoverflow();
super.onSizeChanged(w, h, oldw, oldh);
}
private void transformImageBitmap(ImageView child, Transformation t,
int rotationAngle) {
mCamera.save();
final Matrix imageMatrix = t.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);
}
// 在Y轴上旋转,对应图片竖向向里翻转。
// 如果在X轴上旋转,则对应图片横向向里翻转。
mCamera.rotateY(rotationAngle);
mCamera.getMatrix(imageMatrix);
imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));
imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));
mCamera.restore();
}
}
package com.king.showgallery;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Shader.TileMode;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
public class ImageAdapter extends BaseAdapter{
private Context mContext;
private Integer[] mImageIds;
private ImageView[] mImages;
private String[] strings;
private int width,height;
//图片上的提示信息
private String[] textList={"功能说明","项目说明","玩法说明","软件说明","退出","程序更新","兑奖","查询"};
public ImageAdapter(Context c, Integer[] ImageIds) {
mContext = c;
mImageIds = ImageIds;
mImages = new ImageView[mImageIds.length];
}
public boolean createReflectedImages() {
final int reflectionGap = 4;
int index = 0;
for (int imageId : mImageIds) {
Bitmap originalImage = BitmapFactory.decodeResource(mContext
.getResources(), imageId);
width = originalImage.getWidth();
height = originalImage.getHeight();
Matrix matrix = new Matrix();
// matrix.setRotate(30);
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);
Canvas canvas = new Canvas(bitmapWithReflection);
canvas.drawBitmap(originalImage, 0, 0, null);
Paint deafaultPaint = new Paint();
deafaultPaint.setAntiAlias(true);
canvas.drawRect(0, height, width, height + reflectionGap,
deafaultPaint);
canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
Paint paint = new Paint();
paint.setAntiAlias(true);
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 GameGallery.LayoutParams(180, 240));
mImages[index++] = imageView;
}
return true;
}
private Resources getResources() {
return null;
}
public int getCount() {
return mImageIds.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
//给图片添加文字提示信息
Bitmap newb = Bitmap.createBitmap( width,height, Config.ARGB_8888 );
Canvas canvasTemp = new Canvas( newb );
canvasTemp.drawColor(Color.alpha(0));
Paint p = new Paint();
String familyName = "宋体";
Typeface font = Typeface.create(familyName, Typeface.BOLD);
p.setColor(Color.WHITE); during-pregnancy
p.setTypeface(font);
p.setTextSize(30);
canvasTemp.drawText(textList[position], 40,80, p);
Drawable drawable = new BitmapDrawable(newb);
mImages[position].setBackgroundDrawable(drawable);
return mImages[position];
}
public float getScale(boolean focused, int offset) {
return Math.max(0, 1.0f / (float) Math.pow(2, Math.abs(offset)));
}
}
在ImageAdapter类中有两个非常重要的方法:getCount和getView。其中getCount方法用于返回图像总数,要注意的是,这个总数不能大于图像的实际数(可以小于图像的实际数),否则会抛出越界异常。当Gallery组件要显示某一个图像时,就会调用getView方法,并将当前的图像索引(position参数)传入该方法。一般getView方法用于返回每一个显示图像的组件(ImageView对象)。从这一点可以看出,Gallery组件是即时显示图像的,而不是一下将所有的图像都显示出来。在getView方法中除了创建了ImageView对象,还用从resIds数组中获得了相应的图像资源ID来设置在ImageView中显示的图像。最后还设置了Gallery组件的背景显示风格。
在ImageAdapter里给图片添加文字信息,注意
1.Bitmap,可以来自资源/文件,也可以在程序中创建,实际上的功能相当于图片的存储空间;
2.Canvas,紧密与Bitmap联系,把Bitmap比喻内容的话,那么Canvas就是提供了众多方法操作Bitamp的平台;
3.Paint,与Canvas紧密联系,是"画板"上的笔刷工具,也用于设置View控件上的样式;
4.Drawable,
如果说前三者是看不见地在内存中画图,那么Drawable就是把前三者绘图结果表现出来的接口。Drawable多个子类,例如:位图
(BitmapDrawable)、图形(ShapeDrawable)、图层(LayerDrawable)等。