android-jamendo源码学习——Gesture(手势)
精彩继续~~~jamendo中提供了用gesture(手势)来控制音乐的播放、暂停、停止和向前向后切换歌曲,下面就分析jamendo中gesture控制的实现过程。在这之前可能需要对android提供的gesture有一定的了解,以便可以能更好理解,如果你没有接触过gesture可以先看一下这篇文章:【转】android 手势 API的使用 ;
要想使gesture 我们就要加载一个GestureOverlayView到XML Layout,然后在Activity中为其加上监听事件addOnGesturePerformedListener (GestureOverlayView.OnGesturePerformedListener listener),在这里我们以在HomeActivity中的为例,先看其中的监听事件:
mGestureOverlayView.addOnGesturePerformedListener(JamendoApplication.getInstance().getPlayerGestureHandler());
这里可以看到JamendoApplication.getInstance().getPlayerGestureHandler()就是这个listener,也就是我们要了解的对象。然后我们在JamendoApplication类中找到它。
public GesturesHandler getPlayerGestureHandler(){ if(mPlayerGestureHandler == null){ mPlayerGestureHandler = new GesturesHandler(this, new PlayerGestureCommandRegiser(getPlayerEngineInterface())); } return mPlayerGestureHandler; }
从这方法中可以看出我们要了解的对象有变成了GesturesHandler(this, new PlayerGestureCommandRegiser(getPlayerEngineInterface()));绕来绕去总算是找到根了。。。。
这里就是处理处理手势gesture的地方,在分析这个类之前还要先知道GesturesHandler(this, new PlayerGestureCommandRegiser(getPlayerEngineInterface()))传入的参数 new PlayerGestureCommandRegiser(getPlayerEngineInterface())是什么,下面来看 PlayerGestureCommandRegiser(getPlayerEngineInterface())这个类:
1 public class PlayerGestureCommandRegiser extends GestureCommandRegister { 2 3 public PlayerGestureCommandRegiser(PlayerEngine playerEngine) { 4 super(); 5 6 registerCommand("next", new PlayerGestureNextCommand(playerEngine)); 7 registerCommand("prev", new PlayerGesturePrevCommand(playerEngine)); 8 registerCommand("play", new PlayerGesturePlayCommand(playerEngine)); 9 registerCommand("stop", new PlayerGestureStopCommand(playerEngine)); 10 } 11 12 }
从名字可以大概知道这个类是gesture命令的注册类,类很简单只有四条重复性的代码,分别注册了四种gesture命令。这个类继承了GestureCommandRegister,其中的registerCommand也是来自父类,所以我们还要先了解GestureCommandRegister:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** 2 * Simple register for gesture commands. 3 * 4 * @author Bartosz Cichosz 5 * 6 */ 7 public class GestureCommandRegister { 8 9 private HashMap<String, GestureCommand> mGestures; 10 11 public GestureCommandRegister() { 12 mGestures = new HashMap<String, GestureCommand>(); 13 } 14 15 public void registerCommand(String name, GestureCommand gestureCommand) { 16 mGestures.put(name, gestureCommand); 17 } 18 19 public GestureCommand getCommand(String name) { 20 return mGestures.get(name); 21 } 22 23 }
这个类也很简单就提供了registerCommand方法将gesture注册命令以传递进来的name作为key、gestureCommand作为value存储到HashMap<String, GestureCommand> mGestures中。
这样我们就很清楚的知道了PlayerGestureCommandRegiser类就是将播放上一首、播放下一首、播放、暂停四条gestureCommand存储到HashMap<String, GestureCommand> mGestures中。这里的四条gestureCommand结构都一样,在这里就哪play为例看一下new PlayerGesturePlayCommand(playerEngine):
1 public class PlayerGesturePlayCommand implements GestureCommand { 2 3 PlayerEngine mPlayerEngine; 4 5 public PlayerGesturePlayCommand(PlayerEngine engine) { 6 mPlayerEngine = engine; 7 } 8 9 @Override 10 public void execute() { 11 Log.v(JamendoApplication.TAG, "PlayerGesturePlayCommand"); 12 if (mPlayerEngine.isPlaying()) { 13 mPlayerEngine.pause(); 14 } else { 15 mPlayerEngine.play(); 16 } 17 } 18 19 }
这里的PlayerEngine我们先不讨论,只要先知道它是用来控制播放器的就行。可以看到这个类就只是实现了接口类GestureCommand中的execute()方法,在execute方法中控制播放器的播放和暂停。
到这我们知道了PlayerGestureCommandRegiser(getPlayerEngineInterface())的内容就可以开始分析GesturesHandler(this, new PlayerGestureCommandRegiser(getPlayerEngineInterface()))了。
我们先看一下这个类:
1 /** 2 * Handler for gestures. When gesture is performed, it is checked if thr 3 * register contains apropriate command to execute. 4 * 5 * @author Bartosz Cichosz 6 * 7 */ 8 public class GesturesHandler implements OnGesturePerformedListener { 9 10 private GestureLibrary mLibrary; 11 private boolean mLoaded = false; 12 13 private GestureCommandRegister mRegister; 14 15 public GesturesHandler(Context context, GestureCommandRegister register) { 16 // mLibrary = GestureLibraries.fromRawResource(context, R.raw.gestures); 17 mLibrary = GestureLibraries.fromRawResource(context, R.raw.gestures); 18 load(); 19 setRegister(register); 20 } 21 22 private boolean load() { 23 mLoaded = mLibrary.load(); 24 return mLoaded; 25 } 26 27 @Override 28 public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { 29 if (!mLoaded) { 30 if (!load()) { 31 return; 32 } 33 } 34 35 ArrayList<Prediction> predictions = mLibrary.recognize(gesture); 36 if (predictions.size() > 0) { 37 Prediction prediction = predictions.get(0); 38 Log.v(JamendoApplication.TAG, "Gesture " + prediction.name 39 + " recognized with score " + prediction.score); 40 if (prediction.score > 2.0) { 41 GestureCommand command = getRegister().getCommand( 42 prediction.name); 43 if (command != null) { 44 command.execute(); 45 } 46 } 47 } 48 } 49 50 public void setRegister(GestureCommandRegister mRegister) { 51 this.mRegister = mRegister; 52 } 53 54 public GestureCommandRegister getRegister() { 55 return mRegister; 56 } 57 58 }
首先是构造方法public GesturesHandler(Context context, GestureCommandRegister register)这里面主要是加载预先定义好的手势库和我们上面的到手势执行命令restureCommand。因为是监听器多以必须实现鉴定器接口的方法onGesturePerformed(GestureOverlayView overlay, Gesture gesture)就像我们平时用的Button要实现OnClickListener中的onclick方法一样。
在onGesturePerformed(GestureOverlayView overlay, Gesture gesture) 方法中首先是判断是否加载了手势库,如果没有加载就return。加载手势库后通过手势库mLibrary.recognise(gesture)方法来进行gesture的识别,该方法会得到一组识别结果ArrayList<Prediction> predictions,每个Prediction实例一个gesture的name和识别的匹配分值score。识别结果数组按照分值大小从高到低排序。越高的分值,说明手势越接近用户所画的手势。紧接着取得识别结果中分值最高的也就是Predictions.get(0),当识别分值大于2.0时,第一个识别结果生效。采用什么样的阈值完全由自己决定,但是分值低于1.0的结果一般来说都是匹配不好的。如果得分超过设置阈值则从我们传进的装载着gestureCommand的hashmap中取得名字为该手势的gestureCommand。判断gestureCommand是否存在,若存在则调用execute执行该手势对应的操作。
到此jamedon中Gesture的内容就介绍完了,下面给出jamendo中gestures包中包含类,在上面基本都介绍到了。
休息~休息一下~~