格式化

廣告

廣告2

2012年8月22日 星期三

[Android程式範例] Gellery循環動態陰相片畫廊

Android程式教學-Gellery循環動態陰相片畫廊



要新增兩個java類別-ImageAdapterGalleryFlow
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.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuffXfermode;
import android.graphics.Shader.TileMode;
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 {

 int mGalleryItemBackground;
 private Context mContext;
 private Integer[] mImageIds;
 private ImageView[] mImages;

 public ImageAdapter(Context c, Integer[] ImageIds) {
  mContext = c;
  mImageIds = ImageIds;
  mImages = new ImageView[mImageIds.length];
 }

 /*
  * 創建倒影效果
  * 
  * @return
  */
 public boolean createReflectedImages() {
  // //倒影圖和原圖之間的距離
  final int reflectionGap = 4;
  int index = 0;
  for (int imageId : mImageIds) {
   // //返回原圖解碼之後的bitmap對象
   Bitmap originalImage = BitmapFactory.decodeResource(
     mContext.getResources(), imageId);
   int width = originalImage.getWidth();
   int height = originalImage.getHeight();
   // 創建矩陣對象
   Matrix matrix = new Matrix();
   // //指定一個角度以0,0為坐標進行旋轉
   // // matrix.setRotate(30);
   // //指定矩陣(x軸不變,y軸相反)
   matrix.preScale(1, -1);
   // //將矩陣應用到該原圖之中,返回一個寬度不變,高度為原圖1/2的倒影位圖
   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(false);
   // canvas.drawRect(0, height, width, height +
   // reflectionGap,deafaultPaint);
   canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
   Paint paint = new Paint();
   paint.setAntiAlias(false);
   /*
    * 參數一:為漸變起初點坐標x位置, 參數二:為y軸位置, 參數三和四:分辨對應漸變終點, 最後參數為平鋪方式,
    * 這裡設置為鏡像Gradient是基於Shader類,所以我們通過Paint的setShader方法來設置這個漸變
    */
   LinearGradient shader = new LinearGradient(0,
     originalImage.getHeight(), 0,
     bitmapWithReflection.getHeight() + reflectionGap,
     0x70ffffff, 0x00ffffff, TileMode.MIRROR);
   // 設置陰影
   paint.setShader(shader);
   paint.setXfermode(new PorterDuffXfermode(
     android.graphics.PorterDuff.Mode.DST_IN));
   // 用已經定義好的畫筆構建一個矩形陰影漸變效果
   canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
     + reflectionGap, paint);
   // 創建一個ImageView用來顯示已經畫好的bitmapWithReflection
   ImageView imageView = new ImageView(mContext);
   imageView.setImageBitmap(bitmapWithReflection);
   // 設置imageView大小 ,也就是最終顯示的圖片大小
//   imageView.setLayoutParams(new GalleryFlow.LayoutParams(300, 400));
   imageView.setLayoutParams(new GalleryFlow.LayoutParams(150, 200));
   imageView.setScaleType(ScaleType.FIT_XY);
   // imageView.setScaleType(ScaleType.MATRIX);
   mImages[index++] = imageView;
  }
  return true;
 }

 @SuppressWarnings("unused")
 private Resources getResources() {
  return null;
 }

 public int getCount() {
//  return mImageIds.length;
  return Integer.MAX_VALUE;
 }

 public Object getItem(int position) {
  return position;
 }

 public long getItemId(int position) {
  return position;
 }

 public View getView(int position, View convertView, ViewGroup parent) {
  position=position%mImages.length;
  return mImages[position];
 }

 public float getScale(boolean focused, int offset) {
  return Math.max(0, 1.0f / (float) Math.pow(2, Math.abs(offset)));
 }
}

第二個類別的程式碼
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 GalleryFlow extends Gallery {

 private Camera mCamera = new Camera();// 相機類
 private int mMaxRotationAngle = 60;// 最大轉動角度
 private int mMaxZoom = -300;// //最大縮放值
 private int mCoveflowCenter;// 半徑值d(

 public GalleryFlow(Context context) {
  super(context);
  // 支持轉換 ,執行getChildStaticTransformation方法
  this.setStaticTransformationsEnabled(true);
 }

 public GalleryFlow(Context context, AttributeSet attrs) {
  super(context, attrs);
  this.setStaticTransformationsEnabled(true);
 }

 public GalleryFlow(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;
 }

 private int getCenterOfCoverflow() {
  return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2
    + getPaddingLeft();
 }

 private static int getCenterOfView(View view) {
  System.out.println("view left :" + view.getLeft());
  System.out.println("view width :" + view.getWidth());
  return view.getLeft() + view.getWidth() / 2;
 }

 // 控制gallery中每個圖片的旋轉(重寫的gallery中方法)
 protected boolean getChildStaticTransformation(View child, Transformation t) {
  // 取得當前子view的半徑值
  final int childCenter = getCenterOfView(child);
  System.out.println("childCenter:" + childCenter);
  final int childWidth = child.getWidth();
  // 旋轉角度
  int rotationAngle = 0;
  // 重置轉換狀態
  t.clear();
  // 設置轉換類型
  t.setTransformationType(Transformation.TYPE_MATRIX);
  // 如果圖片位於中心位置不需要進行旋轉
  if (childCenter == mCoveflowCenter) {
   transformImageBitmap((ImageView) child, t, 0);
  } else {
   // 根據圖片在gallery中的位置來計算圖片的旋轉角度
   rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);
   System.out.println("rotationAngle:" + rotationAngle);
   // 如果旋轉角度絕對值大於最大旋轉角度返回(-mMaxRotationAngle或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();
 }

}

主程式:
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;

import android.widget.Toast;

public class MyGellaryActivity extends Activity {

 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
   //全螢幕
  requestWindowFeature(Window.FEATURE_NO_TITLE); 
  getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN ,  
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//設定為橫向螢幕
  
        setContentView(R.layout.layout_gallery);
  Integer[] images = { R.drawable.item1, R.drawable.item2,
    R.drawable.item3, R.drawable.item4, R.drawable.item5,
    R.drawable.item6, R.drawable.item7, R.drawable.item8, R.drawable.item9, R.drawable.item10,
    R.drawable.item11, R.drawable.item12,
    R.drawable.item13, R.drawable.item14, R.drawable.item15,};
  ImageAdapter adapter = new ImageAdapter(this, images);
  adapter.createReflectedImages();// 創建倒影效果
  
  GalleryFlow galleryFlow = (GalleryFlow) this
    .findViewById(R.id.Gallery01);
  
  galleryFlow.setFadingEdgeLength(0);
  galleryFlow.setSpacing(10); // 圖片之間的間距
  galleryFlow.setAdapter(adapter);
  
  galleryFlow.setOnItemClickListener(new OnItemClickListener() {
   public void onItemClick(AdapterView parent, View view,
     int position, long id) {
    Toast.makeText(getApplicationContext(),
      String.valueOf(position), Toast.LENGTH_SHORT).show();
   }

  });
  galleryFlow.setSelection(200);
 }

}