Android Gallery組件實現迴圈顯示映像

來源:互聯網
上載者:User

Gallery組件主要用於橫向顯示映像列表,不過按常規做法。Gallery組件只能有限地顯示指定的映像。也就是說,如果為Gallery組件指定了10張映像,那麼當Gallery組件顯示到第10張時,就不會再繼續顯示了。這雖然在大多數時候沒有什麼關係,但在某些情況下,我們希望映像顯示到最後一張時再重第1張開始顯示,也就是迴圈顯示。要實現這種風格的Gallery組件,就需要對Gallery的Adapter對象進行一番改進。

  Gallery組件的傳統用法

  在實現可迴圈顯示映像的Gallery組件之前先來回顧一下Gallery組件的傳統用法。Gallery組件可以橫向顯示一個映像列表,當單擊當前映像的後一個映像時,這個映像列表會向左移動一格,當單擊當前映像的前一個映像時,這個映像列表會向右移動一樣。也可以通過拖動的方式來向左和向右移動映像列表。當前顯示的是第1個映像的效果1所示。Gallery組件顯示到最後一個映像的效果2所示

 

圖1

 

圖2

 

 

 

從圖2可以看出,當顯示到最後一個映像時,列表後面就沒有映像的,這也是Gallery組件的基本顯示效果。在本文後面的部分將詳細介紹如何使Gallery組件顯示到最後一個映像時會從第1個映像開始顯示。

  好了,現在我們來看一1和圖2的效果是如何做出來的吧。Gallery既然用於顯示映像,那第1步就必須要有一些影像檔用來顯示。現在可以隨意準備一些映像。在本文的例子中準備了6個jpg檔案(item1.jpg至item15.jpg)。將這些檔案都放在res/drawable目錄中

下面將這些映像的資源ID都儲存在int數組中,代碼如下:

private int[] myImageIds = {R.drawable.photo1,<br /> R.drawable.photo2,<br /> R.drawable.photo3,<br /> R.drawable.photo4,<br /> R.drawable.photo5,<br /> R.drawable.photo6,};

 

在本例的main.xml檔案中配置了一個Gallery組件,代碼如下:

<?xml version="1.0" encoding="utf-8"?><br /><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"<br />    android:orientation="vertical" android:layout_width="fill_parent"<br />    android:layout_height="fill_parent"><br />    <Gallery android:id="@+id/gallery" android:layout_width="fill_parent"<br />        android:layout_height="wrap_content" android:layout_marginTop="30dp" /><br /></LinearLayout>

 

 

現在在onCreate方法中裝載這個組件,代碼如下:

 public void onCreate(Bundle savedInstanceState)<br />    {<br />        super.onCreate(savedInstanceState);<br />        setContentView(R.layout.main);<br />        // 裝載Gallery組件<br />        Gallery gallery = (Gallery) findViewById(R.id.gallery);<br />        // 建立用於描述映像資料的ImageAdapter對象<br />        ImageAdapter imageAdapter = new ImageAdapter(this);<br />         // 設定Gallery組件的Adapter對象<br />        gallery.setAdapter(imageAdapter);<br />    }<br />

 

 

在上面的代碼中涉及到一個非常重要的類:ImageAdapter。該類是android.widget.BaseAdapter的子類,用於描述映像資訊。下面先看一下這個類的完整代碼

 public class ImageAdapter extends BaseAdapter<br />    {<br />        int mGalleryItemBackground;<br />        private Context mContext;<br />        public ImageAdapter(Context context)<br />        {<br />            mContext = context;<br />              // 獲得Gallery組件的屬性<br />            TypedArray typedArray = obtainStyledAttributes(R.styleable.Gallery);<br />            mGalleryItemBackground = typedArray.getResourceId(<br />                    R.styleable.Gallery_android_galleryItemBackground, 0);                        <br />        }<br />         // 返回映像總數<br />        public int getCount()<br />        {<br />            return resIds.length;<br />        }<br />        public Object getItem(int position)<br />        {<br />            return position;<br />        }<br />        public long getItemId(int position)<br />        {<br />            return position;<br />        }<br />         // 返回具體位置的ImageView對象<br />        public View getView(int position, View convertView, ViewGroup parent)<br />        {<br />            ImageView imageView = new ImageView(mContext);<br />             // 設定當前映像的映像(position為當前映像列表的位置)<br />            imageView.setImageResource(myImageIds[position]);<br />            imageView.setScaleType(ImageView.ScaleType.FIT_XY);<br />            imageView.setLayoutParams(new Gallery.LayoutParams(163, 106));<br />            // 設定Gallery組件的背景風格<br />            imageView.setBackgroundResource(mGalleryItemBackground);<br />            return imageView;<br />        }<br />    }<br />

 

在編寫ImageAdapter類時應注意的兩點:

  1. 在ImageAdapter類的構造方法中獲得了Gallery組件的屬性資訊。這些資訊被定義在res/values/attrs.xml檔案中,代碼如下:

<?xml version="1.0" encoding="utf-8"?><br /><resources><br />    <declare-styleable name="Gallery"><br />        <attr name="android:galleryItemBackground" /><br />    </declare-styleable><br /></resources><br />

 

 

上面的屬性資訊用於設定Gallery的背景風格。

  2. 在ImageAdapter類中有兩個非常重要的方法:getCount和getView。其中getCount方法用於返回映像總數,要注意的是,這個總數不能大於映像的實際數(可以小於映像的實際數),否則會拋出越界異常。當Gallery組件要顯示某一個映像時,就會調用getView方法,並將當前的映像索引(position參數)傳入該方法。一般getView方法用於返回每一個顯示映像的組件(ImageView對象)。從這一點可以看出,Gallery組件是即時顯示映像的,而不是一下將所有的映像都顯示出來。在getView方法中除了建立了ImageView對象,還用從resIds數組中獲得了相應的映像資源ID來設定在ImageView中顯示的映像。最後還設定了Gallery組件的背景顯示風格。

  OK,現在來運行這個程式,來回拖動映像列表,就會看到1和圖2所示的效果了。

  迴圈顯示映像的原理

  迴圈顯示有些類似於迴圈鏈表,最後一個結點的下一個結點又是第1個結點。迴圈顯示映像也可以類比這一點。

  也許細心的讀者從上一節實現的ImageAdapter類中會發現些什麼。對!就是getView方法中的position參數和getCount方法的關係。position參數的值是不可能超過getCount方法返回的值的,也就是說,position參數值的範圍是0至getCount() - 1。

 

 如果這時Gallery組件正好顯示到最後一個映像,position參數值正好為getCount() - 1。那麼我們如何再讓Gallery顯示下一個映像呢?也就是說讓position參數值再增1,對!將getCount()方法的傳回值也增1。

  那麼這裡還有一個問題,如果position參數值無限地增加,就意味著myImageIds數組要不斷地增大,這樣會大大消耗系統的資源。想到這,就需要解決兩個問題:既要position不斷地增加,又讓resIds數組中儲存的映像資源ID是有限的,該怎麼做呢?對於getCount()方法非常好解決,可以讓getCount方法返回一個很大的數,例如,Integer.MAX_VALUE。這時position參數值就可以隨著Gallery組件的映像不斷向前移動而增大。現在myImageIds數組只有6個元素,如果position的值超過數組邊界,要想繼續迴圈取得數組中的元素(也就是說,當position的值是6時,取myImageIds數組的第0個元素,是6時取第1個元素),最簡單的方法就是取餘,代碼如下:

 

 

myImageIds[position % myImageIds.length]

 

 在本節對ImageAdapter類做了如下兩個改進:

  1. 使getCount方法返回一個很大的值。建議返回Integer.MAX_VALUE。

  2. 在getView方法中通過取餘來迴圈取得resIds數組中的映像資源ID。

  通過上面兩點改進,可以使映像列表在向右移動時會迴圈顯示映像。當然,這種方法從本質上說只是偽迴圈,也就是說,如果真把映像移動到getCount方法返回的值那裡,那也就顯示到最後一個映像的。不過在這裡getCount方法返回的是Integer.MAX_VALUE,這個值超過了20億,除非有人真想把映像移動到第20億的位置,否則Gallery組件看著就是一個迴圈顯示映像的組件。

  實現迴圈顯示映像的Gallery組件

  在本節將組出與迴圈顯示映像相關的ImageAdapter類的完整代碼。讀者可以從中看到上一節介紹的兩點改進。為了使介面看上去更豐滿,本例還在單擊某一個Gallery組件中的映像時在下方顯示一個放大的映像(使用ImageSwitcher組件)。本例的顯示效果3所示。當不斷向後移動映像時,映像可不斷顯示,讀者可以自己運行本例來體驗一下。

本例中Main類的完整代碼如下:

package irdc.EX04_10;</p><p>import android.app.Activity;<br />import android.os.Bundle; /*本範例需使用到的class*/<br />import android.content.Context;<br />import android.content.res.TypedArray;<br />import android.view.View;<br />import android.view.ViewGroup;<br />import android.widget.AdapterView;<br />import android.widget.BaseAdapter;<br />import android.widget.Gallery;<br />import android.widget.ImageView;<br />import android.widget.Toast;<br />import android.widget.AdapterView.OnItemClickListener;</p><p>public class EX04_10 extends Activity<br />{<br /> /** Called when the activity is first created. */<br /> @Override<br /> public void onCreate(Bundle savedInstanceState)<br /> {<br /> super.onCreate(savedInstanceState);<br /> setContentView(R.layout.main); /* 透過findViewById取得 */<br /> Gallery g = (Gallery) findViewById(R.id.mygallery); /* 新增一ImageAdapter並設定給Gallery對象 */<br /> g.setAdapter(new ImageAdapter(this)); /* 設定一個itemclickListener並Toast被點選圖片的位置 */<br /> setTitle("Gallery 實現迴圈瀏覽圖片");<br /> g.setOnItemClickListener(new OnItemClickListener()<br /> {<br /> public void onItemClick(AdapterView parent, View v, int position, long id)<br /> {<br /> Toast.makeText(EX04_10.this, getString(R.string.my_gallery_text_pre) + position + getString(R.string.my_gallery_text_post), Toast.LENGTH_SHORT).show();<br /> }<br /> });<br /> }</p><p> public class ImageAdapter extends BaseAdapter /* 改寫BaseAdapter自訂一ImageAdapter class */<br /> {<br /> int mGalleryItemBackground;<br /> private Context mContext; /* ImageAdapter的建構子 */<br /> private int[] myImageIds = {R.drawable.photo1,<br /> R.drawable.photo2,<br /> R.drawable.photo3,<br /> R.drawable.photo4,<br /> R.drawable.photo5,<br /> R.drawable.photo6,};</p><p> public ImageAdapter(Context c)<br /> {<br /> mContext = c;<br /> TypedArray a = obtainStyledAttributes(R.styleable.Gallery); /* 使用在res/values/attrs.xml中的定義 的Gallery屬性. */<br /> mGalleryItemBackground = a.getResourceId(R.styleable.Gallery_android_galleryItemBackground, 0); ///*取得Gallery屬性的Index<br /> a.recycle();/* 讓對象的styleable屬效能夠反覆使用 */<br /> } </p><p> public int getCount() /* 一定要重寫的方法getCount,傳回圖片數目總數 */<br /> {<br /> //return myImageIds.length;<br /> return Integer.MAX_VALUE;<br /> } </p><p> public Object getItem(int position) /* 一定要重寫的方法getItem,傳回position */<br /> {<br /> return position;<br /> } </p><p> public long getItemId(int position) /* 一定要重寫的方法getItemId,傳回position */<br /> {<br /> return position;<br /> } </p><p> public View getView(int position, View convertView, ViewGroup parent)/* 一定要重寫的方法getView,傳回一View對象 */<br /> {<br />// if (position == getCount())<br />// {<br />// position = 0;<br />// }<br /> ImageView i = new ImageView(mContext);<br /> i.setImageResource(myImageIds[position%myImageIds.length]); /* 設定圖片給imageView對象 */<br /> i.setScaleType(ImageView.ScaleType.FIT_XY); /* 重新設定圖片的寬高 */<br /> i.setLayoutParams(new Gallery.LayoutParams(136, 88)); /* 重新設定Layout的寬高 */<br /> i.setBackgroundResource(mGalleryItemBackground); /* 設定Gallery背景圖 */<br /> return i; /* 傳回imageView物件 */<br /> }<br /> }<br />}

 

 

 2011-01-15

 14:33:17

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.