自定义设置监听器方法:

1.OnViewChangeListener 类

public interface OnViewChangeListener {
	public void OnViewChange(int view);
}

2.NavigitionActivity 类
package com.zqs.navigation.activity;

import com.zqs.navigation.listener.OnViewChangeListener;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class NavigitionActivity extends Activity implements OnViewChangeListener {
	private NavigationLayout navigationLayout ;
	private Button start_btn;
	private PassBroadCast passBroadCast;
	private int count;
	private ImageView[] imgs;
	private LinearLayout pointLLayout;
	private int currentItem;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		
		super.onCreate(savedInstanceState);
		setContentView(R.layout.navigation);
		initBroadCastReceiver();
		initView();
		
		
	}
	
	private void initView() {
		navigationLayout = (NavigationLayout) findViewById(R.id.navigationLayout);
		pointLLayout = (LinearLayout) findViewById(R.id.llayout);
		start_btn = (Button) findViewById(R.id.start_btn);
		start_btn.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Intent intent = new Intent();
				intent.setClass(NavigitionActivity.this, MainActivity.class);
				NavigitionActivity.this.startActivity(intent);
				NavigitionActivity.this.finish();
			}
		});
		
		count = navigationLayout.getChildCount();
		imgs = new ImageView[count];
		for (int i = 0; i < count; i++) {
			imgs[i] = (ImageView) pointLLayout.getChildAt(i);
			imgs[i].setEnabled(true);
			imgs[i].setTag(i);
		}
		currentItem = 0;
		imgs[currentItem].setEnabled(false);
		
		//方法二 注册监听器
		navigationLayout.SetOnViewChangeListener(this);
	}

	private void initBroadCastReceiver() {
		//注册该广播
				IntentFilter intentFilter = new IntentFilter();
				intentFilter.addAction("passByValue");
				passBroadCast = new PassBroadCast();
				registerReceiver(passBroadCast, intentFilter);
		
	}
	
	private class PassBroadCast extends BroadcastReceiver{

		@Override
		public void onReceive(Context context, Intent intent) {
			int cunrrentPage = intent.getIntExtra("CurScreen",0);
			setcurrentPoint(cunrrentPage);
		}
		
	}
	
	private void setcurrentPoint(int position) {
		if (position < 0 || position > count - 1 || currentItem == position) {
			return;
		}
		imgs[currentItem].setEnabled(true);
		imgs[position].setEnabled(false);
		currentItem = position;
	}

	@Override
	public void OnViewChange(int position) {
		setcurrentPoint(position);
		
	}
}
3.NavigationLayout 类

package com.zqs.navigation.activity;

import com.zqs.navigation.listener.OnViewChangeListener;

import android.content.Context;
import android.content.Intent;
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;

public class NavigationLayout extends ViewGroup{

    private static final String TAG = "ScrollLayout";   
    
    private VelocityTracker mVelocityTracker;  			
    
    private static final int SNAP_VELOCITY = 1500;    
    
    private Scroller  mScroller;					
	
    private int mCurScreen;    						
    
	private int mDefaultScreen = 0;    					
	 
    private float mLastMotionX;  
    
    private Context context;
    
    
    private OnViewChangeListener mOnViewChangeListener;
	 
	public NavigationLayout(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		init(context);
	}
	
	public NavigationLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		init(context);
	}
	
	public NavigationLayout(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
		
		init(context);
	}
	
	private void init(Context context)
	{
		mCurScreen = mDefaultScreen;    
	  
		this.context = context;  
	        
	    mScroller = new Scroller(context); 
	    
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		// TODO Auto-generated method stub
		
		
		 if (changed) {    
	            int childLeft = 0;    
	            final int childCount = getChildCount();    
	                
	            for (int i=0; i<childCount; i++) {    
	                final View childView = getChildAt(i);    
	                if (childView.getVisibility() != View.GONE) {    
	                    final int childWidth = childView.getMeasuredWidth();    
	                    childView.layout(childLeft, 0,     
	                            childLeft+childWidth, childView.getMeasuredHeight());    
	                    childLeft += childWidth;    
	                }    
	            }    
	        }    
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		// TODO Auto-generated method stub
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		
	
		
		final int width = MeasureSpec.getSize(widthMeasureSpec);       
	    @SuppressWarnings("unused")
		final int widthMode = MeasureSpec.getMode(widthMeasureSpec);      
	    
		
		final int count = getChildCount();       
        for (int i = 0; i < count; i++) {       
            getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);       
        }         
        
        scrollTo(mCurScreen * width, 0);
		
	}

	//我们是缓慢移动的,因此需要根据偏移值判断目标屏是哪个? 
	 public void snapToDestination() {    
	        final int screenWidth = getWidth();    
	      //判断是否超过下一屏的中间位置,如果达到就抵达下一屏,否则保持在原屏幕      
	        //直接使用这个公式判断是哪一个屏幕 前后或者自己  
	        //判断是否超过下一屏的中间位置,如果达到就抵达下一屏,否则保持在原屏幕  
	        // 这样的一个简单公式意思是:假设当前滑屏偏移值即 scrollCurX 加上每个屏幕一半的宽度,除以每个屏幕的宽度就是  
	        //  我们目标屏所在位置了。 假如每个屏幕宽度为320dip, 我们滑到了500dip处,很显然我们应该到达第二屏 
	        final int destScreen = (getScrollX()+ screenWidth/2)/screenWidth;    
	        snapToScreen(destScreen);    
	 }  
	
	 public void snapToScreen(int whichScreen) {    
		 	//简单的移到目标屏幕,可能是当前屏或者下一屏幕  
	        //直接跳转过去,不太友好  
	        //scrollTo(mLastScreen * MultiScreenActivity.screenWidth, 0);  
	        //为了友好性,我们在增加一个动画效果  
	        //需要再次滑动的距离 屏或者下一屏幕的继续滑动距离
	        // //防止屏幕越界,即超过屏幕数  
	        whichScreen = Math.max(0, Math.min(whichScreen, getChildCount()-1));    
	        if (getScrollX() != (whichScreen*getWidth())) {    
	        	//为了达到下一屏幕或者当前屏幕,我们需要继续滑动的距离.根据dx值,可能想左滑动,也可能像又滑动
	            final int delta = whichScreen*getWidth()-getScrollX();    
	        
	            mScroller.startScroll(getScrollX(), 0,     
	                    delta, 0, Math.abs(delta)*2);
 
	            
	            mCurScreen = whichScreen;    
	            invalidate();       //由于触摸事件不会重新绘制View,所以此时需要手动刷新View 否则没效果    
	            //方法一:创建广播监听 传当前启动页 给NavigationActivity改变指引图标
//	            Intent intent = new Intent();
//	            intent.setAction("passByValue");
//	            intent.putExtra("CurScreen", mCurScreen);
//	            context.sendBroadcast(intent);
	            //方法二:创建监听类监听改变, NavigationActivity实现监听器具体功能
	            if (mOnViewChangeListener != null)
	            {
	            	mOnViewChangeListener.OnViewChange(mCurScreen);
	            }
	        }    
	    }    

	 //调用ondraw() 调用此方法
	@Override
	public void computeScroll() {
		// TODO Auto-generated method stub
		if (mScroller.computeScrollOffset()) {    
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());  
            postInvalidate();    
        }   
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub           
	            
	        final int action = event.getAction();    
	        final float x = event.getX();    
	        @SuppressWarnings("unused")
			final float y = event.getY();    
	            
	        switch (action) {    
	        case MotionEvent.ACTION_DOWN: 
	        	if (mVelocityTracker == null) {    
			            mVelocityTracker = VelocityTracker.obtain();    
			            mVelocityTracker.addMovement(event); 
			    }
	        	 
	            if (!mScroller.isFinished()){    
	                mScroller.abortAnimation();    
	            }    
	            
	            mLastMotionX = x;	           
	            break;    
	                
	        case MotionEvent.ACTION_MOVE:  
	           int deltaX = (int)(mLastMotionX - x);
	           
        	   if (IsCanMove(deltaX))
        	   {
        		 if (mVelocityTracker != null)
  		         {
  		            	mVelocityTracker.addMovement(event); 
  		         }   

  	            mLastMotionX = x;    
 
  	            scrollBy(deltaX, 0);	
        	   }
         
	           break;    
	                
	        case MotionEvent.ACTION_UP:       
	        	
	        	int velocityX = 0;
	            if (mVelocityTracker != null)
	            {
	            	mVelocityTracker.addMovement(event); 
	            	mVelocityTracker.computeCurrentVelocity(1000);  
	            	//计算速率  
					velocityX = (int) mVelocityTracker.getXVelocity();
				}

				//滑动速率达到了一个标准(快速向右滑屏,返回上一个屏幕) 马上进行切屏处理 
				if (velocityX > SNAP_VELOCITY && mCurScreen > 0) {       
					// Fling enough to move left       
					Log.e(TAG, "snap left");    
					snapToScreen(mCurScreen - 1);       
				}
				//快速向左滑屏,返回下一个屏幕)  
				else if (velocityX < -SNAP_VELOCITY       
						&& mCurScreen < getChildCount() - 1) {       
					// Fling enough to move right       
					Log.e(TAG, "snap right");    
					snapToScreen(mCurScreen + 1);       
				} 
				//以上为快速移动的 ,强制切换屏幕
				else {  
					//我们是缓慢移动的,因此先判断是保留在本屏幕还是到下一屏幕
					snapToDestination();       
				}     
	            
	           
				//回收VelocityTracker对象 
	            if (mVelocityTracker != null) {       
	                mVelocityTracker.recycle();       
	                mVelocityTracker = null;       
	            }       
	            
	      //      mTouchState = TOUCH_STATE_REST;
	            break;      
	        }    
	            
	        return true;    
	}
	
	private boolean IsCanMove(int deltaX)
	{
		//简而言之,getScrollX() 就是当前view的左上角相对于母视图的左上角的X轴偏移量。(nice!)
		if (getScrollX() <= 0 && deltaX < 0 )
		{
			return false;
		}
		//getWidth Return the width of the your view.
		if  (getScrollX() >=  (getChildCount() - 1) * getWidth() && deltaX > 0)
		{
			return false;
		}
			
		
		return true;
	}
	
	public void SetOnViewChangeListener(OnViewChangeListener listener)
	{
		mOnViewChangeListener = listener;
	}

}

总结:

 自定义设置监听器方法:
(1)对清对象,被监听对象,监听器,实现监听器对象
监听器:public interface OnViewChangeListener {}
实现监听器对象:public class NavigitionActivity extends Activity implements OnViewChangeListener {}
被监听对象:public class NavigationLayout extends ViewGroup{}

(2) 实现监听器对象 NavigitionActivity :实现方法:
@Override
public void OnViewChange(int position) {
setcurrentPoint(position);

}
(3) 被监听对象 NavigationLayout : 设置监听器
public void SetOnViewChangeListener(OnViewChangeListener listener)
{
mOnViewChangeListener = listener;
}

(4) 关联监听器 与被监听对象
//方法二 注册监听器
navigationLayout.SetOnViewChangeListener(this);

(5)被监听对象 改变之后 调用监听器
if (mOnViewChangeListener != null)
            {
             mOnViewChangeListener.OnViewChange(mCurScreen);
            } 
Demo 地址: http://download.csdn.net/detail/zqs62761130/8228427

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值