前言
這篇博客講解一下Android開發中,Gallery控件的使用,這是一個畫廊視圖,用於展示一組圖片,用固定在中間位置的水平滾動列表顯示列表項的視圖。Android最新的API文檔中了解到,在Android4.1(Android API level16)之后,就不再贊成使用這個控件,但還對其有支持,所以這里簡單講解一下如何使用。在這篇博客中,將了解到Gallery的一些常用屬性、方法、以及樣式的設置,最后會以一個小示例來展示如何使用Gallery展示一個畫廊的效果。
Gallery
Gallery與Spinner兩個控件具有共同的父類:AbsSpinner,表示Gallery和Spinner都是一個列表框。它們之間的區別在於Spinner顯示的是一個垂直的列表選擇框,而Gallery顯示的是一個水平的列表選擇框,而且支持水平滑動的效果。Gallery與Spinner還有一個區別:Spinner的作用是供用戶選擇,而Gallery則允許用戶通過拖動來查看上一個、下一個列表項。對於Spinner,在我的另外一篇博客中有詳細講解,有興趣的朋友可以看看:Android--UI之Spinner。
下面介紹一下Gallery的常用XML屬性,Android也為其屬性提供了相應的getter、setter方法:
- android:animationDuration:設置列表項切換時的動畫持續時間,使用毫秒為單位。
- android:gravity:設置列表項的對其方式。
- android:spacing:設置Gallery內列表項之間的間距。
- android:unselectedAlpha:設置沒有被選中的列表項的透明度,范圍是一個為0~1的float數,越接近0越透明。
作為一個列表框,它和Spinner一樣,聲明的事件也是定義在AdapterView類中,常用事件有如下幾個:
- AdapterView.OnItemCLickListener:列表項被點擊時觸發。
- AdapterView.OnItemLongClickListener:列表項被長按時觸發。
- AdapterView.OnItemSelectedListener:列表項被選擇時觸發。
Gallery的數據綁定
Gallery本身的用法非常簡單,基本上與Spinner的用法相似,只要為它提供一個Adapter適配器即可。如果需要響應Gallery上用戶的操作,可以監聽上面介紹的幾個事件。
Adapter適配器的概念,在我的另外一篇博客中有講解,有興趣的朋友可以看看,Android--UI之AutoCompleteTextView。而對於Gallery的Adapter適配器,雖然可以直接實現Adapter接口,但是一般推薦繼承另外一個抽象類:BaseAdapter,它已經實現了一些常用的方法。對於BaseAdapter而言,繼承它必須要實現幾個方法,下面先了解一下這幾個方法:
- int getCount():當前適配器中存在多少個數據項。
- Object getItem(int position):返回數據集中指定位置的數據項。
- long getItemId(int position):返回數據集中指定位置的數據行Id。
- View getView(int position,View convertView,ViewGroup parent):返回一個視圖,用於顯示數據集中指定位置的數據項。
對於BaseAdapter的getView()方法,這里着重講解一下。在綁定Adapter適配器之后,系統會根據getCount()方法返回的數據項,循環調用getView()方法,用於返回每個position位置的顯示視圖,所以對於一個Adapter適配器,其主要的代碼量就在getView()方法中。因為BaseAdapter的getView()方法返回的是一個View數據,所以一般自定義的展示效果都會用到BaseAdapter來做父類,繼承實現其中的方法來實現自定義的View來展示在UI界面上,
示例程序
下面通過一個示例說明上面講到的知識點,在這個示例程序中,使用一個Gallery來展示一組圖片的畫廊效果,大部分項目中用到的也是這種效果,但是它展示的是一個View,所以並不是僅僅可以用來顯示圖片,這里只是用圖片進行演示。在示例程序中還聲明了一個ImageView,用於顯示從Gallery中選中的圖片,對於ImageView的用法,請參見另外一篇博客:ImageView的使用,這里就不在累述了。
因為是顯示一個圖片的畫廊效果,所以需要准備一組圖片,這些圖片放在res/drawable-hdpi目錄下,這些圖片會隨着項目源碼一起打包到源碼中的。
布局代碼:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Gallery Demo" /> <!-- 定義一個Gallery,其中動畫換進3秒,數據項間隔3dp,透明度為50% --> <Gallery android:id="@+id/gallery1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:animationDuration="3000" android:spacing="3dp" android:unselectedAlpha="0.5" /> <ImageView android:id="@+id/image1" android:layout_width="320dp" android:layout_height="250dp" android:scaleType="fitXY" /> </LinearLayout>
實現代碼:
1 package com.bgxt.gallerydemo; 2 3 import android.os.Bundle; 4 import android.app.Activity; 5 import android.content.Context; 6 import android.content.res.TypedArray; 7 import android.view.Menu; 8 import android.view.View; 9 import android.view.ViewGroup; 10 import android.widget.AdapterView; 11 import android.widget.AdapterView.OnItemClickListener; 12 import android.widget.BaseAdapter; 13 import android.widget.Gallery; 14 import android.widget.ImageView; 15 16 public class MainActivity extends Activity { 17 private int[] imagesIDs = new int[] { R.drawable.bmp1, R.drawable.bmp2, 18 R.drawable.bmp3, R.drawable.bmp4, R.drawable.bmp5, R.drawable.bmp6, 19 R.drawable.bmp7, R.drawable.bmp8, R.drawable.bmp9, R.drawable.bmp10 }; 20 private Gallery gallery; 21 private ImageView image; 22 23 @Override 24 protected void onCreate(Bundle savedInstanceState) { 25 super.onCreate(savedInstanceState); 26 setContentView(R.layout.activity_main); 27 gallery = (Gallery) findViewById(R.id.gallery1); 28 image = (ImageView) findViewById(R.id.image1); 29 gallery.setAdapter(new ImageAdapter(MainActivity.this)); 30 gallery.setOnItemClickListener(new OnItemClickListener() { 31 32 @Override 33 public void onItemClick(AdapterView<?> parent, View view, 34 int position, long id) { 35 image.setImageResource(imagesIDs[position]); 36 } 37 }); 38 } 39 40 // 聲明一個BaseAdapter 41 public class ImageAdapter extends BaseAdapter { 42 // 使用Adapter的上下文變量 43 Context context; 44 // 背景樣式的Id 45 int itemBackground; 46 47 public ImageAdapter(Context c) { 48 // 在構造函數中傳遞需要使用這個Adapter的上下文變量 49 context = c; 50 // 通過XML資源中定義的樣式,設定背景 51 TypedArray a = obtainStyledAttributes(R.styleable.Gallery1); 52 itemBackground = a.getResourceId( 53 R.styleable.Gallery1_android_galleryItemBackground, 0); 54 a.recycle(); 55 } 56 57 @Override 58 public int getCount() { 59 // 返回當前數據集中數據的個數 60 return imagesIDs.length; 61 } 62 63 @Override 64 public Object getItem(int position) { 65 // 返回數據集中,當前position位置的數據 66 return imagesIDs[position]; 67 } 68 69 @Override 70 public long getItemId(int position) { 71 // 返回數據集中,當前position位置的數據的Id 72 return position; 73 } 74 75 @Override 76 public View getView(int position, View convertView, ViewGroup parent) { 77 // 返回當前position位置的視圖 78 ImageView imageview; 79 if (convertView == null) { 80 // 通過數據上下文對象聲明一個ImageView,並設置相關屬性 81 imageview = new ImageView(context); 82 imageview.setImageResource(imagesIDs[position]); 83 imageview.setScaleType(ImageView.ScaleType.FIT_XY); 84 imageview.setLayoutParams(new Gallery.LayoutParams(150, 120)); 85 86 } else { 87 imageview = (ImageView) convertView; 88 } 89 // 使用XML 中定義的樣式為待顯示的View設定背景樣式 90 imageview.setBackgroundResource(itemBackground); 91 92 return imageview; 93 } 94 95 } 96 97 @Override 98 public boolean onCreateOptionsMenu(Menu menu) { 99 // Inflate the menu; this adds items to the action bar if it is present. 100 getMenuInflater().inflate(R.menu.main, menu); 101 return true; 102 } 103 104 }
在代碼中用到了一個XML文件定義的Android樣式,這里僅僅是為了用於Gallery展示圖片的背景樣式,並不是必須的。下面是樣式的XML資源文件attrs.xml的代碼,文件存放地址為res/values中。
1 <?xml version="1.0" encoding="utf-8"?> 2 <resources> 3 4 <declare-styleable name="Gallery1"> 5 <attr name="android:galleryItemBackground" /> 6 </declare-styleable> 7 8 </resources>
效果展示:
總結
雖然Gallery在Android4.1之后就已經不推薦使用了,但是在實際項目中,還是有機會用到這個控件的,並且通過這個控件,講解了BaseAdapter的用法,BaseAdapter可以定義所有自定義的返回數據,在實際項目中屬於比較常用的Adapter。
請支持原創,尊重原創,轉載請注明出處。謝謝。