Gallery

本文概述:

用gallery是实现图片手动滑动和自动滚动的效果

Gallery_第1张图片Gallery_第2张图片

基本解决方案:重写Gallery,重写里面的方法

1、手动滑动

gallery默认便是可进行手动滑动的,但滑动时会同时滑动多张,重写滑动事件onFling(),保证每次只滑动一张图片

        /**
	 * 一次只滑动一张图片
	 */
	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
		// TODO Auto-generated method stub

		int kEvent;
		if (isScrollingRight(e1, e2)) {
			kEvent = KeyEvent.KEYCODE_DPAD_LEFT;
		} else {
			kEvent = KeyEvent.KEYCODE_DPAD_RIGHT;
		}
		return onKeyDown(kEvent, null);
	}
上面有一个isScrollingRight(),只不过是用来判断是向左还是向右滑动:

        /**
	 * 判断手指是否向右滑动
	 */
	 private boolean isScrollingRight(MotionEvent e1, MotionEvent e2) {
		return e2.getX() > e1.getX();
	 }


2、自动滚动

构造一个计时器,隔一段时间便通知gallery该触发滑动事件onKeyDown(int keyCode,KeyEvent event);

        /**
	 * 构造计时器
	 */
	private Timer timer = new Timer();
	private TimerTask task = new TimerTask() {
		@Override
		public void run() {
			// TODO Auto-generated method stub
			handler.sendEmptyMessage(GUIDE_TIMER);
		}
	};
        Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case GUIDE_TIMER:
				onKeyDown(KeyEvent.KEYCODE_DPAD_RIGHT, null);
				break;
			}
		};
	};
       /**
	 * 开始计时
	 */
	public void startTimer() {
		timer.schedule(task, periodTime, periodTime);

	}
计时器的时间间隔periodTime可由外部传入,启动计时器后,每隔periodTime的时间gallery会自动滑动一张图片


3、图片滑动事件与点击事件的冲突问题

在自定义的gallery中重写onInterceptTouchEvent(MotionEvent ev)方法:

        /**
	 * 解决滑动和点击事件冲突,重写该方法拦截触屏事件,返回false将会上抛该事件到子view上面, 返回true则事件不会上抛,将在
	 * Gallery内部的OnTouchEvent() 接收做处理
	 */
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		// TODO Auto-generated method stub
		boolean b = super.onInterceptTouchEvent(ev);
		if (ev.getAction() == MotionEvent.ACTION_DOWN) {
			e = MotionEvent.obtain(ev);
			super.onTouchEvent(ev);
		} else if (ev.getAction() == MotionEvent.ACTION_MOVE) {
			if (Math.abs(ev.getX() - e.getX()) > 20 || Math.abs(ev.getY() - e.getY()) > 20) {
				b = true;
			}
		}
		return b;
	}
4、禁止手动滑动

gallery默认是可以进行手动滑动的,若只想让图片自动滚动,重写里面的 onTouchEvent(MotionEvent event)事件,将返回值返回false即可:

        /**
	 * 重写touch事件,禁止滑动
	 */
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		return false;
	}


5、无限循环自动滚动

上面的方法在自动滚动完最后一张图片后,gallery的自动滚动便会停止,若想让gallery滚动完最后一张后出现第一张重新滚动,可重新定义adapter,处理getCount()和getView()方法,将个数设置成Integer.MAX_VALUE,显示时对应将相应的图片展示出来即可:

        @Override
	public int getCount() {
		// TODO Auto-generated method stub
		return Integer.MAX_VALUE;
	}
        @Override
	public View getView(int position, View view, ViewGroup parent) {
		// TODO Auto-generated method stub
		if (view == null) {
			view = LayoutInflater.from(context).inflate(R.layout.gallery_item, null);
		}
		ImageView imageView = (ImageView) view.findViewById(R.id.item_iv);
		imageView.setImageResource(icon[position % icon.length]);
		return view;
	}
同时,为了让用户感觉可以左右无限循环,可将gallery默认选中最大值的中间部分,即使是刚开始也能左右都能滑动:

                int centerNum = Integer.MAX_VALUE / 2;
		centerNum -= centerNum % size;//size图片个数,显示的是第一张图片
		myGallery.setSelection(centerNum);// 设置默认选中
6、左右自动滚动(顺序滚动完最后一张,然后逆序滚动,逆序滚动到第一张,再顺序滚动)

此种实现不需要类似5那样处理adapter,像常规处理即可,处理类似上边的handler回调:

//position当前页,num图片数量
Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case GUIDE_TIMER:
				if (flag) {// 向右
					onScroll(null, null, 1, 0);
					onKeyDown(KeyEvent.KEYCODE_DPAD_RIGHT, null);
					if (position == num - 2) {//滑动到最后一张
						flag = false;
					}
				} else if (!flag) {// 向左
					onScroll(null, null, -1, 0);
					onKeyDown(KeyEvent.KEYCODE_DPAD_LEFT, null);
					if (position == 1) {//滑动到第一张
						flag = true;
					}
				}
				break;
			}
		};
	};
当前页的position可由设置监听 OnItemSelectedListener获得


7、自动滚动抖动问题

当gallery放在RelativeLayout中时,在滚动过程中会出现左右抖动,解决方法,将gallery的外面套的父RelativeLayout统统去掉(同级不影响),可选用Framelayout代替。


8、边框模糊问题

xml添加属性 android:fadingEdgeLength=”0dp”


9、设置setSpacing()后自动滚动失效

gallery设置setSpacing()之后会导致onKeyDown()失效,从而不能自动滚动,调用onScroll()方法可解决问题

                                /**
				 * gallery设置setSpacing()后,onKeyDown()会失效,添加onScroll方法可解决,
				 * 后面两个参数分别是自上次调用onScroll方法在X、Y上的距离
				 **/
				onScroll(null, null, 1, 0);
				onKeyDown(KeyEvent.KEYCODE_DPAD_RIGHT, null);

10、gallery每个子元素充满整个屏幕

如果显示的内容比较小,gallery会自动在一个屏幕显示好几个子元素,想要每个屏幕只显示一个元素,关键改变item的layout的最外层,使用RelativeLayout






11、禁止点击声音

setSoundEffectsEnabled(false);

12、禁止点击震动(触感反馈)

setHapticFeedbackEnabled(false);












你可能感兴趣的:(Android)