Android Gallery和ImageSwitcher同步自動(滾動)播放圖片庫
本文主要內容是如何讓Gallery和ImageSwitcher控件能夠同步自動播放圖片集 ,看起來較難,然而,實現的方法非常簡單,
請跟我慢慢來。總的來說,本文要實現的效果如下圖:(截圖效果不怎麽好)
本文是建立在以下兩篇bolg上的:
1、Android入門第十二篇之Gallery
2、Android 控件之ImageSwitcher圖片切換器
如果對Gallery和ImageSwitcher控件不是很熟悉的同學,建議先過去看看,本文並沒有怎麽講述控件的使用方法,而是在使用
基礎上,搭建我們的技巧。
接下來,溫習鞏固這兩個控件的知識點,有個知識性的儲備。
一、 Gallery的監聽事件
Gallery的兩個重要監聽事件如下:
1、OnItemClickListener 監聽事件
說明:當Gallery中的Item處於選中狀態並且被點擊觸發該事件 ;
其監聽方法為:
public voidonItemClick(AdapterView<?> parent, View view, int position, long id)
2、OnItemSelectedListener 監聽事件
說明:當Gallery中的Item處於選中狀態時觸發該事件
其監聽方法為:
public voidonItemSelected(AdapterView<?> parent, View view, int position, long id)
說明:當Gallery中的Item處於選中狀態時觸發該事件
public void onNothingSelected(AdapterView<?> parent)
說明:當控件沒有任何一項item選中時,觸發該方法
兩種監聽事件的區別在於,Item被選中(selected)的由來。其由來有兩種:
1、鼠標點擊(click)了Item (先click),然後該項selected ;
2、代碼設置某項Item 選中,例如setSelection(int position)(具體使用見下文) ,然後該項selected .
在情形1時,首先觸發OnItemClickListener(先click),接著便是OnItemSelectedListener監聽(因為item selected)。當某個Item
處於選中狀態時,如果它是由情形2而來,就不會觸發OnItemClickListener監聽(沒有click),只會觸發OnItemSelectedListener監聽
(只是selected)。
二、Gallery的setSelection()方法
方法原型: public void setSelection (int position)
說明:使第position處於選中狀態。同時觸發OnItemSelectedListener監聽事件。
PS: 在listView控件中也存在setSelection()是讓該行處於屏幕可見狀態,不需要手動滑動定位。第一次進入界面時,
默認顯示第一行,於是乎,我們可以手動設置該方法,ListView在顯示時,便可主動定位該item了。
準備材料已經上齊,相信通過前面的介紹,您一定對Gallery和ImageSwitcher控件很熟悉了,下面準備大餐!
步驟一:開啟一個線程,循環遍歷圖片集的資源id,並且將id發送至Hanlder對象。
步驟二:Handler接受到當前圖片資源的ID,調用setSelection (id)選中它(該Item selected),繼而setSelection()
觸發OnItemSelectedListener 事件,執行目標方法,這樣我們的目的就達到了。
下面,給出該Demo,希望能幫助大家更好的理解。
1 、 布局文件 main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <ImageSwitcher android:id="@+id/myimgSwitcher" android:layout_gravity="center" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="20dip"></ImageSwitcher> <Gallery android:id="@+id/mygallery" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#8A2BE2"></Gallery> </LinearLayout>
2 、主文件 MainActivity.Java
package com.lover.qinjun; import java.lang.reflect.Field; import java.util.ArrayList; import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.Gallery; import android.widget.ImageSwitcher; import android.widget.ImageView; import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ViewSwitcher.ViewFactory; public class MainActivity extends Activity implements ViewFactory { private static String TAG = "Gallery_Auto"; private static int MSG_UPDATE = 1; private int count_drawble = 0; private int cur_index = 0; private boolean isalive = true; 、//線程循環運行的條件 private ImageSwitcher imgSwitcher; private Gallery mgallery; // 為Gallery控件設置Adapter private ImageAdapter imgAdapter = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); imgSwitcher = (ImageSwitcher) findViewById(R.id.myimgSwitcher); mgallery = (Gallery) findViewById(R.id.mygallery); mgallery.setSpacing(3); //設置圖片之間的間隔,如果不加設置 ,圖片會疊加。設置為0,表示圖片之間無間縫。 // 設置監聽事件 --->當Gallery中的Item處於選中並且被點擊觸發該事件 mgallery.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View view, int position, long arg3) { System.out.println("setOnItemClickListener"); // imgSwitcher.setBackgroundResource(imgAdapter.getResId(position)); } }); //當Gallery中的Item處於選中並且被點擊觸發該事件 ,在該監聽事件中,保證圖片播放的同步性 mgallery.setOnItemSelectedListener(new OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> arg0, View view, int position, long arg3) { System.out.println("setOnItemSelectedListener"); //這兒不能通過setImageResource()設置圖片 imgSwitcher.setBackgroundResource(imgAdapter.getResId(position)); } @Override public void onNothingSelected(AdapterView<?> arg0) { } }); //構建適配器,並且分配 imgAdapter = new ImageAdapter(this); mgallery.setAdapter(imgAdapter); count_drawble = imgAdapter.getCount(); // 利用線程來更新 當前欲顯示的圖片id, 調用handler來選中當前圖片 new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub while (isalive) { cur_index = cur_index % count_drawble; // 圖片區間[0,count_drawable) Log.i(TAG, "cur_index"+ cur_index +" count_drawble --"+ count_drawble); //msg.arg1 = cur_index Message msg = mhandler.obtainMessage(MSG_UPDATE, cur_index, 0); mhandler.sendMessage(msg); //更新時間間隔為 2s try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } cur_index++; //放置在Thread.sleep(2000) ;防止mhandler處理消息的同步性,導致cur_index>=count_drawble } } }).start(); } //通過handler來更新主界面 mgallery.setSelection(positon),選中第position的圖片,然後調用OnItemSelectedListener監聽改變圖像 private Handler mhandler = new Handler() { public void handleMessage(Message msg) { if (msg.what == MSG_UPDATE) { Log.i(TAG, "cur_index"+ cur_index); mgallery.setSelection(msg.arg1); //UI Thread直接更改圖片 ,不利用Gallery.OnItemSelectedListener監聽更改 //imgSwitcher.setBackgroundResource(imgAdapter.getResId(msg.arg1)); } } }; public void onDestroy() { super.onDestroy(); isalive = false; } @Override public View makeView() { //ImageSwitcher的ViewFactory方法 // TODO Auto-generated method stub ImageView img = new ImageView(this); return img; } // 為Gallery控件提供適配器的類 class ImageAdapter extends BaseAdapter { private Context mcontext; private ArrayList<Integer> residList = new ArrayList<Integer>(); // 通過放射機制保存所有圖片的id public ImageAdapter(Context context) { mcontext = context; // 反射的可重用性更好 // R.id在R文件中本質上是一個類,我們通過這個R.id.class.getClass().getDeclaredFields()可以找到它的所有屬性 Field[] residFields = R.drawable.class.getDeclaredFields(); for (Field residField : residFields) { // 例如: public static final int icon=0x7f020000; // 它的Field表示為 : name= icon ; field.getInt() = 0x7f020000 if (!"icon".equals(residField.getName())) { int resid; try { resid = residField.getInt(null);// 找到該屬性的值 residList.add(resid); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } @Override public int getCount() { Log.e(TAG, " " + residList.size()); return residList.size(); } @Override public Object getItem(int position) { return residList.get(position); } @Override public long getItemId(int position) { return 0; } //得到該圖片的res id public int getResId(int position) { return residList.get(position); } @Override public View getView(int position, View convertView, ViewGroup parent) { ImageView img; if (convertView == null) { img = new ImageView(mcontext); img.setScaleType(ImageView.ScaleType.FIT_XY); img.setLayoutParams(new Gallery.LayoutParams(100, 100)); // 圖片顯示寬和長 img.setImageResource(residList.get(position)); } else { img = (ImageView) convertView; } return img; } } }
主要的工程邏輯如上 ,由於采用了放射機制,直接添加圖片資源便可成功運行了。
本文源代碼地址為:http://download.csdn.net/detail/qinjuning/3888134
Android Gallery和ImageSwitcher同步自動(滾動)播放圖片庫