上一篇讲解了如何在自定义控件中进行性能优化,本篇来讲解如何给自定义控件添加监听器。
基本方法
说到监听器,相信OnClickListener是大家所熟知的,控件被点击后就会调用OnCLickListener的回调方法。按照这个原理我们也可以自己为自定义控件设计一种监听器。
首先我们要想好要监听什么,明确了这一点才能开始动工。拿我之前写的弹性指示器做例子。
现在要设计一个监听器,用来监听小圆点出发事件和尾巴到达终点的事件。可以在控件里写一个静态接口。
public static interface PointListener{
//小圆点出发
void onPointStart();
//尾巴到达终点
void onPointEnd();
}
然后提供一个set方法。
private mPointListener;
public void setPointListener(PointListener pointListener){
if(pointListener == null){
return;
}
mPointListener = pointListener;
}
在圆点出发时调用onPointStart方法,在尾巴到达终点时调用onPointEnd方法就行了。下面是伪代码。
void onHandleMessage(Message msg){
if(圆点出发){
if(mPointListener != null){
mPointListener.onPointStart();
}
}else if(尾巴到达终点){
if(mPointListener != null){
mPointListener.onPointEnd();
}
}
}
监听多个对象
使用过ViewPage的朋友应该知道,ViewPager的setOnPageChangeListener方法已经过时了,现在推荐使用addOnPageChangeListener方法。前者只能设置一个监听者,而后者可以添加多个监听者。我们也可以改进一下刚刚的代码。
private List<PointListener > mListenerList = new ArrayList<>();
public void addPointListener(PointListener pointListener){
if(pointListener == null){
return;
}
mListenerList.add(pointListener);
}
这里把原来的单个监听器换成了List,这样就可以存放多个监听者了。再来看看事件回调的处理。
void onHandleMessage(Message msg){
if(圆点出发){
for(int i = 0;i < mListenerList .size();i++){
mListenerList .get(i).onPointStart();
}
}else if(尾巴到达终点){
for(int i = 0;i < mListenerList .size();i++){
mListenerList .get(i).onPointEnd();
}
}
}
这样就可以响应多个监听者了。
WaveLoadingView的监听器
在WaveLoadingView里面有一个用来控制波运动方式的类。
public static interface WaveControler{
/**
* 波移动前会调用,可以用于控制波的移动方向和移动大小
* @param currentPostion 波当前的位置,这个位置是指波最高点的位置
* @param start 波可移动的左边界
* @param end 波可移动的右边界
* @return 波下一个移动位置,可以通过它决定波的移动方向和移动大小
* currentPostion大于返回值,波往左移动。currentPostion小于返回值,波往右移动
*/
int onRefresh(int currentPostion,int start,int end);
}
波每移动一次就会回调一次onRefresh方法(代码1),实现的原理和刚刚讲的例子是类似的。
protected void waveMove(){
if(mWaveControler != null){
//1
mWaveStart = mWaveControler.onRefresh(mWaveStart,0,mElements.length - 1);
}else{
mWaveStart++;
}
if(mWaveStart >= mElements.length || mWaveStart < 0){
mWaveStart = 0;
}
invalidate();
}
最后
监听器可以很好地拓展自定义控件的功能。对OnClickListener和OnTouchListener内部实现原理感兴趣的朋友可以看看我写的这篇文章。
限于文章篇幅,无法把WaveLoadingView完整的监听器代码贴出来,感兴趣的话也可以到Github项目里看看。