[Android]在游戏的SurfaceView中获取输入与施用EditText,Spinner等控件的方法
游戏中有时候需要玩家输入信息,选择信息。在普通的Android程序里面,可以使用EditText,Spinner等输入控件方便地实现这些功能。但是,一般游戏是使用SurfaceView,所有的东西都是自己绘制。所以加入控件有些不伦不类。而且SurfaceView属于View,本身是不能追加的控件的。我在网络上找了许多文件,一般来说提到了一个方法在外面使用布局。但说到底还是不伦不类。而且使游戏的UI变得复杂。我想,做为一个游戏开发者,想要的应该是一个获取输入的机制。
我在网上找了许多资料,没有一个资料实际上解决了这个问题。有些文件介绍到了使用BaseConnectionInput加InputMethodManager来使SurfaceView获得输入,这个方法被到处转,但实际上不起作用。到最后,我在一个老外的网站上找到了答案,要使用以上的方法来使控件获取输入,这个控件至少是继承自TextView这种“具有接受输入能力”的控件。但既然继承了SurfaceView,那这就不一个选择了。
到最后没办法,我想了一个旁门左道来解决这个问题。我称为“代理机制”。这实际上不是通过SurfaceView获得输入,但是能够工作得很好。
首先,关于使用EditText的问题。游戏中需要获取玩家的输入,这是最关键的。其它的控件都可以使用点击事件来处理,只有这个最麻烦,需要键盘。要实现这个,需要几步。
1、建立一个自己的EditText。
这个很简单,人人都会做。继承EditText,复写draw方法,复写draw方法直接就使他变成空函数,什么都不做。增加一个自己的TextWatcher类用于处理文本改变后的逻辑。
2、将自己的EditText添加到ContentView中。
一般使用SurfaceView是通过如下的方法:
SurfaceView gameSurface = new SurfaceView(this);
setContentView(gameSurface );
在后面加上:
EditText myEdit = new MyEditText(this);
addContentView(myEdit);
使myEdit成为主Activity的一个ContentView。但是,你在主界面看不到它。因为它的draw方法被你重写成不绘制任何东西了。他除了看不见之外,其它功能都是完好的。
有人会问,用setVisibility(View.GONE)把它配置成看不见行吗?不行,不知道为什么,这样它的功能就失效了。也许是因为它无法获得焦点或是其它什么原因。
3、使用输入代理。
在你需要输入的时候,使你的EditText获得焦点,然后使用InputMethodManager打开软键盘。这样就大功造成了。其它的业务处理逻辑都在TextWatcher中处理就行了。关于InputMethodManager的使用可以在网上查找,我就不详细介绍了。
public void openEditAgent(){
myEdit.requestFocus();
InputMethodManager input = (InputMethodManager) context.getSystemService( Context.INPUT_METHOD_SERVICE);
input.toggleSoftInput(0, InputMethodManager.SHOW_FORCED);
}
关于Spinner的使用也是如于同样的原理。1、继承,然后复写draw方法,使它看不见。2、使用addContentView加入到主Activity。3、调用。Spinner的调用比EditText简单,只需要模拟点击就行了。
public void openSpinnerAgent(){
mySpinner.requestFocus();
mySpinner.performClick();
}
这样,你就可以使用Spinner控件来完成游戏中要求的输入。当然,你也可以如法炮制其它控件的使用。
这是使用Spinner来获取输入时的样子。EditText不截图和平时使用一样把整个屏幕占了。