Gallery自动循环滚动,手动滚动的平滑切换及存在问题

来自:http://blog.csdn.net/lenghun00/article/details/7635374

 

 

@Gallery配合dot使用时,如果放在RelativeLayout中,则手动滑动有反弹现象,其他layout没问题,现在还没弄清原因。
首先继承Gallery重写OnFling函数,去除gallery的滚动惯性

  1. public class MyGallery extends Gallery {  
  2.   
  3.     public MyGallery(Context context, AttributeSet attrs) {  
  4.         super(context, attrs);  
  5.         // TODO Auto-generated constructor stub   
  6.     }  
  7.   
  8.     private boolean isScrollingLeft(MotionEvent e1, MotionEvent e2) {  
  9.   
  10.         return e2.getX() > e1.getX();  
  11.   
  12.     }  
  13.       
  14.     @Override  
  15.     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,  
  16.             float velocityY) {  
  17.         int keyCode;  
  18.   
  19.         if (isScrollingLeft(e1, e2)) {  
  20.   
  21.             keyCode = KeyEvent.KEYCODE_DPAD_LEFT;  
  22.   
  23.         } else {  
  24.   
  25.             keyCode = KeyEvent.KEYCODE_DPAD_RIGHT;  
  26.   
  27.         }  
  28.   
  29.         onKeyDown(keyCode, null);  
  30.   
  31.         return true;  
  32.     }  
  33.   
  34. }  
public class MyGallery extends Gallery {

	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();

	}
	
	@Override
	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;
	}

}

 

@OnFling直接返回false也能实现类似效果,但那样需要滑动很大距离,图片才会切换,用户体验不好

第二步,构造adapter

要想平滑的实现循环滚动,可以让getCount返回一个很大的值,这样gallery就认为是有多个item,item之间的切换动画是平滑的

  1. public class GalleryAdapter extends BaseAdapter {  
  2.   
  3.     private LayoutInflater mInflater;  
  4.     private Context mContext;  
  5.     private int width;  
  6.     private int count;  
  7.     private int[] mImageIds;  
  8.   
  9.     public GalleryAdapter(Context context, int[] ids) {  
  10.         mContext = context;  
  11.         mImageIds = ids;  
  12.         mInflater = LayoutInflater.from(mContext);  
  13.         DisplayMetrics dm = mContext.getApplicationContext().getResources()  
  14.                 .getDisplayMetrics();  
  15.         width = dm.widthPixels;  
  16.         count = mImageIds.length;  
  17.     }  
  18.   
  19.     @Override  
  20.     public int getCount() {  
  21.         return Integer.MAX_VALUE;//用于循环滚动  
  22.     }  
  23.   
  24.     @Override  
  25.     public Object getItem(int position) {  
  26.         return position;  
  27.     }  
  28.   
  29.     @Override  
  30.     public long getItemId(int position) {  
  31.         return position;  
  32.     }  
  33.   
  34.     @Override  
  35.     public View getView(int position, View convertView, ViewGroup parent) {  
  36.         position = position % count;  
  37.         if (convertView == null) {  
  38.             convertView = mInflater.inflate(R.layout.gallery_item, null);  
  39.         }  
  40.         ImageView v = (ImageView) convertView.findViewById(R.id.img);  
  41.         v.setLayoutParams(new Gallery.LayoutParams(width, 200));  
  42.         v.setScaleType(ImageView.ScaleType.FIT_XY);  
  43.         v.setBackgroundResource(mImageIds[position]);  
  44.         return v;  
  45.     }  
  46.   
  47. }  
public class GalleryAdapter extends BaseAdapter {

	private LayoutInflater mInflater;
	private Context mContext;
	private int width;
	private int count;
	private int[] mImageIds;

	public GalleryAdapter(Context context, int[] ids) {
		mContext = context;
		mImageIds = ids;
		mInflater = LayoutInflater.from(mContext);
		DisplayMetrics dm = mContext.getApplicationContext().getResources()
				.getDisplayMetrics();
		width = dm.widthPixels;
		count = mImageIds.length;
	}

	@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) {
		position = position % count;
		if (convertView == null) {
			convertView = mInflater.inflate(R.layout.gallery_item, null);
		}
		ImageView v = (ImageView) convertView.findViewById(R.id.img);
		v.setLayoutParams(new Gallery.LayoutParams(width, 200));
		v.setScaleType(ImageView.ScaleType.FIT_XY);
		v.setBackgroundResource(mImageIds[position]);
		return v;
	}

}

 

第三,实现自动滚动

由于我们还要手动滚动,所以自动滚动用单独一个进程来实现

  1. private void startAutoScroll() {  
  2.         new Thread() {  
  3.             @Override  
  4.             public void run() {  
  5.                 int count = 0;  
  6.                 while (mAutoScroll) {  
  7.                     count = 0;  
  8.                     while (count < 30) {  
  9.                         count++;  
  10.                         try {  
  11.                             Thread.sleep(100);  
  12.                         } catch (InterruptedException e) {  
  13.                             e.printStackTrace();  
  14.                         }  
  15.                         if (mOnTouch) {// 用戶手动滑动时,停止自动滚动  
  16.                             count = 0;  
  17.                         }  
  18.                     }  
  19.                     mPosition++;  
  20.                     Message msg = mHandler.obtainMessage(SCROLL, mPosition, 0);  
  21.                     mHandler.sendMessage(msg);  
  22.                 }  
  23.             }  
  24.   
  25.         }.start();  
  26.     }  
  27.   
  28.     private Handler mHandler = new Handler() {  
  29.   
  30.         @Override  
  31.         public void handleMessage(Message msg) {  
  32.             switch (msg.what) {  
  33.             case SCROLL:  
  34.                 mGallery.setSelection(msg.arg1);  
  35.                 break;  
  36.             }  
  37.         }  
  38.   
  39.     };  
private void startAutoScroll() {
		new Thread() {
			@Override
			public void run() {
				int count = 0;
				while (mAutoScroll) {
					count = 0;
					while (count < 30) {
						count++;
						try {
							Thread.sleep(100);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						if (mOnTouch) {// 用戶手动滑动时,停止自动滚动
							count = 0;
						}
					}
					mPosition++;
					Message msg = mHandler.obtainMessage(SCROLL, mPosition, 0);
					mHandler.sendMessage(msg);
				}
			}

		}.start();
	}

	private Handler mHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case SCROLL:
				mGallery.setSelection(msg.arg1);
				break;
			}
		}

	};

 

第四实现手动滚动

手动滚动时,要停止自动滚动,监听gallery的onTouch事件,DOWN时mOnTouch置为true,UPmOnTouch置为false即可

  1. mGallery.setOnTouchListener(new OnTouchListener() {  
  2.   
  3.             @Override  
  4.             public boolean onTouch(View v, MotionEvent event) {  
  5.                 int action = event.getAction();  
  6.                 if (action == MotionEvent.ACTION_DOWN) {  
  7.                     mOnTouch = true;  
  8.                 } else if (action == MotionEvent.ACTION_UP) {  
  9.                     mOnTouch = false;  
  10.                 }  
  11.                 return false;  
  12.             }  
  13.   
  14.         });  
mGallery.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				int action = event.getAction();
				if (action == MotionEvent.ACTION_DOWN) {
					mOnTouch = true;
				} else if (action == MotionEvent.ACTION_UP) {
					mOnTouch = false;
				}
				return false;
			}

		});


到现在我们已经可以自动滚动,手动滚动时自动滚动也会停止。

我们也许还需要加上dot提示图片滚动的位置

  1. LinearLayout layout = (LinearLayout) findViewById(R.id.dot);  
  2.         if (mDots == null) {  
  3.             mDots = new ImageView[ids.length];  
  4.             for (int i = 0; i < ids.length; i++) {  
  5.                 if (mDots[i] == null)  
  6.                     mDots[i] = new ImageView(this);  
  7.   
  8.                 mDots[i].setBackgroundResource(R.drawable.banner_tab_unselected);  
  9.                 layout.addView(mDots[i], new LinearLayout.LayoutParams(mWidth  
  10.                         / ids.length + 1, LayoutParams.WRAP_CONTENT));  
  11.             }  
  12.             mDots[0].setBackgroundResource(R.drawable.banner_tab_selected);  
  13.         }  
LinearLayout layout = (LinearLayout) findViewById(R.id.dot);
		if (mDots == null) {
			mDots = new ImageView[ids.length];
			for (int i = 0; i < ids.length; i++) {
				if (mDots[i] == null)
					mDots[i] = new ImageView(this);

				mDots[i].setBackgroundResource(R.drawable.banner_tab_unselected);
				layout.addView(mDots[i], new LinearLayout.LayoutParams(mWidth
						/ ids.length + 1, LayoutParams.WRAP_CONTENT));
			}
			mDots[0].setBackgroundResource(R.drawable.banner_tab_selected);
		}

 

  1. mGallery.setOnItemSelectedListener(new OnItemSelectedListener() {  
  2.   
  3.             @Override  
  4.             public void onItemSelected(AdapterView<?> arg0, View view,  
  5.                     int position, long arg3) {  
  6.                 mDotPosition = position % ids.length;  
  7.                 mDots[mDotPosition]  
  8.                         .setBackgroundResource(R.drawable.banner_tab_selected);  
  9.                 if (mDotPosition != mPreDotPosition)  
  10.                     mDots[mPreDotPosition]  
  11.                             .setBackgroundResource(R.drawable.banner_tab_unselected);  
  12.                 mPreDotPosition = mDotPosition;  
  13.             }  
  14.   
  15.             @Override  
  16.             public void onNothingSelected(AdapterView<?> arg0) {  
  17.                                   
  18.             }  
  19.               
  20.         });  

你可能感兴趣的:(gallery)