我想在一个TextView onTouchListeners分配给每个字。 (不链接到一些在互联网上,但只是为了继续该应用内的游戏逻辑)。我的游戏在这一点上的一般操作是看到一个TextView,触摸一个字,如果是你赢了目标词,否则加载基于你触摸的话,重复另一个TextView中。我做到这一点,现在的方式是用ClickableSpans和onClicks每个单词。
不过,我宁愿有onTouchListeners这样我就可以更改touch_down字的背景颜色,做游戏逻辑上touch_up,使它看起来更加敏感。我怎样才能做到这一点?
最后的TextView defTV =(TextView中)findViewById(R.id.defTV);
文=新SpannableString(RV); // RV是未来可点击TextView的文本
ClickableSpan clickableSpan = NULL;
字符串的regex =\\ W +;
模式P = Pattern.compile(正则表达式);
匹配匹配= p.matcher(文本);
而(matcher.find()){
最终诠释开始= matcher.start();
最终诠释结束= matcher.end();
clickableSpan =新ClickableSpan(){
公共无效的onClick(查看为arg0){
字符串LWORD =(字符串)text.subSequence(开始,结束)的ToString();
如果(lword.equalsIgnoreCase(targetword)){
// 赢得
} 其他 {
//构建基于LWORD新的TextView,重新来过
}
}
};
text.setSpan(clickableSpan,开始,结束,0);
}
解决方案
所以我复制ClickableSpan.java并提出TouchableSpan.java:
进口android.text.TextPaint;
进口android.text.style.CharacterStyle;
进口android.text.style.UpdateAppearance;
进口android.view.MotionEvent;
进口android.view.View;
/ **
*如果这种类型的一个对象被附接到一个TextView的文本
中*与LinkTouchMovementMethod的运动方法,受影响的跨度
*文字可以选择。如果触摸时,{@link #onTouch}方法
* 叫做。
* /
公共抽象类TouchableSpan扩展CharacterStyle实现UpdateAppearance {
/ **
*执行与这个跨度相关联的触摸动作。
* @返回
* /
公共抽象布尔onTouch(查看小部件,MotionEvent米);
/ **
*可以使下划线的文本或更改链接的颜色。
* /
@覆盖
公共抽象无效updateDrawState(TextPaint DS);
}
和我延长 LinkMovementMethod.java
到 LinkTouchMovementMethod.java
。所述的onTouchEvent方法是相同的,除了一提的onClick的相同改变为onTouch和一个新的行被添加
进口android.text.Layout;
进口android.text.Selection;
进口android.text.Spannable;
进口android.text.method.LinkMovementMethod;
进口android.view.MotionEvent;
进口android.widget.TextView;
公共类LinkTouchMovementMethod扩展LinkMovementMethod
{
@覆盖
公共布尔的onTouchEvent(TextView的小部件,Spannable缓冲,
MotionEvent事件){
INT行动= event.getAction();
如果(行动== MotionEvent.ACTION_UP ||
行动== MotionEvent.ACTION_DOWN){
INT X =(int)的event.getX();
INT Y =(INT)event.getY();
x - = widget.getTotalPaddingLeft();
Ÿ - = widget.getTotalPaddingTop();
X + = widget.getScrollX();
Y + = widget.getScrollY();
布局布局= widget.getLayout();
INT线= layout.getLineForVertical(Y);
诠释关闭= layout.getOffsetForHorizontal(线,X);
TouchableSpan []链接= buffer.getSpans(脱,脱,TouchableSpan.class);
如果(link.length!= 0){
如果(动作== MotionEvent.ACTION_UP){
链接[0] .onTouch(小部件,事件); ////////在此更改
}否则,如果(动作== MotionEvent.ACTION_DOWN){
链接[0] .onTouch(小部件,事件); ////////添加了此
Selection.setSelection(缓冲,
buffer.getSpanStart(联系[0]),
buffer.getSpanEnd(联系[0]));
}
返回true;
} 其他 {
Selection.removeSelection(缓冲液);
}
}
返回super.onTouchEvent(窗口小部件,缓冲,事件);
}
}
而在你的code设置MovementMethod正确:
TextView的电视=(TextView中)findViewById(R.id.tv);
tv.setMovementMethod(新LinkTouchMovementMethod());
现在显示的文字:
touchableSpan =新TouchableSpan(){
公共布尔onTouch(查看小部件,MotionEvent M){
...
}
公共无效updateDrawState(TextPaint DS){
ds.setUnderlineText(假);
ds.setAntiAlias(真正的);
}
};
字符串RV =文本跨越;
文=新SpannableString(RV);
text.setSpan(touchableSpan,开始,结束,0);
tv.setText(文字,BufferType.SPANNABLE);
I would like to assign onTouchListeners to each word in a TextView. (Not to link to something on the internet, but just to continue the game logic inside the app). The general action of my game at this point is to see a TextView, touch a word, if it's the target word you win, else load another TextView based on the word you touch and repeat. The way I accomplish this now is with ClickableSpans and onClicks for each word.
But I would rather have onTouchListeners so I can change the color of the background of the word on touch_down and do the game logic on touch_up, to make it look more responsive. How can I accomplish this?
final TextView defTV = (TextView) findViewById(R.id.defTV);
text = new SpannableString(rv); // rv is the future clickable TextView text
ClickableSpan clickableSpan = null;
String regex = "\\w+";
Pattern p = Pattern.compile(regex);
Matcher matcher = p.matcher(text);
while (matcher.find()) {
final int begin = matcher.start();
final int end = matcher.end();
clickableSpan = new ClickableSpan() {
public void onClick(View arg0) {
String lword = (String) text.subSequence(begin, end).toString();
if (lword.equalsIgnoreCase(targetword)) {
// WIN
} else {
// Build new TextView based on lword, start over
}
}
};
text.setSpan(clickableSpan, begin, end, 0);
}
解决方案
So I copied ClickableSpan.java and made TouchableSpan.java:
import android.text.TextPaint;
import android.text.style.CharacterStyle;
import android.text.style.UpdateAppearance;
import android.view.MotionEvent;
import android.view.View;
/**
* If an object of this type is attached to the text of a TextView
* with a movement method of LinkTouchMovementMethod, the affected spans of
* text can be selected. If touched, the {@link #onTouch} method will
* be called.
*/
public abstract class TouchableSpan extends CharacterStyle implements UpdateAppearance {
/**
* Performs the touch action associated with this span.
* @return
*/
public abstract boolean onTouch(View widget, MotionEvent m);
/**
* Could make the text underlined or change link color.
*/
@Override
public abstract void updateDrawState(TextPaint ds);
}
And I extended LinkMovementMethod.java
to LinkTouchMovementMethod.java
. The onTouchEvent method is the same the same except for a mention of onClick is changed to onTouch and a new line is added:
import android.text.Layout;
import android.text.Selection;
import android.text.Spannable;
import android.text.method.LinkMovementMethod;
import android.view.MotionEvent;
import android.widget.TextView;
public class LinkTouchMovementMethod extends LinkMovementMethod
{
@Override
public boolean onTouchEvent(TextView widget, Spannable buffer,
MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_UP ||
action == MotionEvent.ACTION_DOWN) {
int x = (int) event.getX();
int y = (int) event.getY();
x -= widget.getTotalPaddingLeft();
y -= widget.getTotalPaddingTop();
x += widget.getScrollX();
y += widget.getScrollY();
Layout layout = widget.getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
TouchableSpan[] link = buffer.getSpans(off, off, TouchableSpan.class);
if (link.length != 0) {
if (action == MotionEvent.ACTION_UP) {
link[0].onTouch(widget,event); //////// CHANGED HERE
} else if (action == MotionEvent.ACTION_DOWN) {
link[0].onTouch(widget,event); //////// ADDED THIS
Selection.setSelection(buffer,
buffer.getSpanStart(link[0]),
buffer.getSpanEnd(link[0]));
}
return true;
} else {
Selection.removeSelection(buffer);
}
}
return super.onTouchEvent(widget, buffer, event);
}
}
And set the MovementMethod appropriately in your code:
TextView tv = (TextView) findViewById(R.id.tv);
tv.setMovementMethod(new LinkTouchMovementMethod());
Now to show the text:
touchableSpan = new TouchableSpan() {
public boolean onTouch(View widget, MotionEvent m) {
...
}
public void updateDrawState(TextPaint ds) {
ds.setUnderlineText(false);
ds.setAntiAlias(true);
}
};
String rv = "Text to span";
text = new SpannableString(rv);
text.setSpan(touchableSpan, begin, end, 0);
tv.setText(text, BufferType.SPANNABLE);