`
onewayonelife
  • 浏览: 252189 次
  • 性别: Icon_minigender_1
  • 来自: 太原
社区版块
存档分类
最新评论

Android 自定义滚动视图

阅读更多

MainActivity

package org.wp.activity;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ImageView;

public class MainActivity extends Activity {
	private ImageScrollView imageScrollView = null;
	private PageControlView pageControlView = null;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		imageScrollView = (ImageScrollView) this.findViewById(R.id.myImageScrollView);

		ImageView imageView = new ImageView(this);
		imageView.setImageResource(R.drawable.a1);
		imageScrollView.addView(imageView);

		imageView = new ImageView(this);
		imageView.setImageResource(R.drawable.a2);
		imageScrollView.addView(imageView);

		imageView = new ImageView(this);
		imageView.setImageResource(R.drawable.a3);
		imageScrollView.addView(imageView);

		imageView = new ImageView(this);
		imageView.setImageResource(R.drawable.a4);
		imageScrollView.addView(imageView);

		imageView = new ImageView(this);
		imageView.setImageResource(R.drawable.a5);
		imageScrollView.addView(imageView);

		imageView = new ImageView(this);
		imageView.setImageResource(R.drawable.a6);
		imageScrollView.addView(imageView);

		pageControlView = (PageControlView) this.findViewById(R.id.myPageControlView);
		/** 设置圆圈的数量 **/
		pageControlView.setCount(imageScrollView.getChildCount());
		/** 初始化圆圈 **/
		pageControlView.generatePageControl(0);
		/** 设置视图切换回调函数实现 **/
		imageScrollView.setScrollToScreenCallback(pageControlView);
	}
}

 

ImageScrollView

package org.wp.activity;

import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.Scroller;

public class ImageScrollView extends ViewGroup {
	/** 滚动对象Scroller **/
	private Scroller scroller = null;
	/** 手势识别对象GestureDetector **/
	private GestureDetector gestureDetector = null;
	/** 当前屏幕索引 **/
	private int currentScreenIndex = 0;
	/** 设置一个标志位,防止底层的onTouch事件重复处理UP事件 **/
	private boolean fling = false;

	public ImageScrollView(Context context, AttributeSet attrs) {
		super(context, attrs);
		initView(context);
	}

	@Override
	protected void onLayout(boolean changed, int left, int top, int right,
			int bottom) {
		/** 设置布局,将子视图顺序横屏排列 **/
		for (int i = 0; i < getChildCount(); i++) {
			View child = getChildAt(i);
			child.setVisibility(View.VISIBLE);
			child.measure(right - left, bottom - top);
			child.layout(i * getWidth(), 0, (i + 1) * getWidth(), getHeight());
		}
	}

	/** 初始化 **/
	private void initView(final Context context) {
		this.scroller = new Scroller(context);

		this.gestureDetector = new GestureDetector(new OnGestureListener() {
			@Override
			public boolean onSingleTapUp(MotionEvent e) {
				return false;
			}

			@Override
			public void onShowPress(MotionEvent e) {
			}

			@Override
			public boolean onScroll(MotionEvent e1, MotionEvent e2,
					float distanceX, float distanceY) {
				// 防止移动过最后一页
				if ((distanceX > 0 && getScrollX() < getWidth() * (getChildCount() - 1))
						|| (distanceX < 0 && getScrollX() > 0)) {// 防止向第一页之前移动
					scrollBy((int) distanceX, 0);
				}
				return true;
			}

			@Override
			public void onLongPress(MotionEvent e) {
			}

			@Override
			public boolean onFling(MotionEvent e1, MotionEvent e2,
					float velocityX, float velocityY) {
				// 判断是否达到最小轻松速度,取绝对值的
				if (Math.abs(velocityX) > ViewConfiguration.get(context)
						.getScaledMinimumFlingVelocity()) {
					if (velocityX > 0 && currentScreenIndex > 0) {
						fling = true;
						scrollToScreen(currentScreenIndex - 1);
					} else if (velocityX < 0 && currentScreenIndex < getChildCount() - 1) {
						fling = true;
						scrollToScreen(currentScreenIndex + 1);
					}
				}
				return true;
			}

			@Override
			public boolean onDown(MotionEvent e) {
				return false;
			}
		});
	}

	/** 切换到指定屏 **/
	public void scrollToScreen(int whichScreen) {
		if (whichScreen != currentScreenIndex && getFocusedChild() != null
				&& getFocusedChild() == getChildAt(currentScreenIndex)) {
			getFocusedChild().clearFocus(); // 清除焦点
		}

		final int delta = whichScreen * getWidth() - getScrollX();
		scroller.startScroll(getScrollX(), 0, delta, 0, Math.abs(delta) * 2);
		invalidate();

		currentScreenIndex = whichScreen; // 设置当前屏幕索引
		if (scrollToScreenCallback != null) { // 刷新圆圈
			scrollToScreenCallback.callback(currentScreenIndex);
		}
	}

	@Override
	public void computeScroll() {
		// 当滚动没有完成
		if (scroller.computeScrollOffset()) {
			scrollTo(scroller.getCurrX(), 0);
			postInvalidate();
		}
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		gestureDetector.onTouchEvent(event);

		if (event.getAction() == MotionEvent.ACTION_UP) {
			if (!fling) {
				// 当用户停止拖动
				snapToDestination();
			}
			fling = false;
		}
		return true;
	}

	/** 根据当前x坐标位置确定切换到第几屏 **/
	private void snapToDestination() {
		scrollToScreen((getScrollX() + (getWidth() / 2)) / getWidth());
	}

	/** 底部圆圈显示回调接口 **/
	interface ScrollToScreenCallback {
		public void callback(int currentIndex);
	}

	/** ScrollToScreenCallback回调对象 **/
	private ScrollToScreenCallback scrollToScreenCallback;

	/** 设置回调函数对象 **/
	public void setScrollToScreenCallback(ScrollToScreenCallback scrollToScreenCallback) {
		this.scrollToScreenCallback = scrollToScreenCallback;
	}
}

 

PageControlView

package org.wp.activity;

import org.wp.activity.ImageScrollView.ScrollToScreenCallback;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class PageControlView extends LinearLayout implements
		ScrollToScreenCallback {
	/** Context对象 **/
	private Context context;
	/** 圆圈的数量 **/
	private int count;

	public PageControlView(Context context, AttributeSet attrs) {
		super(context, attrs);
		this.context = context;
	}

	/** 回调函数 **/
	@Override
	public void callback(int currentIndex) {
		generatePageControl(currentIndex);
	}

	/** 设置选中圆圈 **/
	public void generatePageControl(int currentIndex) {
		this.removeAllViews();

		for (int i = 0; i < this.count; i++) {
			ImageView iv = new ImageView(context);
			if (currentIndex == i) {
				iv.setImageResource(R.drawable.page_indicator_focused);
			} else {
				iv.setImageResource(R.drawable.page_indicator);
			}
			this.addView(iv);
		}
	}

	/** 设置圆圈数量 **/
	public void setCount(int count) {
		this.count = count;
	}
}

 

main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent" 
	android:layout_height="fill_parent">
	<org.wp.activity.ImageScrollView android:layout_width="fill_parent"
		android:layout_height="fill_parent"
		android:id="@+id/myImageScrollView" />
	<org.wp.activity.PageControlView android:layout_width="fill_parent"
		android:layout_height="40dip"
		android:layout_alignParentBottom="true"
		android:background="#8f00000f"
		android:gravity="center"
		android:id="@+id/myPageControlView" />	
</RelativeLayout>

 

 

 

分享到:
评论
2 楼 M985300651 2012-12-05  
難得一見的好教學
1 楼 423884605 2012-03-01  
很精辟 找了好久 能给个demo吗97687283@qq.com

相关推荐

Global site tag (gtag.js) - Google Analytics