最近在项目中用到图片轮播,试了Gallery,ViewFlipper,ViewPager,感觉Gallery最符合需求,但是Gallery的系统边框很难看,项目中要求用自己的背景图片。
下面来看一下使用Gallery实现图片轮播
运行效果:
布局文件:
<FrameLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="16dp" android:paddingRight="16dp" android:paddingTop="10dp" > <Gallery android:id="@+id/gallery" android:layout_width="fill_parent" android:layout_height="wrap_content" android:fadingEdge="none" android:spacing="0dp" /> <RelativeLayout android:layout_width="fill_parent" android:layout_height="18dp" android:layout_gravity="bottom" android:layout_marginBottom="3dp" android:layout_marginLeft="3dp" android:layout_marginRight="3dp" android:background="#80776f63" android:gravity="center" > <ImageView android:id="@+id/dot_1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_dot_normal" /> <ImageView android:id="@+id/dot_2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_toRightOf="@+id/dot_1" android:src="@drawable/ic_dot_normal" /> <ImageView android:id="@+id/dot_3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_toRightOf="@+id/dot_2" android:src="@drawable/ic_dot_normal" /> </RelativeLayout> </FrameLayout>其中, android:fadingEdge="none"消除图片两边的阴影。使用FrameLayout在底部显示小圆点
public class MainActivity extends Activity { private Gallery mGallery; private int index = 0;// 记录选中的图片位置 private ImageView[] mImageViewIds;// 小圆点ImageView数组 private static final int IMAGE_COUNT = 3;// 小圆点个数 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViews(); mImageViewIds[0].setImageDrawable(getBaseContext().getResources() .getDrawable(R.drawable.ic_dot_focused)); ImageAdapteradapter = new ImageAdapter(this); mGallery.setAdapter(adapter); Timer timer = new Timer(); timer.schedule(task, 2000, 2000); mGallery.setOnItemSelectedListener(onItemSelectedListener); mGallery.setOnItemClickListener(onItemClickListener); } private void findViews() { mGallery = (Gallery) findViewById(R.id.gallery); mImageViewIds = new ImageView[] { (ImageView) findViewById(R.id.dot_1), (ImageView) findViewById(R.id.dot_2), (ImageView) findViewById(R.id.dot_3) }; } private TimerTask task = new TimerTask() { @Override public void run() { Message message = new Message(); message.what = 2; index = mGallery.getSelectedItemPosition(); index++; handler.sendMessage(message); } }; /** * 开一个线程执行耗时操作 */ private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 2: mGallery.setSelection(index); break; default: break; } } }; /** * 设置小圆点显示,position会一直增加,如果要循环显示图片,需要对position取余,否则数组越界 */ private OnItemSelectedListener onItemSelectedListener = new OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { int pos = position % IMAGE_COUNT; mImageViewIds[pos].setImageDrawable(getBaseContext().getResources() .getDrawable(R.drawable.ic_dot_focused)); if (pos > 0) { mImageViewIds[pos - 1].setImageDrawable(getBaseContext() .getResources().getDrawable(R.drawable.ic_dot_normal)); } if (pos < (IMAGE_COUNT - 1)) { mImageViewIds[pos + 1].setImageDrawable(getBaseContext() .getResources().getDrawable(R.drawable.ic_dot_normal)); } if (pos == 0) { mImageViewIds[IMAGE_COUNT - 1] .setImageDrawable(getBaseContext().getResources() .getDrawable(R.drawable.ic_dot_normal)); } } @Override public void onNothingSelected(AdapterView<?> arg0) { // TODO Auto-generated method stub } }; /** * 点击事件,点击图片进入SecondActivity */ private OnItemClickListener onItemClickListener = new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) { Intent intent = new Intent(); intent.setClass(MainActivity.this, SecondActivity.class); startActivity(intent); } }; }ImageAdapter类,重写android.widget.BaseAdapter,用于描述图像信息。
public class ImageAdapter extends BaseAdapter { private Context context; private int[] mImages = { R.drawable.bg_timeline_01, R.drawable.bg_timeline_02, R.drawable.bg_timeline_03 }; private static final int IMAGE_PX_HEIGHT = 198; public ImageAdapter(Context context) { this.context = context; } @Override public int getCount() { return Integer.MAX_VALUE;//实现循环显示 } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ImageView imageView = new ImageView(context); imageView.setImageResource(mImages[position % mImages.length]); imageView.setScaleType(ImageView.ScaleType.CENTER); imageView.setLayoutParams(new Gallery.LayoutParams( Gallery.LayoutParams.FILL_PARENT, IMAGE_PX_HEIGHT)); RelativeLayout borderImg = new RelativeLayout(context); borderImg.setPadding(2, 2, 2, 2); borderImg.setBackgroundResource(R.drawable.bg_gallery);//设置ImageView边框 borderImg.addView(imageView); return borderImg; } }
int mGalleryItemBackground; private Context mContext; public ImageAdapter(Context context) { mContext = context; // 获得Gallery组件的属性 TypedArray typedArray = obtainStyledAttributes(R.styleable.Gallery); mGalleryItemBackground = typedArray.getResourceId( R.styleable.Gallery_android_galleryItemBackground, 0); }在getview中设置
imageView.setBackgroundResource(mGalleryItemBackground);Gallery组件属性信息定义在res\values\attrs.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="Gallery"> <attr name="android:galleryItemBackground" /> </declare-styleable> </resources>详细讲解见 http://www.eoeandroid.com/forum.php?mod=viewthread&tid=182297
自定义边框参考http://stackoverflow.com/questions/4830173/change-border-style-in-gallery
下面是控制gallery滑动过快的方法,重写gallery的手势操作
public class MyGallery extends Gallery { public MyGallery(Context context) { super(context); // TODO Auto-generated constructor stub } public MyGallery(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub } private boolean isScrollingLeft(MotionEvent e1, MotionEvent e2) { return e2.getX() > e1.getX(); } public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { int keyCode; if (isScrollingLeft(e1, e2)) { keyCode = KeyEvent.KEYCODE_DPAD_LEFT; } else { keyCode = KeyEvent.KEYCODE_DPAD_RIGHT; } onKeyDown(keyCode, null); return true; } }