今天我的小伙伴让帮忙写一个仿新浪微博加#话题的EditText,并给了我一篇文章的连接,如下:http://dwz.cn/I1Tm1
这篇文章虽说写的很详细,但我的看的是云里雾里的,没看太懂(只能怪我理解能力不行啦),所以只好根据这个作者的思路自己写一个了。
写给大家伙看看微博的样子,如下(导的别人的图):
由于是写一个demo而已,所以我这里是点击一个按钮添加一个蓝色字体块,大体说一下我的思路:
1.要改变#字体块的颜色。
2.当删除时遇到#号字体块时,要删除整块。
3.当手指点击字体将光标移动到#字体块中时,要将光标移动到#字体块的尾部。
以上三个功能就是我们要实现的,我们来一 一讲解。
第一点(改变#字体块的颜色):
这个我感觉是比较简单的,我们可以利用css样式来改变,这个技术我也是刚知道不久,java中有一个Html的类,我们就要利用这个类来实现一部分字体颜色的变化,代码如下:
String str = "#你是一个啥#";
Spanned spanned = Html.fromHtml("<font color=\"blue\">" + str + "</font>");
textInputEdit.setText(spanned);
好了就这么几句代码就搞定了。
第二点(当删除时遇到#号字体块时,要删除整块):
这一功能我的思路是在删除是遇到#号时,先获取整个#的下标(也就是光标位置),然后我们就去遍历整个EditText中的文本,找到这个#号的下一个#的下标,根据这两个下标来进行删除操作。
第三点(当手指点击字体将光标移动到#字体块中时,要将光标移动到#字体块的尾部):
这个实现的思路就是,在添加#号字体块的时候将添加的位置记录下来放到一个集合当中(只储存首尾下标),然后再每次点击EditText时获取光标的位置并判断这个光标在不在集合记录的位置当中,如果在,那么就获取在哪一个范围中,找到这个范围后将光标的位置移动到这个范围的末尾下标。
整体的思路就是这样的。
ps:这里只是简单说一下思路一会具体的看代码。
代码中用到的实体类:
package com.example.administrator.coo.Bean;
/**
* Created by zhanglei on 2017/3/20 0020.
* 记录每个要整体删除的字段的首位下标
*/
public class IndexBean {
private int heardIndex;
private int footerIndex;
private int length;
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public int getHeardIndex() {
return heardIndex;
}
public void setHeardIndex(int heardIndex) {
this.heardIndex = heardIndex;
}
public int getFooterIndex() {
return footerIndex;
}
public void setFooterIndex(int footerIndex) {
this.footerIndex = footerIndex;
}
}
Activity中的代码:
package com.example.administrator.coo;
import android.os.Bundle;
import android.text.Editable;
import android.text.Html;
import android.text.Spanned;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import com.example.administrator.coo.Bean.IndexBean;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
/**
* @author zhanglei
* @date 17/03/20
* 仿微博话题输入页
*/
public class TextInputActivity extends BaseActivity {
@BindView(R.id.text_input_edit)
EditText textInputEdit;
@BindView(R.id.text_input_add_text)
Button textInputAddText;
private List<Integer> mList;
private List<IndexBean> indexBeanList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_text_input);
ButterKnife.bind(this);
initListener();
}
/**
* 初始化监听事件
*/
private void initListener() {
textInputEdit.addTextChangedListener(new MyTextWatcher());
}
@OnClick({R.id.text_input_add_text, R.id.text_input_edit})
public void onClick(View view) {
switch (view.getId()) {
//添加文字
case R.id.text_input_add_text:
addText();
break;
case R.id.text_input_edit:
getAndSetIndex();
break;
}
}
/**
* 获取edittext光标位置
* 如果光标在蓝色字体内部,就将光标移动到蓝色字体的后方
*/
private void getAndSetIndex() {
if (indexBeanList != null && indexBeanList.size() > 0) {
int selectionStart = textInputEdit.getSelectionStart() - 1;
Log.e("getAndSetIndex", "selectionStart:" + selectionStart);
//遍历集合查看光标是否在蓝色字体块中
for (IndexBean bean : indexBeanList) {
Log.e("getAndSetIndex", "getHeardIndex:" + bean.getHeardIndex() + "\ngetFooterIndex:" + bean.getFooterIndex());
if (selectionStart >= bean.getHeardIndex() && selectionStart <= bean.getFooterIndex()) {
//条件成立,表示光标在蓝色字体块内,设置光标位置
textInputEdit.setSelection(bean.getFooterIndex());
}
}
}
}
/**
* 添加一段文字
*/
private void addText() {
String str = "#你是一个啥#";
int heard;
int footer;
Spanned spanned = Html.fromHtml("<font color=\"blue\">" + str + "</font>");
//添加文字
textInputEdit.setText(textInputEdit.getText());
heard = textInputEdit.getText().length();
textInputEdit.append(spanned);
footer = textInputEdit.getText().length();
//设置光标位置
textInputEdit.setSelection(textInputEdit.getText().toString().length());
//记录蓝色字体块的头尾下标
IndexBean bean = new IndexBean();
bean.setHeardIndex(heard);
bean.setFooterIndex(footer);
bean.setLength(str.length());
indexBeanList.add(bean);
}
/**
* Edit录入的监听事件
*/
public class MyTextWatcher implements TextWatcher {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
//记录两个#号的下标
mList = new ArrayList<>();
//表示是删除操作
if (i1 == 1) {
try {
//判断光标的前一位字符是不是#
String str = charSequence.toString();
String lastText = str.substring(i, i + 1);
//如果是,那么我们就要删除这个#号到下一个#号的之间的字符(包括#号)
if (lastText.equals("#")) {
String substring = str.substring(0, i + 1);
char[] chars = substring.toCharArray();
int count = 0;
if (mList != null) {
mList.clear();
}
//记录要删除内容的下标
int length = chars.length - 1;
for (int index = length; index >= 0; index--) {
if ((chars[index] + "").equals("#")) {
count++;
mList.add(index);
if (count == 2) {
break;
}
}
}
}
} catch (NullPointerException e) {
}
}
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
//在这里执行删除的操作
if (mList != null && mList.size() > 1) {
Integer integer = mList.get(0);
Integer integer1 = mList.get(1);
editable.delete(integer1, integer);
int index = 0;
//删除的字符串长度
int length = 0;
//从蓝色块集合中删除
if (indexBeanList != null && indexBeanList.size() > 0) {
for (int i = 0; i < indexBeanList.size(); i++) {
IndexBean bean = indexBeanList.get(i);
if (integer >= bean.getHeardIndex() && integer <= bean.getFooterIndex()) {
index = i;
length = bean.getLength();
}
}
}
indexBeanList.remove(index);
//重新设置蓝色块下标集合
for (int i = 0; i < indexBeanList.size(); i++) {
IndexBean bean = indexBeanList.get(i);
if (integer < bean.getHeardIndex()) {
bean.setHeardIndex(bean.getHeardIndex() - length);
bean.setFooterIndex(bean.getFooterIndex() - length);
indexBeanList.set(i, bean);
}
}
}
}
}
}
布局代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_text_input"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.administrator.coo.TextInputActivity">
<EditText
android:id="@+id/text_input_edit"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/text_input_add_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10px"
android:text="添加文字" />
</LinearLayout>
好啦本文到此结束,希望对有需求的同学有所帮助