⬇️⬇️⬇️⬇️⬇️⬇️⬇️ 废话 ⬇️⬇️⬇️⬇️⬇️⬇️⬇️
最近不造产品何时的需求,要输入框不能输入原生的Emoji表情,而且还要有输入字数的限制。
搞得测试MM追到我改,我当时想的是一个输入限制能有多难...结果尼玛一上午过去了都没搞得- -.
无奈测试MM要东西...就老老实实的百度了。在网上找到一哥们的Demo,下下来运行了发现确实可行。但是写的不符合我的要求,对于有编程强迫症的我怎么可能忍。
于是乎 改改改,抄抄抄,按照他的步伐抄了一下午都没超出来...到最后都没能理解...
好吧,测试MM妹妹已经提BUG下班走人了...
但是我这坑还是要填的...废话到这里,直接进入主题。
⬆️⬆️⬆️⬆️⬆️⬆️⬆️ 废话 ⬆️⬆️⬆️⬆️⬆️⬆️⬆️
主布局文件, 新建的Module自动生成的布局,只不过将TextView改了一下。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.warden.snsemoji.MainActivity">
<EditText
android:id="@+id/main_et"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Hello World!"/>
</RelativeLayout>
主要是TextChange 这个内部内,构造方法中的参数是方便解耦。
package com.warden.snsemoji;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity
{
private static final String TAG = "warden";
private EditText mainEt;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainEt = (EditText) findViewById(R.id.main_et);
mainEt.addTextChangedListener(new TextChange(mainEt));
}
private class TextChange implements TextWatcher
{
private EditText et;
public TextChange(EditText et)
{
this.et = et;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
// i("s:" + s);
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
// e("s:" + s + " start:" + start + " before:" + before + " count:" + count);
//输入的类容
CharSequence input = s.subSequence(start, start + count);
//e("输入信息:" + input);
// 退格
if (count == 0) return;
//如果 输入的类容包含有Emoji
if (isEmojiCharacter(input))
{
show("not input emoji");
//那么就去掉
et.setText(removeEmoji(s));
}
//如果输入的字符超过最大限制,超出的部分 砍掉~
if (s.length() > 3)
{
show("超过输入的最大限制");
et.setText(s.subSequence(0, start));
}
//最后光标移动到最后 TODO 这里可能会有更好的解决方案
et.setSelection(et.getText().toString().length());
}
@Override
public void afterTextChanged(Editable s)
{
// d("s:" + s);
}
}
/**
* 去除字符串中的Emoji表情
* @param source
* @return
*/
private String removeEmoji(CharSequence source)
{
String result = "";
for (int i = 0; i < source.length(); i++)
{
char c = source.charAt(i);
if (isEmojiCharacter(c))
{
continue;
}
result += c;
}
return result;
}
/**
* 判断一个字符串中是否包含有Emoji表情
* @param input
* @return true 有Emoji
*/
private boolean isEmojiCharacter(CharSequence input)
{
for (int i = 0; i < input.length(); i++)
{
if (isEmojiCharacter(input.charAt(i)))
{
return true;
}
}
return false;
}
/**
* 是否是Emoji 表情,抄的那哥们的代码
*
* @param codePoint
* @return true 是Emoji表情
*/
public static boolean isEmojiCharacter(char codePoint)
{
// Emoji 范围
boolean isScopeOf = (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA) || (codePoint == 0xD)
|| ((codePoint >= 0x20) && (codePoint <= 0xD7FF) && (codePoint != 0x263a))
|| ((codePoint >= 0xE000) && (codePoint <= 0xFFFD))
|| ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
return !isScopeOf;
}
private void show(String msg)
{
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
}
void e(String msg)
{
Log.e(TAG, msg);
}
void i(String msg)
{
Log.i(TAG, msg);
}
void d(String msg)
{
Log.d(TAG, msg);
}
}
如果我的代码帮到了你,请帮我点一个赞~\(≧▽≦)/~