你的位置:首页 > 操作系统

[操作系统]点击文本改变改行背景色,弹出对话框


 我想单纯靠一个文本实现微信回复评论的效果,在一列回复文本中点击某一行,然后该行的背景色改变并且弹出对话框,如下图,我们想要回复A,那么就点击A所在的那一行(A回复B:哈哈哈)。

注意,这里两行包括下面一系列的回复文本都是在一个textView中。

网上查了许久,结合自己的一些知识,终于实现了。

 

揭晓答案(步骤如下):

/** * 

  对于第二行来说

   commentName为A

   replyName为B,

   commentContent为内容

* **/

1.

SpannableString commentReplyNameContent = null;

commentReplyNameContent = new SpannableString(commentName + "回复" + replyName + ":" + commentContent);

commentReplyNameContent.setSpan(new ClickableSpan()  //设置点击时候的效果(在这里只是弹出键盘而已) {        @Override      
public void updateDrawState(TextPaint ds)
{
super.updateDrawState(ds);
ds.setUnderlineText(false); //取消下划线
} @Override
public void onClick(View widget)
{
showKeyBoard(comment.getComentName()); //弹出键盘
 //或者进行其他操作,comment.getComentName()为要回复的人的名字,即点击这二行的话,comment.getComentName()就为A
}
}, 0, commentName.length() + replyName.length() + commentContent.length() + 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);commentReplyNameContent.setSpan //设置A的颜色(new ForegroundColorSpan(Color.BLUE), 0, commentName.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);commentReplyNameContent.setSpan //设置整一行的背景为黑色(new ForegroundColorSpan(Color.BLACK), commentName.length(), commentName.length() + replyName.length() + commentContent.length() + 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);/** * replyContent为此textView * **/replyContent.append("\n"); //换行
replyContent.append(commentReplyNameContent);// 把这一行追加在textView后面replyContent.setMovementMethod(new MyLinkMovementMethod());//这句话是为了响应点击效果。

 

 2.点击改变那一行的背景色,重写LinkMovementMethod

private class MyLinkMovementMethod extends LinkMovementMethod   
{
@Override
public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event)
{
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_DOWN
|| action == MotionEvent.ACTION_MOVE)
{
int x = (int) event.getX();
int y = (int) event.getY(); x -= widget.getTotalPaddingLeft();// 返回textView的偏移量,如textView设置了padding=3px,则返回3
y -= widget.getTotalPaddingTop(); /**
* 左侧超出屏幕的偏移量,如一个view可左右滑动,由于此view比较大,左侧的view被挡住了,
* 被挡住的偏移量就是getScrollX(),同理getScrollY()
*/
x += widget.getScrollX();
y += widget.getScrollY(); // 上述的目的是定位出点击的位置 在整个view组件的绝对坐标(不是屏幕的相对坐标)
Layout layout = widget.getLayout();
int line = layout.getLineForVertical(y); // 获取点击位置的 text的行数
int off = layout.getOffsetForHorizontal(line, x);// 获取点击位置的偏移量 // 通过偏移量来获取span (具体是通过偏移量对应的span来确定)
ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
if (link.length != 0)
{
if (action == MotionEvent.ACTION_UP)
{
link[0].onClick(widget); buffer.setSpan(new BackgroundColorSpan(Color.TRANSPARENT), buffer.getSpanStart(link[0]),
buffer.getSpanEnd(link[0]), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); Selection.removeSelection(buffer); }
else if (action == MotionEvent.ACTION_DOWN)
{ buffer.setSpan(new BackgroundColorSpan(Color.GRAY), buffer.getSpanStart(link[0]),
buffer.getSpanEnd(link[0]), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); Selection.setSelection(buffer, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0]));
}
else if (action == MotionEvent.ACTION_MOVE)
{ buffer.setSpan(new BackgroundColorSpan(Color.TRANSPARENT), buffer.getSpanStart(link[0]),
buffer.getSpanEnd(link[0]), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); Selection.removeSelection(buffer);
} return true;
}
else
{
Selection.removeSelection(buffer);
}
}
//必须returnsuper.onTouchEvent(widget, buffer, event);
//否则因为重写了onTouchEvent,导致在action_up的时候无法调用ClickableSpan
return super.onTouchEvent(widget, buffer, event);
}
}

3.弹出键盘

 

  /**   * 弹出软键盘   */  private void showKeyBoard(String name)  {    commentEdit.setHint("回复"+name); //输入框显示要回复谁    commentEdit.requestFocus();    (new Handler()).postDelayed(new Runnable()     {       public void run()       {       ((InputMethodManager) (commentEdit.getContext()                       .getSystemService(Context.INPUT_METHOD_SERVICE)))                       .toggleSoftInput(0,       InputMethodManager.HIDE_NOT_ALWAYS);       }       }, 100);  }