学习了一下android中的Gallery + ImageSwitcher,在网上找了点资料,做了个简单的电子相册。
并实现了自动播放效果,通过双击的手势来开启关闭自动播放。上图才是王道。
主要实现代码
package com.eebbk.elealbum.activity;
import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.ViewSwitcher.ViewFactory;
public class MainActivity extends Activity implements ViewFactory, OnItemSelectedListener, Runnable
{
//自动播放的标志位
private boolean isPlay = false;
//自动播放更新消息
private final static int UPDATE = 1;
//当前播放索引值
private int cur_index = 0;
// GestureDetector为手势识别类
private GestureDetector mGestureDetector;
private Gallery gallery = null;
private ImageSwitcher imageSwitcher = null;
private int[] imageIds =new int[]{
R.drawable.pic1 , R.drawable.pic2,
R.drawable.pic3 , R.drawable.pic4,
R.drawable.pic5 , R.drawable.pic6,
R.drawable.pic7 , R.drawable.pic8,
};
private Handler handler = new Handler( )
{
@Override
public void handleMessage( Message msg )
{
// TODO Auto-generated method stub
if ( msg.what == UPDATE )
{
gallery.setSelection( msg.arg1 );
}
super.handleMessage( msg );
}
};
/** Called when the activity is first created. */
@Override
public void onCreate( Bundle savedInstanceState )
{
super.onCreate( savedInstanceState );
//设置无标题
requestWindowFeature(Window.FEATURE_NO_TITLE);
//设置全屏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView( R.layout.main );
init( );
}
private void init( )
{
mGestureDetector = new GestureDetector( new MySimpleGesture( ));
gallery = ( Gallery ) findViewById( R.id.gallery_id );
gallery.setAdapter(new ImageAdaper( this ));
gallery.setOnItemSelectedListener(this);
imageSwitcher = ( ImageSwitcher ) findViewById( R.id.imageSwitcher_id );
imageSwitcher.setFactory( this );
//设置淡入淡出切换效果
imageSwitcher.setInAnimation( AnimationUtils.loadAnimation( this, android.R.anim.fade_in ) );
imageSwitcher.setOutAnimation( AnimationUtils.loadAnimation( this, android.R.anim.fade_out ) );
}
@Override
public boolean onTouchEvent( MotionEvent event )
{
// TODO Auto-generated method stub
mGestureDetector.onTouchEvent( event );
return super.onTouchEvent( event );
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK){
isPlay = false;
}
return super.onKeyDown(keyCode, event);
}
/* (non-Javadoc)
* @see android.widget.ViewSwitcher.ViewFactory#makeView()
*/
@Override
public View makeView( )
{
// TODO Auto-generated method stub
ImageView imageView = new ImageView(this);
imageView.setScaleType(imageView.getScaleType().FIT_CENTER);
imageView.setBackgroundColor(0xFF000000);
imageView.setLayoutParams(new ImageSwitcher.LayoutParams(LayoutParams.FILL_PARENT , LayoutParams.FILL_PARENT));
return imageView;
}
public class ImageAdaper extends BaseAdapter{
Context context;
int mGalleryItemBackground;
public ImageAdaper(Context context){
this.context = context;
TypedArray typedArray = obtainStyledAttributes(R.styleable.Gallery);
mGalleryItemBackground = typedArray.getResourceId( R.styleable.Gallery_android_galleryItemBackground, 0);
typedArray.recycle();
}
public int getCount() {
// TODO Auto-generated method stub
return Integer.MAX_VALUE;
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return imageIds[position];
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ImageView imageview = new ImageView(this.context);
imageview.setImageResource(imageIds[position % imageIds.length]);
imageview.setScaleType(ImageView.ScaleType.FIT_XY);
imageview.setLayoutParams(new Gallery.LayoutParams(136 , 88));
imageview.setBackgroundResource(mGalleryItemBackground);
return imageview;
}
}
/* (non-Javadoc)
* @see android.widget.AdapterView.OnItemSelectedListener#onItemSelected(android.widget.AdapterView, android.view.View, int, long)
*/
@Override
public void onItemSelected( AdapterView< ? > parent, View view, int position, long id )
{
//gallery选中一项之后,切换图片
System.out.println("position: " + position + "cur_index: " + cur_index);
imageSwitcher.setImageResource(imageIds[position%imageIds.length]);
}
/* (non-Javadoc)
* @see android.widget.AdapterView.OnItemSelectedListener#onNothingSelected(android.widget.AdapterView)
*/
@Override
public void onNothingSelected( AdapterView< ? > parent )
{
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run( )
{
// TODO Auto-generated method stub
while(isPlay)
{
//cur_index = cur_index % imageIds.length;
Message msg = handler.obtainMessage(UPDATE, cur_index, 0);
handler.sendMessage(msg);
//更新时间间隔为 2s
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
cur_index++;
}
}
private class MySimpleGesture extends SimpleOnGestureListener
{
// 按两下的第二下Touch down时触发
public boolean onDoubleTap( MotionEvent e )
{
//双击触发切换自动播放
if ( isPlay == false )
{
isPlay = true;
new Thread( MainActivity.this).start( );
}
else
{
isPlay = false;
}
return true;
}
}
}
源码附上:http://download.csdn.net/detail/tianmi1988/4914807
Gallery 高级应用
上面的示例,仅仅是最简单的Gallery应用,如果我们想做的更酷、更炫的效果:
1、Gallery 图片显示能够循环播放,即向右滑到左侧第一张图片后,需要接着显示最后一张图片;向左滑到最后一张图片后,需要接着显示第一张图片,往复不间断显示的循环效果。
2、选中图片高亮,未选中图片阴影,更加突出当前获取焦点的选中图片
3、区分“点击”与“选中”图片事件的区别和适用场景
效果1 —— 高亮显示
没有选中,在GalleryActivity中,设置gallery.setUnselectedAlpha(0.3f); 透明度为0.3
选中,在ImageAdapter的getView(int position, View convertView, ViewGroup parent)中,设置imageview.setBackgroundColor(Color.alpha(1)); 背景色为1
效果2 —— 循环播放
原理:Gallery循环播放的原理,跟循环链表的思想一样,首尾item连接都是通过“取余”实现
修改1、ImageAdapter中的getCount() 方法中,修改返回值为无穷大 return Integer.MAX_VALUE;
修改2、ImageAdapter中的getView(int position, View convertView, ViewGroup parent)方法中,设置imageview.setImageResource(imgs[position % imgs.length]); 取余
修改3、GalleryActivity中,设置gallery.setSelection(imgAdapter.imgs.length * 100); 使gallery显示图片的位置从中间开始显示(即imgAdapter.imgs.length * 100)
修改解释:
修改1,主要是为了是循环接近无限往复循环,使position无限大,循环在实践应用上不容易结束(理论上会结束,即2^31-1约20亿次循环后)
修改2,通过取余,使图片能够重复利用并显示
修改3,由于起始位置如果是0,则向右滑动左侧将无法循环(此时左侧将为-1,超出了imgs[]数组的下边界),因此开始应设置起始位置为imgAdapter.imgs.length的整数倍
效果3 —— “点击”和“选中”事件
1、点击事件OnItemClickListener,是需要用手点击才触发,滑动时不触发
2、选中事件OnItemSelectedListener,是当图片滑到屏幕正中,则视为自动选中,在滑动的过程中会触发
适用场景:
1、点击事件OnItemClickListener,是在确定要选中该项时,才点击进行逻辑处理
2、选中事件OnItemSelectedListener,可以用来提醒用户,当前获取焦点的项,如果确认为该项则需要点击OnItemClickListener后,进行下一步的逻辑处理
高级应用完整代码:
Activity
importandroid.app.Activity;
importandroid.os.Bundle;
importandroid.view.Gravity;
importandroid.view.View;
importandroid.widget.AdapterView;
importandroid.widget.Gallery;
importandroid.widget.Toast;
publicclass GalleryActivity extendsActivity {
privateImageAdapter imgAdapter = null; // 声明图片资源对象
privateGallery gallery = null;
@Override
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
gallery = (Gallery) findViewById(R.id.gallery);
imgAdapter = newImageAdapter(this);
gallery.setAdapter(imgAdapter); // 设置图片资源
gallery.setGravity(Gravity.CENTER_HORIZONTAL); // 设置水平居中显示
gallery.setSelection(imgAdapter.imgs.length * 100); // 设置起始图片显示位置(可以用来制作gallery循环显示效果)
gallery.setOnItemClickListener(clickListener); // 设置点击图片的监听事件(需要用手点击才触发,滑动时不触发)
gallery.setOnItemSelectedListener(selectedListener); // 设置选中图片的监听事件(当图片滑到屏幕正中,则视为自动选中)
gallery.setUnselectedAlpha(0.3f); // 设置未选中图片的透明度
gallery.setSpacing(40); // 设置图片之间的间距
}
// 点击图片的监听事件
AdapterView.OnItemClickListener clickListener = newAdapterView.OnItemClickListener() {
@Override
publicvoid onItemClick(AdapterView parent, View view, intposition, longid) {
Toast.makeText(GalleryActivity.this,"点击图片 " + (position + 1),100).show();
}
};
// 选中图片的监听事件
AdapterView.OnItemSelectedListener selectedListener = newAdapterView.OnItemSelectedListener() {
@Override
publicvoid onItemSelected(AdapterView parent, View view, intposition, longid) {
Toast.makeText(GalleryActivity.this,"选中图片 " + (position + 1),20).show();
}
@Override
publicvoid onNothingSelected(AdapterView arg0) {
}
};
}
ImageAdapter.java
importandroid.content.Context;
importandroid.graphics.Color;
importandroid.view.View;
importandroid.view.ViewGroup;
importandroid.widget.BaseAdapter;
importandroid.widget.Gallery;
importandroid.widget.ImageView;
publicclass ImageAdapter extendsBaseAdapter {
privateContext mContext;
// 图片数组源
publicInteger[] imgs = { R.drawable.img1, R.drawable.img2,
R.drawable.img3, R.drawable.img4, R.drawable.img5,
R.drawable.img6, R.drawable.img7};
publicImageAdapter(Context c) {
mContext = c;
}
@Override
publicint getCount() {
returnInteger.MAX_VALUE;
}
// 获取图片位置
@Override
publicObject getItem(intposition) {
returnimgs[position];
}
// 获取图片ID
@Override
publiclong getItemId(intposition) {
returnposition;
}
@Override
publicView getView(intposition, View convertView, ViewGroup parent) {
ImageView imageview = newImageView(mContext);
imageview.setImageResource(imgs[position % imgs.length]);
imageview.setLayoutParams(newGallery.LayoutParams(200,94)); // 设置布局 图片120×120显示
imageview.setScaleType(ImageView.ScaleType.CENTER); // 设置显示比例类型
imageview.setBackgroundColor(Color.alpha(1));
returnimageview;
}
}