Android之ImageSwitcher,Gallery用法
今天在做一个软件界面时用到了ImageSwitcher和Gallery控件,在看API时,感觉上面的例子讲的不是很具体,效率并不高。在这里我就以一个图片浏览功能来具体说明这两个控件的用法。
首先看运行效果:
在这里图片我用的是API中的图片。先说下这个图片浏览的功能吧,首先,它要实现图片的切换,当点击上面的小图时,下方会出现对象的大图,其次就是实现上图中最上面的样式,即一个图片和一个文本。下来我们还要实现起始位置居中,滑动小图的速率的控制,最上面小图的无限循环等功能。下面我就将具体实现代码附下,供大家参考。
main.xml:
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical"> 6 <cn.yj3g.gallery.MyGallery android:id="@+id/gallery" 7 android:background="#55000000" 8 android:layout_width="match_parent" 9 android:layout_height="80dp" 10 android:gravity="center_vertical" 11 android:spacing="2dp" 12 /> 13 <ImageSwitcher android:id="@+id/switcher" 14 android:layout_width="match_parent" 15 android:layout_height="match_parent" 16 android:layout_weight="1" 17 /> 18 </LinearLayout>
在上面我是自定义视图,引用自己定义的一个Gallery,在这个Gallery中我重新设置的滑动的速率,让它滑动速度放慢,下面是我自定义的Gallery
代码:
MyGallery.java:
下面是在定义gallery布局文件的代码:
gallery_item.xml:
下面就是核心实现代码:
PictrueChangeActivity:
1 package cn.yj3g.PictrueChange; 2 3 import java.util.HashMap; 4 5 import android.app.Activity; 6 import android.content.Context; 7 import android.content.res.TypedArray; 8 import android.os.Bundle; 9 import android.util.Log; 10 import android.view.LayoutInflater; 11 import android.view.View; 12 import android.view.ViewGroup; 13 import android.view.Window; 14 import android.view.animation.AnimationUtils; 15 import android.widget.AdapterView; 16 import android.widget.BaseAdapter; 17 import android.widget.Gallery; 18 import android.widget.Gallery.LayoutParams; 19 import android.widget.ImageSwitcher; 20 import android.widget.ImageView; 21 import android.widget.TextView; 22 import android.widget.ViewSwitcher; 23 24 public class PictrueChangeActivity extends Activity implements AdapterView.OnItemClickListener, 25 ViewSwitcher.ViewFactory { 26 //定义ImageSwitcher类对象 27 private ImageSwitcher mSwitcher; 28 //文本资源 29 private String[] titles = {"标题1","标题2","标题3","标题4","标题5","标题6","标题7","标题8",}; 30 //大图资源 31 private Integer[] mThumbIds = { R.drawable.sample_0, R.drawable.sample_1, R.drawable.sample_2, 32 R.drawable.sample_3, R.drawable.sample_4, R.drawable.sample_5, R.drawable.sample_6, 33 R.drawable.sample_7 }; 34 //大图对应的小图资源 35 private Integer[] mImageIds = { R.drawable.sample_thumb_0, R.drawable.sample_thumb_1, 36 R.drawable.sample_thumb_2, R.drawable.sample_thumb_3, R.drawable.sample_thumb_4, 37 R.drawable.sample_thumb_5, R.drawable.sample_thumb_6, R.drawable.sample_thumb_7 }; 38 @Override 39 public void onCreate(Bundle savedInstanceState) { 40 super.onCreate(savedInstanceState); 41 //设置窗体无标题 42 requestWindowFeature(Window.FEATURE_NO_TITLE); 43 setContentView(R.layout.main); 44 mSwitcher = (ImageSwitcher) findViewById(R.id.switcher); 45 mSwitcher.setFactory(this); 46 //设置图片的滑动效果 47 mSwitcher.setInAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_in)); 48 mSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_out)); 49 50 Gallery g = (Gallery) findViewById(R.id.gallery); 51 //设置Gallery的适配器 52 g.setAdapter(new ImageAdapter(this, mThumbIds.length)); 53 //Gallery中每个条目的点击事件监听 54 g.setOnItemClickListener(this); 55 //设置默认其实位置为第二张图片 56 g.setSelection(1); 57 } 58 59 public void onItemSelected(AdapterView parent, View v, int position, long id) { 60 mSwitcher.setImageResource(mThumbIds[position % mImageIds.length]); 61 } 62 public void onNothingSelected(AdapterView parent) { 63 } 64 65 @Override 66 public View makeView() { 67 ImageView i = new ImageView(this); 68 i.setBackgroundColor(0xFF000000); 69 i.setScaleType(ImageView.ScaleType.FIT_CENTER); 70 i.setLayoutParams(new ImageSwitcher.LayoutParams(LayoutParams.MATCH_PARENT, 71 LayoutParams.MATCH_PARENT)); 72 return i; 73 } 74 //Gallery的适配器 75 public class ImageAdapter extends BaseAdapter { 76 private int mGalleryItemBackground; 77 //定义map存储划过的位置 78 private HashMap<Integer, View> mViewMaps; 79 private int mCount; 80 //定义布局加载器 81 private LayoutInflater mInflater; 82 83 public ImageAdapter(Context c, int count) { 84 this.mCount = count; 85 mViewMaps = new HashMap<Integer, View>(count); 86 mInflater = LayoutInflater.from(PictrueChangeActivity.this); 87 //定义图片的背景样式 88 TypedArray a = obtainStyledAttributes(R.styleable.Gallery1); 89 mGalleryItemBackground = a.getResourceId( 90 R.styleable.Gallery1_android_galleryItemBackground, 0); 91 //定义可以重复使用.可回收 92 a.recycle(); 93 } 94 95 public int getCount() { 96 //设置循环的次数 97 return Integer.MAX_VALUE; 98 } 99 100 public Object getItem(int position) { 101 return position; 102 } 103 104 public long getItemId(int position) { 105 return position; 106 } 107 108 public View getView(int position, View convertView, ViewGroup parent) { 109 Log.v("TAG", "getView() position=" + position + " convertView=" + convertView); 110 View viewGroup = mViewMaps.get(position%mCount); 111 ImageView imageView = null; 112 TextView textView = null; 113 if(viewGroup==null) { 114 viewGroup = mInflater.inflate(R.layout.gallery_item, null); 115 imageView = (ImageView) viewGroup.findViewById(R.id.item_gallery_image); 116 textView = (TextView) viewGroup.findViewById(R.id.item_gallery_text); 117 imageView.setBackgroundResource(mGalleryItemBackground); 118 mViewMaps.put(position%mCount, viewGroup); 119 imageView.setImageResource(mImageIds[position % mImageIds.length]); 120 textView.setText(titles[position % mImageIds.length]); 121 } 122 123 return viewGroup; 124 } 125 } 126 //记录当前位置 127 private int curruntPos = -1; 128 @Override 129 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 130 if (curruntPos == position) { 131 return; 132 } else 133 curruntPos = position; 134 mSwitcher.setImageResource(mThumbIds[position % mThumbIds.length]); 135 } 136 }
这里要加载一个背景文件,放在values目录下,文件名为attrs.xml,代码如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <resources> 3 4 <!-- These are the attributes that we want to retrieve from the theme 5 in view/Gallery1.java --> 6 <declare-styleable name="Gallery1"> 7 <attr name="android:galleryItemBackground" /> 8 </declare-styleable> 9 10 </resources>
这样显示的图片就有一个相框一样的边框。
在上面的代码中,和API中不同的是做了四点改进:
1.实现滑动可以无限滑动,就是在上面的getCount()中,返回的是一个Integer.MAX_VALUE,这样可以做到无限滑动。
2.提高在滑动时大图的显示效率。就是在上面,我自定义了一个Map,将滑动过的位置全部记录下来,等到下次滑到这个位置时,就不必再去加载图片了,类似于缓存。这样提高了效率。
3.在点击事件中,如果重复点击同一张图片,不会去加载图片。在这里我设置了一个标记位置,如果标记位置和当前位置一样,那就不去加载图片。
4.设置起始位置为第二位,这样初始界面比较美观,显示的图片两边都有图片。