仿新浪微博的插入#话题#

来源:互联网 发布:淘宝能买到唛可奈因吗 编辑:程序博客网 时间:2024/04/29 23:17

最近看到其他网上有写仿新浪微博插入话题这个功能,具体就是当用户输入"#"这个字符以后,会跳出一个选项让用户选择一个话题,然后在输入框中会显示#XX话题#,点击删除会一下把整个话题删除,而不是一个个删除,并且#XX话题#会变色。

我的想法,首先肯定是监听EditText的输入,当用户输入"#"之后,Activity就会跳转到选择话题的另外一个Activity,用户点击一个话题之后,通过onActivityResult这个回调函数拿到话题,至于怎么做到一下子把整个话题删除,变色这样的功能,我是把拿到的String转换成一个


首先是监听用户的输入:

et.addTextChangedListener(new TextWatcher() {@Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {//System.out.println( s.charAt(start));if(s.length() == start){}else{if("#".toCharArray()[0] == s.charAt(start)){AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);//Dialog dialog = builder.show();builder.setIcon(R.drawable.ic_launcher).setTitle("choose the topic!").setPositiveButton("ensure", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {//dialog.dismiss();Intent intent = new Intent(MainActivity.this,ChooseActivity.class);startActivityForResult(intent, 1);}}).create().show();//System.out.println("equals");//Toast.makeText(MainActivity.this, "you input an a!!", Toast.LENGTH_SHORT).show();}}//System.out.println(start + " " + before);//System.out.println("the word you input this time:" + " " + s.charAt(start));}@Overridepublic void beforeTextChanged(CharSequence s, int start, int count,int after) {//System.out.println(count);//lastInputString = s.toString();}@Overridepublic void afterTextChanged(Editable s) {// TODO 自动生成的方法存根}});


接着是onActivityReslut这个回调函数:


@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {if(requestCode == 1 && resultCode == 0){String topic = "#" + data.getExtras().getString("topic") + "#";et.insertTopic(topic);}super.onActivityResult(requestCode, resultCode, data);}


看到insertTopic这个函数,就应该知道我使用的EditText是自定义的,并且自己添加了这个方法。


下面是自定义的EditText:


public class MyEditText extends EditText {public MyEditText(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}public MyEditText(Context context, AttributeSet attrs) {super(context, attrs);}public MyEditText(Context context) {super(context);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);}public void insertTopic(String topic){this.getText().delete(this.getText().length() - 1, this.getText().length());SpannableString ss = new SpannableString("[" + topic + "]");TopicDrawable td = new TopicDrawable(topic);td.setBounds(0, 0, td.getIntrinsicWidth(), td.getIntrinsicHeight());System.out.println(td.getIntrinsicHeight() + " " + td.getIntrinsicWidth());ImageSpan span = new ImageSpan(td, ImageSpan.ALIGN_BASELINE);ss.setSpan(span, 0, topic.length()+2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);int start = this.getSelectionStart();int end = this.getSelectionEnd();if(start == end){//System.out.println(et.getText().length());this.getText().insert(start, ss);}else{this.getText().replace(start, end, ss);}//System.out.println(start + ss.length());//System.out.println(getText().length());this.setSelection(start + ss.length());}}

将string转化成drawable,具体就是通过SpannableString和ImageSpan来实现的最后一句话是将EditText的光标设置到最后,大家可以去掉再看看是什么情况。

当然,TopicDrawable也是我自定义的。


public class TopicDrawable extends Drawable {private String topic;private Paint paint;public TopicDrawable(String topic){this.topic = topic;paint = new Paint();paint.setColor(Color.BLUE);paint.setTextSize(36);}@Overridepublic void draw(Canvas canvas) {canvas.drawText(topic, 0, 0, paint);}@Overridepublic void setAlpha(int alpha) {}@Overridepublic void setColorFilter(ColorFilter cf) {}@Overridepublic int getOpacity() {return 0;}@Overridepublic int getIntrinsicHeight() {return 0;}@Overridepublic int getIntrinsicWidth() {return (int) paint.measureText(topic);}}


核心代码就是onDraw了,通过一个paint来控制颜色和字体大小。另外还有就是需要重写getIntrinsicHeight和getIntrinsicWidth这个两个函数,不然的话,EditText的光标是无法设置到正确的位置的。height直接返回0就可以,如果你返回的不是0(比如n),那么光标的位置就会相应的往下移n个具体,width的话,当然就是text的宽度了,使用paint的measureText就能很快的得到。


以上就是全部代码了,虽然很简单,不过其中也涵盖了不少的知识,其中有很多是比较细碎的,可以细细品味。

0 0
原创粉丝点击