Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android開發系列(七) Gallery 3D效果

Android開發系列(七) Gallery 3D效果

編輯:關於Android編程

昨天沒有做更新,原因是一直在看有關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);          }         
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved