/* * Copyright (C) 2012 www.amsoft.cn * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.ab.view.sliding; /* * Copyright (C) 2012 www.amsoft.cn * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import android.content.Context; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; import android.view.ViewGroup; import android.widget.Scroller; // TODO: Auto-generated Javadoc /** * © 2012 amsoft.cn * 名称:AbSlidingPageView.java * 描述:页面滚动切换,实现焦点触发和Touch,适用于电视开发. * * @author 还如一梦中 * @version v1.0 * @date:2013-05-17 下午6:46:29 */ public class AbSlidingPageView extends ViewGroup { /** 记录日志的标记. */ private String TAG = AbSlidingPageView.class.getSimpleName(); /** 记录日志的开关. */ private boolean D = true; /** 滚动器. */ private Scroller mScroller; /** 速度. */ private VelocityTracker mVelocityTracker; /** 显示的下一个View. */ public static final int SCREEN_STATE_NEXT = 0; /** 显示的前一个View. */ public static final int SCREEN_STATE_PROVIOUS = 1; /** 当前屏幕状态. */ private int mScreenState = SCREEN_STATE_PROVIOUS; /** 下一个View的偏移. */ private int nextViewOffset = 50; /** 页面切换监听器. */ private OnPageChangeListener onPageChangeListener = null; /** 目标滚动是否完成. */ private boolean finish = true; /** * 构造. * @param context the context */ public AbSlidingPageView(Context context) { super(context); mScroller = new Scroller(context); } /** * 构造. * @param context the context * @param attrs the attrs */ public AbSlidingPageView(Context context, AttributeSet attrs) { super(context, attrs); } /** * 描述:View的位置设定. * * @param changed the changed * @param l the l * @param t the t * @param r the r * @param b the b */ @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { //初始布局 for (int i = 0; i < getChildCount(); i++) { View child = getChildAt(i); int height = child.getMeasuredHeight(); int width = child.getMeasuredWidth(); child.setFocusable(true); if(D) Log.d(TAG, "--onLayout--:"+width); if(i==0){ child.layout(-nextViewOffset,0 ,nextViewOffset+width , height); }else{ child.layout(width-nextViewOffset,0,2*width-nextViewOffset, height); } } } /** * 描述:测量View的宽高. * @param widthMeasureSpec the width measure spec * @param heightMeasureSpec the height measure spec * @see android.view.View#onMeasure(int, int) */ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if(D) Log.d(TAG, "--onMeasure--"); int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); setMeasuredDimension(width, height); for (int i = 0; i < getChildCount(); i++) { getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec); } } /** * 打开下一个View. */ public void showNext() { if(!finish || mScreenState==SCREEN_STATE_NEXT){ return; } finish = false; mScreenState = SCREEN_STATE_NEXT; if(onPageChangeListener!=null){ onPageChangeListener.onPageSelected(1); } if(D) Log.d(TAG, "--showNext--:"+getScrollX()+" dx "+(getChildAt(1).getWidth()-2*nextViewOffset)); //始终要以onlayout的位置作为最初始位置计算 mScroller.startScroll(getScrollX(), 0, getChildAt(1).getWidth()-2*nextViewOffset, 0, 800); invalidate(); } /** * 返回上一个View. */ public void showPrevious() { if(!finish || mScreenState==SCREEN_STATE_PROVIOUS){ return; } mScreenState = SCREEN_STATE_PROVIOUS; if(onPageChangeListener!=null){ onPageChangeListener.onPageSelected(0); } if(D) Log.d(TAG, "--showPrevious--:"+getScrollX()+" dx -"+getScrollX()); //滚动回onlayout的0的位置 mScroller.startScroll(getScrollX(), 0, -getScrollX(), 0, 800); invalidate(); } /** * 描述:滚动. * @see android.view.View#computeScroll() */ public void computeScroll() { super.computeScroll(); if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); postInvalidate(); } //这次滚动结束 if(mScroller.getFinalX()==mScroller.getCurrX()){ finish = true; } } /** * 初始化速度检测. * @param event the event */ private void obtainVelocityTracker(MotionEvent event) { if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(event); } /** * 释放速度检测. */ private void releaseVelocityTracker() { if (mVelocityTracker != null) { mVelocityTracker.recycle(); mVelocityTracker = null; } } /** * 获取当前状态. * @return the screen state */ public int getScreenState() { return mScreenState; } /** * 设置主View. * * @param view the view */ public void addContentView(View view) { addView(view,0, getLayoutParams()); view.setOnFocusChangeListener(new OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if(hasFocus){ showPrevious(); } } }); view.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if(MotionEvent.ACTION_DOWN == event.getAction()){ showPrevious(); } return false; } }); } /** * 设置下一个View. * * @param view the view */ public void addNextView(View view) { addView(view,1, getLayoutParams()); view.setOnFocusChangeListener(new OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if(hasFocus){ showNext(); } } }); view.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if(MotionEvent.ACTION_DOWN == event.getAction()){ showNext(); } return false; } }); } /** * Gets the next view offset. * * @return the next view offset */ public int getNextViewOffset() { return nextViewOffset; } /** * 设置遮挡距离. * * @param nextViewOffset the new next view offset */ public void setNextViewOffset(int nextViewOffset) { this.nextViewOffset = nextViewOffset; } /** * Gets the on page change listener. * * @return the on page change listener */ public OnPageChangeListener getOnPageChangeListener() { return onPageChangeListener; } /** * 设置页面改变监听器. * * @param onPageChangeListener the new on page change listener */ public void setOnPageChangeListener(OnPageChangeListener onPageChangeListener) { this.onPageChangeListener = onPageChangeListener; } }