【Android 界面效果7】Android中Gallery和ImageSwitcher同步自动(滚动)播放图片库

十度 Android 2015年12月02日 收藏

  本文主要内容是如何让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

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical" android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent">  
  5.     <TextView android:layout_width="fill_parent"  
  6.         android:layout_height="wrap_content" android:text="@string/hello" />  
  7.     <ImageSwitcher android:id="@+id/myimgSwitcher" android:layout_gravity="center"  
  8.         android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="20dip"></ImageSwitcher>  
  9.     <Gallery android:id="@+id/mygallery" android:layout_width="fill_parent"  
  10.         android:layout_height="wrap_content" android:background="#8A2BE2"></Gallery>  
  11. </LinearLayout>  

 

  2 、主文件 MainActivity.java

  1. package com.lover.qinjun;  
  2.   
  3. import java.lang.reflect.Field;  
  4. import java.util.ArrayList;  
  5.   
  6. import android.app.Activity;  
  7. import android.content.Context;  
  8. import android.os.Bundle;  
  9. import android.os.Handler;  
  10. import android.os.Message;  
  11. import android.util.Log;  
  12. import android.view.View;  
  13. import android.view.ViewGroup;  
  14. import android.view.View.OnClickListener;  
  15. import android.widget.AdapterView;  
  16. import android.widget.BaseAdapter;  
  17. import android.widget.Gallery;  
  18. import android.widget.ImageSwitcher;  
  19. import android.widget.ImageView;  
  20. import android.widget.AdapterView.OnItemClickListener;  
  21. import android.widget.AdapterView.OnItemSelectedListener;  
  22. import android.widget.ViewSwitcher.ViewFactory;  
  23.   
  24. public class MainActivity extends Activity implements ViewFactory {  
  25.     private static String TAG = "Gallery_Auto";  
  26.     private static int MSG_UPDATE = 1;  
  27.   
  28.     private int count_drawble = 0;  
  29.     private int cur_index = 0;  
  30.     private boolean isalive = true; 、//线程循环运行的条件   
  31.     private ImageSwitcher imgSwitcher;  
  32.     private Gallery mgallery;  
  33.     // 为Gallery控件设置Adapter  
  34.     private ImageAdapter imgAdapter = null;  
  35.   
  36.     /** Called when the activity is first created. */  
  37.     @Override  
  38.     public void onCreate(Bundle savedInstanceState) {  
  39.         super.onCreate(savedInstanceState);  
  40.         setContentView(R.layout.main);  
  41.         imgSwitcher = (ImageSwitcher) findViewById(R.id.myimgSwitcher);  
  42.         mgallery = (Gallery) findViewById(R.id.mygallery);  
  43.         mgallery.setSpacing(3); //设置图片之间的间隔,如果不加设置 ,图片会叠加。设置为0,表示图片之间无间缝。  
  44.         // 设置监听事件 --->当Gallery中的Item处于选中并且被点击触发该事件   
  45.         mgallery.setOnItemClickListener(new OnItemClickListener() {  
  46.             @Override  
  47.             public void onItemClick(AdapterView<?> arg0, View view,  
  48.                     int position, long arg3) {  
  49.                 System.out.println("setOnItemClickListener");  
  50. //              imgSwitcher.setBackgroundResource(imgAdapter.getResId(position));  
  51.             }  
  52.         });  
  53.         //当Gallery中的Item处于选中并且被点击触发该事件   ,在该监听事件中,保证图片播放的同步性  
  54.         mgallery.setOnItemSelectedListener(new OnItemSelectedListener() {  
  55.             @Override  
  56.             public void onItemSelected(AdapterView<?> arg0, View view,  
  57.                     int position, long arg3) {  
  58.                  System.out.println("setOnItemSelectedListener");  
  59.                  //这儿不能通过setImageResource()设置图片   
  60.                  imgSwitcher.setBackgroundResource(imgAdapter.getResId(position));  
  61.             }  
  62.             @Override  
  63.             public void onNothingSelected(AdapterView<?> arg0) {  
  64.   
  65.             }  
  66.         });  
  67.         //构建适配器,并且分配  
  68.         imgAdapter = new ImageAdapter(this);  
  69.         mgallery.setAdapter(imgAdapter);  
  70.         count_drawble = imgAdapter.getCount();  
  71.   
  72.         // 利用线程来更新 当前欲显示的图片id, 调用handler来选中当前图片  
  73.         new Thread(new Runnable() {  
  74.             @Override  
  75.             public void run() {  
  76.                 // TODO Auto-generated method stub  
  77.                 while (isalive) {  
  78.                     cur_index = cur_index % count_drawble;  // 图片区间[0,count_drawable)  
  79.                     Log.i(TAG, "cur_index"+ cur_index +" count_drawble --"+ count_drawble);  
  80.                     //msg.arg1 = cur_index   
  81.                     Message msg = mhandler.obtainMessage(MSG_UPDATE, cur_index, 0);  
  82.                     mhandler.sendMessage(msg);  
  83.                     //更新时间间隔为 2s   
  84.                     try {  
  85.                         Thread.sleep(2000);  
  86.                     } catch (InterruptedException e) {  
  87.                         // TODO Auto-generated catch block  
  88.                         e.printStackTrace();  
  89.                     }  
  90.                     cur_index++;  //放置在Thread.sleep(2000) ;防止mhandler处理消息的同步性,导致cur_index>=count_drawble  
  91.                 }  
  92.             }  
  93.         }).start();  
  94.     }  
  95.     //通过handler来更新主界面  mgallery.setSelection(positon),选中第position的图片,然后调用OnItemSelectedListener监听改变图像  
  96.     private Handler mhandler = new Handler() {  
  97.         public void handleMessage(Message msg) {  
  98.             if (msg.what == MSG_UPDATE) {  
  99.                 Log.i(TAG, "cur_index"+ cur_index);  
  100.                 mgallery.setSelection(msg.arg1);  
  101.                 //UI Thread直接更改图片 ,不利用Gallery.OnItemSelectedListener监听更改  
  102.                 //imgSwitcher.setBackgroundResource(imgAdapter.getResId(msg.arg1));  
  103.             }  
  104.         }  
  105.     };  
  106.   
  107.     public void onDestroy() {  
  108.         super.onDestroy();  
  109.         isalive = false;  
  110.     }  
  111.   
  112.     @Override  
  113.     public View makeView() {   //ImageSwitcher的ViewFactory方法  
  114.         // TODO Auto-generated method stub  
  115.         ImageView img = new ImageView(this);  
  116.         return img;  
  117.     }  
  118.   
  119.     // 为Gallery控件提供适配器的类  
  120.     class ImageAdapter extends BaseAdapter {  
  121.         private Context mcontext;  
  122.         private ArrayList<Integer> residList = new ArrayList<Integer>(); // 通过放射机制保存所有图片的id  
  123.   
  124.         public ImageAdapter(Context context) {  
  125.             mcontext = context;  
  126.             // 反射的可重用性更好  
  127.             // R.id在R文件中本质上是一个类,我们通过这个R.id.class.getClass().getDeclaredFields()可以找到它的所有属性  
  128.             Field[] residFields = R.drawable.class.getDeclaredFields();  
  129.             for (Field residField : residFields) {  
  130.                 // 例如: public static final int icon=0x7f020000;  
  131.                 // 它的Field表示为 : name= icon ; field.getInt() = 0x7f020000  
  132.                 if (!"icon".equals(residField.getName())) {  
  133.                     int resid;  
  134.                     try {  
  135.                         resid = residField.getInt(null);// 找到该属性的值  
  136.                         residList.add(resid);  
  137.                     } catch (IllegalArgumentException e) {  
  138.                         // TODO Auto-generated catch block  
  139.                         e.printStackTrace();  
  140.                     } catch (IllegalAccessException e) {  
  141.                         // TODO Auto-generated catch block  
  142.                         e.printStackTrace();  
  143.                     }  
  144.                 }  
  145.             }  
  146.         }  
  147.   
  148.         @Override  
  149.         public int getCount() {  
  150.             Log.e(TAG, " " + residList.size());  
  151.             return residList.size();  
  152.         }  
  153.   
  154.         @Override  
  155.         public Object getItem(int position) {  
  156.             return residList.get(position);  
  157.         }  
  158.   
  159.         @Override  
  160.         public long getItemId(int position) {  
  161.             return 0;  
  162.         }  
  163.         //得到该图片的res id  
  164.         public int getResId(int position) {  
  165.             return residList.get(position);  
  166.         }  
  167.   
  168.         @Override  
  169.         public View getView(int position, View convertView, ViewGroup parent) {  
  170.             ImageView img;  
  171.             if (convertView == null) {  
  172.                 img = new ImageView(mcontext);  
  173.                 img.setScaleType(ImageView.ScaleType.FIT_XY);  
  174.                 img.setLayoutParams(new Gallery.LayoutParams(100100)); // 图片显示宽和长  
  175.                 img.setImageResource(residList.get(position));  
  176.             } else {  
  177.                 img = (ImageView) convertView;  
  178.             }  
  179.             return img;  
  180.         }  
  181.   
  182.     }  
  183. }  

 

  

     主要的工程逻辑如上 ,由于采用了放射机制,直接添加图片资源便可成功运行了。

  

       本文源代码地址为:http://download.csdn.net/detail/qinjuning/3888134