Android--UI之Gallery


前言

  這篇博客講解一下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。

 

  請支持原創,尊重原創,轉載請注明出處。謝謝。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM