1. 实现效果
滚动翻页 + 页面点击 + 页码指示器 + 焦点控制
2. 实现这个效果之前必须要了解
基于 Android 高级图片滚动控件实现 3D 版图片轮播器的代码进行修改,主要为了移植到电视上做了按键事件和焦点控制。
3. 具体代码
Image3DSwitchView
public class Image3DSwitchView extends LinearLayout {
private int currentPage = 0; // 定义当前第几页
/**
* 图片左右两边的空白间距
*/
public static final int IMAGE_PADDING = 5;
private static final int TOUCH_STATE_REST = 0;
private static final int TOUCH_STATE_SCROLLING = 1;
/**
* 滚动到下一张图片的速度
*/
private static final int SNAP_VELOCITY = 600;
/**
* 表示滚动到下一张图片这个动作
*/
private static final int ;
;
;
();
mWidth;
VelocityTracker mVelocityTracker;
Scroller mScroller;
OnImageSwitchListener mListener;
TOUCH_STATE_REST;
mTouchSlop;
mHeight;
mImageWidth;
mCount;
mCurrentImage;
mLastMotionX;
forceToRelayout;
[] mItems;
{
(context, attrs);
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
mScroller = (context);
setFocusable();
}
{
(changed || forceToRelayout) {
mCount = getChildCount();
(mCount < ) {
;
}
mWidth = getMeasuredWidth();
mHeight = getMeasuredHeight();
mImageWidth = () (mWidth * );
(mCurrentImage >= && mCurrentImage < mCount) {
mScroller.abortAnimation();
setScrollX();
-mImageWidth * + (mWidth - mImageWidth) / ;
[] items = {getIndexForItem(), getIndexForItem(),
getIndexForItem(), getIndexForItem(),
getIndexForItem()};
mItems = items;
( ; i < items.length; i++) {
(Image3DView) getChildAt(items[i]);
childView.layout(left + IMAGE_PADDING, , left
+ mImageWidth - IMAGE_PADDING, mHeight);
childView.initImageViewBitmap();
left = left + mImageWidth;
}
refreshImageShowing();
}
forceToRelayout = ;
}
}
{
;
;
}
OnFocusListener onFocusListener;
{
.onFocusListener = onFocusListener;
}
{
(event.getAction() == KeyEvent.ACTION_DOWN) {
(event.getKeyCode()) {
KeyEvent.KEYCODE_DPAD_DOWN:
(onFocusListener != ) {
onFocusListener.onFocus();
}
;
KeyEvent.KEYCODE_DPAD_CENTER:
Toast.makeText(getContext(), + (currentPage % + ), Toast.LENGTH_SHORT).show();
;
KeyEvent.KEYCODE_DPAD_RIGHT:
scrollToNext();
(onFocusListener != ) {
onFocusListener.setValue((currentPage % + ) + );
}
;
KeyEvent.KEYCODE_DPAD_LEFT:
scrollToPrevious();
(onFocusListener != ) {
onFocusListener.setValue((currentPage % + ) + );
}
;
}
}
;
}
{
(mScroller.isFinished()) {
(mVelocityTracker == ) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(event);
event.getAction();
event.getX();
(action) {
MotionEvent.ACTION_DOWN:
mLastMotionX = x;
;
MotionEvent.ACTION_MOVE:
() (mLastMotionX - x);
mLastMotionX = x;
scrollBy(disX, );
refreshImageShowing();
;
MotionEvent.ACTION_UP:
mVelocityTracker.computeCurrentVelocity();
() mVelocityTracker.getXVelocity();
(shouldScrollToNext(velocityX)) {
scrollToNext();
} (shouldScrollToPrevious(velocityX)) {
scrollToPrevious();
} {
scrollBack();
}
(mVelocityTracker != ) {
mVelocityTracker.recycle();
mVelocityTracker = ;
}
;
}
}
;
}
{
ev.getAction();
((action == MotionEvent.ACTION_MOVE)
&& (mTouchState != TOUCH_STATE_REST)) {
;
}
ev.getX();
(action) {
MotionEvent.ACTION_DOWN:
mLastMotionX = x;
mTouchState = TOUCH_STATE_REST;
;
MotionEvent.ACTION_MOVE:
() Math.abs(mLastMotionX - x);
(xDiff > mTouchSlop) {
mTouchState = TOUCH_STATE_SCROLLING;
}
;
MotionEvent.ACTION_UP:
:
mTouchState = TOUCH_STATE_REST;
;
}
mTouchState != TOUCH_STATE_REST;
}
{
(mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
refreshImageShowing();
postInvalidate();
}
}
{
mListener = listener;
}
{
mCurrentImage = currentImage;
requestLayout();
}
{
(mScroller.isFinished()) {
currentPage++;
mImageWidth - getScrollX();
checkImageSwitchBorder(SCROLL_NEXT);
(mListener != ) {
mListener.onImageSwitch(mCurrentImage);
}
beginScroll(getScrollX(), , disX, , SCROLL_NEXT);
}
}
{
(mScroller.isFinished()) {
(currentPage == ) {
currentPage = ;
}
currentPage--;
-mImageWidth - getScrollX();
checkImageSwitchBorder(SCROLL_PREVIOUS);
(mListener != ) {
mListener.onImageSwitch(mCurrentImage);
}
beginScroll(getScrollX(), , disX, , SCROLL_PREVIOUS);
}
}
{
(mScroller.isFinished()) {
beginScroll(getScrollX(), , -getScrollX(), , SCROLL_BACK);
}
}
{
( ; i < mCount; i++) {
(Image3DView) getChildAt(i);
childView.recycleBitmap();
}
}
{
() ( / mImageWidth * Math.abs(dx));
mScroller.startScroll(startX, startY, dx, dy, duration);
invalidate();
handler.postDelayed( () {
{
(action == SCROLL_NEXT || action == SCROLL_PREVIOUS) {
forceToRelayout = ;
requestLayout();
}
}
}, duration);
}
{
-;
index = mCurrentImage + item - ;
(index < ) {
index = index + mCount;
}
(index > mCount - ) {
index = index - mCount;
}
index;
}
{
( ; i < mItems.length; i++) {
(Image3DView) getChildAt(mItems[i]);
childView.setRotateData(i, getScrollX());
childView.invalidate();
}
}
{
(action == SCROLL_NEXT && ++mCurrentImage >= mCount) {
mCurrentImage = ;
} (action == SCROLL_PREVIOUS && --mCurrentImage < ) {
mCurrentImage = mCount - ;
}
}
{
velocityX < -SNAP_VELOCITY || getScrollX() > mImageWidth / ;
}
{
velocityX > SNAP_VELOCITY || getScrollX() < -mImageWidth / ;
}
{
;
}
}


