py4j汉语转拼音多音字处理
先看下效果
一 、布局
<!-- 上面的搜索框 -->
<com.example.editablealphalist.widgget.ClearEditText
android:id="@+id/filter_edit"
android:layout_marginTop="5dip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/search_bar_edit_selector"
android:drawableLeft="@drawable/search_bar_icon_normal"
android:hint="请输入关键字"
android:singleLine="true"
android:textSize="15sp" /> <FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent" > <ListView
android:id="@+id/name_listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:divider="@null" /> <!-- 中间显示的选中的大写首字母 -->
<TextView
android:id="@+id/dialog"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_gravity="center"
android:background="@drawable/show_head_toast_bg"
android:gravity="center"
android:textColor="@color/font_color_selected"
android:textSize="30sp"
android:visibility="gone" /> <!-- 右侧供选择的列表 -->
<com.example.editablealphalist.widgget.SideBar
android:id="@+id/sidrbar"
android:layout_width="30dp"
android:layout_height="match_parent"
android:layout_gravity="right|center" />
</FrameLayout>
二、自定义控件
2.1 ClearEditText 带删除按钮的输入框
public class ClearEditText extends AppCompatEditText implements OnFocusChangeListener, TextWatcher { /**
* 删除按钮的引用
*/
private Drawable mClearDrawable; public ClearEditText(Context context) {
this(context, null);
} public ClearEditText(Context context, AttributeSet attrs) {
// 这里构造方法也很重要,不加这个很多属性不能再XML里面定义
this(context, attrs, android.R.attr.editTextStyle);
} public ClearEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
} private void init() {
// 获取EditText的DrawableRight,假如没有设置我们就使用默认的图片
mClearDrawable = getCompoundDrawables()[2];
if (mClearDrawable == null) {
mClearDrawable = getResources().getDrawable(R.drawable.emotionstore_progresscancelbtn);
}
mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight());
setClearIconVisible(false);
setOnFocusChangeListener(this);
addTextChangedListener(this);
} @Override
public boolean onTouchEvent(MotionEvent event) { if (getCompoundDrawables()[2] != null) { if (event.getAction() == MotionEvent.ACTION_UP) { boolean touchable = event.getX() > (getWidth() - getPaddingRight() - mClearDrawable.getIntrinsicWidth())
&& (event.getX() < ((getWidth() - getPaddingRight())));
if (touchable) { //选中了“删除”按钮 this.setText("");
}
}
}
return super.onTouchEvent(event);
} /**
* 当ClearEditText焦点发生变化的时候,判断里面字符串长度设置清除图标的显示与隐藏
*/
@Override
public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { setClearIconVisible(getText().length() > 0);
} else { setClearIconVisible(false);
}
} /**
* 设置清除图标的显示与隐藏,调用setCompoundDrawables为EditText绘制上去
*
* @param visible
*/
protected void setClearIconVisible(boolean visible) { Drawable right = visible ? mClearDrawable : null;
setCompoundDrawables(getCompoundDrawables()[0], getCompoundDrawables()[1], right, getCompoundDrawables()[3]);
} /**
* 当输入框里面内容发生变化的时候回调的方法
*/
@Override
public void onTextChanged(CharSequence s, int start, int count, int after) {
setClearIconVisible(s.length() > 0);
} @Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
} @Override
public void afterTextChanged(Editable s) { }
}
2.2 SideBar 右侧首字母列表
/**
* 右侧首字母列表bar
* @author Jack
* @version 创建时间:2014-2-6 下午3:37:33
*/
public class SideBar extends View { /** 触摸事件 */
private OnTouchingLetterChangedListener onTouchingLetterChangedListener;
/** 26个字母 */
public static String[] characters = { "A", "B", "C", "D", "E", "F", "G",
"H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
"U", "V", "W", "X", "Y", "Z", "#" };
private int ifSelected = -1; // 选中
private Paint paint = new Paint();
private TextView mTextDialog; public void setTextView(TextView mTextDialog) {
this.mTextDialog = mTextDialog;
} public SideBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
} public SideBar(Context context, AttributeSet attrs) {
super(context, attrs);
} public SideBar(Context context) {
super(context);
} /**
* 重写这个方法
*/
protected void onDraw(Canvas canvas) { super.onDraw(canvas);
// 获取焦点改变背景颜色.
int height = getHeight(); // 获取对应高度
int width = getWidth(); // 获取对应宽度
int singleHeight = height / characters.length; // 获取每一个字母的高度 for (int i = 0; i < characters.length; i++) { // 设置颜色
paint.setColor(Color.rgb(33, 65, 98));
// 设置字体
paint.setTypeface(Typeface.DEFAULT_BOLD);
// 设置抗锯齿
paint.setAntiAlias(true);
// 设置字体大小
paint.setTextSize(20);
// 选中的状态
if (i == ifSelected) { paint.setColor(Color.parseColor("#3399ff"));
paint.setFakeBoldText(true);
}
// x坐标等于中间-字符串宽度的一半.
float xPos = width / 2 - paint.measureText(characters[i]) / 2;
float yPos = singleHeight * i + singleHeight;
canvas.drawText(characters[i], xPos, yPos, paint);
paint.reset();// 重置画笔
}
} @Override
public boolean dispatchTouchEvent(MotionEvent event) { final int action = event.getAction();
final float y = event.getY();// 点击y坐标
final int oldSelected = ifSelected;
final OnTouchingLetterChangedListener listener = onTouchingLetterChangedListener;
final int selected = (int) (y / getHeight() * characters.length);// 点击y坐标所占总高度的比例*b数组的长度就等于点击b中的个数. switch (action) { case MotionEvent.ACTION_UP: setBackgroundDrawable(new ColorDrawable(0x00000000));
ifSelected = -1;//
invalidate();
if (mTextDialog != null) {
mTextDialog.setVisibility(View.INVISIBLE);
}
break;
default: setBackgroundResource(R.drawable.sidebar_background);
if (oldSelected != selected) {
if (selected >= 0 && selected < characters.length) {
if (listener != null) {
listener.onTouchingLetterChanged(characters[selected]);
}
if (mTextDialog != null) {
mTextDialog.setText(characters[selected]);
mTextDialog.setVisibility(View.VISIBLE);
}
ifSelected = selected;
invalidate();
}
}
break;
}
return true;
} /**
* 向外公开的方法
* @param onTouchingLetterChangedListener
*/
public void setOnTouchingLetterChangedListener(OnTouchingLetterChangedListener onTouchingLetterChangedListener) { this.onTouchingLetterChangedListener = onTouchingLetterChangedListener;
} /**
* 触碰右侧列表时的回调接口
*/
public interface OnTouchingLetterChangedListener {
public void onTouchingLetterChanged(String s);
}
三、事件处理
3.1 右侧字母栏滑动处理
sideBar = (SideBar) findViewById(R.id.sidrbar);
dialog = (TextView) findViewById(R.id.dialog);
sideBar.setTextView(dialog);
// 设置右侧触摸监听
sideBar.setOnTouchingLetterChangedListener(new SideBar.OnTouchingLetterChangedListener() { @Override
public void onTouchingLetterChanged(String s) {
// 该字母首次出现的位置
int position = adapter.getPositionForSection(s.charAt(0));
if (position != -1) {
sortListView.setSelection(position);
}
}
});
3.2 输入框事件处理
//查询框设置监听
mClearEditText = (ClearEditText) findViewById(R.id.filter_edit);
// 根据输入框输入值的改变来过滤搜索
mClearEditText.addTextChangedListener(new TextWatcher() { @Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
// 当输入框里面的值为空,更新为原来的列表,否则为过滤数据列表
filterData(s.toString());
} @Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) { } @Override
public void afterTextChanged(Editable s) {
}
});
/**
* 根据输入框中的值来过滤数据源,截取含有查询字符串的数据
*
* @param filterStr 查询字符串
*/
private void filterData(String filterStr) { List<SortModel> filterDataList = new ArrayList<SortModel>();
if (TextUtils.isEmpty(filterStr)) { filterDataList = sourceDataList;
} else { filterDataList.clear();
for (SortModel sortModel : sourceDataList) { String name = sortModel.getName();
/*if (name.indexOf(filterStr.toString()) != -1 || characterParser.getSelling(name).startsWith(filterStr.toString())) { filterDataList.add(sortModel);
}*/
if (name.indexOf(filterStr.toString()) != -1 || pinyin4JUtil.convertChineseToPinyin(name).startsWith(filterStr.toString())) { filterDataList.add(sortModel);
}
}
}
// 根据a-z进行排序
Collections.sort(filterDataList, pinyinComparator);
adapter.updateListView(filterDataList);
}
四、汉字转拼音及多音字处理
4.1 初始化转换格式
/**
* 获取拼音初始汉语拼音格式化实例
*
* @param withTone
* @return
*/
private HanyuPinyinOutputFormat getHanyuPinyinOutputFormat(boolean withTone) {
HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
if (withTone) {
//直接用音标符
format.setToneType(HanyuPinyinToneType.WITH_TONE_MARK);// WITHOUT_TONE:无音标 (xing)
//format.setToneType(HanyuPinyinToneType.WITH_TONE_NUMBER);// WITH_TONE_NUMBER:1-4数字表示英标 (xing2)
//直接用ü (nü)
format.setVCharType(HanyuPinyinVCharType.WITH_U_UNICODE);//WITH_V:用v表示ü (nv) //WITH_U_AND_COLON:用”u:”表示ü (nu:)
format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
} else {
//直接用音标符
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
format.setVCharType(HanyuPinyinVCharType.WITH_U_UNICODE);
format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
}
return format;
}
setToneType 设置音标的显示方式:
- HanyuPinyinToneType.WITH_TONE_MARK:在拼音字母上显示音标,如“zhòng”
- HanyuPinyinToneType.WITH_TONE_NUMBER:在拼音字符串后面通过数字显示,如“zhong4”
- HanyuPinyinToneType.WITHOUT_TONE:不显示音标
setCaseType 设置拼音大小写:
- HanyuPinyinCaseType.LOWERCASE:返回的拼音为小写字母
- HanyuPinyinCaseType.UPPERCASE:返回的拼音为大写字母
setVCharType 设置拼音字母“ü”的显示方式
汉语拼音中的“ü”不能简单的通过英文来表示,所以需要单独定义“ü”的显示格式- HanyuPinyinVCharType.WITH_U_UNICODE:默认的显示方式,输出“ü”
- HanyuPinyinVCharType.WITH_V:输出“v”
- HanyuPinyinVCharType.WITH_U_AND_COLON:输出“u:”
4.2 转换成汉语拼音
HanyuPinyinOutputFormat defaultFormat = getHanyuPinyinOutputFormat(false);
String[] results = PinyinHelper.toHanyuPinyinStringArray(ch, defaultFormat);//ch是要转化的汉字,用char表示。如'重'
如果results中拼音个数如果大于1说明该汉字是多音字
4.3 多音字处理
4.3.1 获取py4j.txt中的数据转换成map形式
private HashMap<String, String> initDictionary(Context context) {
String fileName = "py4j.txt";
InputStreamReader inputReader = null;
BufferedReader bufferedReader = null;
HashMap<String, String> polyphoneMap = new HashMap<String, String>();
try {
inputReader = new InputStreamReader(context.getResources().getAssets().open(fileName), "UTF-8");
bufferedReader = new BufferedReader(inputReader);
String line = null;
while ((line = bufferedReader.readLine()) != null) {
//Log.d(TAG,"======"+line);
if (line != null) {
String[] arr = line.split("#");
String pinyin = arr[0];
String chinese = arr[1];
if (chinese != null) {
String[] strs = chinese.split(" ");
List<String> list = Arrays.asList(strs);
pinyinMap.put(pinyin, list);
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
将py4j.txt保存到assets目录通过context.getResources().getAssets().open(fileName)打开,存放到字符流中。
4.3.2 判断多音字并找到最优的拼音
{
int len = results.length;
if (len == 1) { // 不是多音字
String[] pinyinArray = getHanyuStrings(true, ch);
pinyin.append(pinyinArray[0]);
} else if (results[0].equals(results[1])) { //非多音字 有多个音,取第一个
//pinyin.append(results[0]);
String[] pinyinArray = getHanyuStrings(true, ch);
pinyin.append(pinyinArray[0]);
} else { // 多音字
int length = chinese.length();
boolean flag = false;
String s = null;
List<String> keyList = null;
for (int x = 0; x < len; x++) {
String py = results[x];
keyList = pinyinMap.get(py.toLowerCase());
resultPos = x;
if (i + 3 <= length) { //后向匹配2个汉字 大西洋
s = chinese.substring(i, i + 3);
if (keyList != null && (keyList.contains(s))) {
flag = true;
break;
}
}
if (i + 2 <= length) { //后向匹配 1个汉字 大西
s = chinese.substring(i, i + 2);
if (keyList != null && (keyList.contains(s))) {
flag = true;
break;
}
}
if ((i - 2 >= 0) && (i + 1 <= length)) { // 前向匹配2个汉字 龙固大
s = chinese.substring(i - 2, i + 1);
if (keyList != null && (keyList.contains(s))) {
flag = true;
break;
}
}
if ((i - 1 >= 0) && (i + 1 <= length)) { // 前向匹配1个汉字 固大
s = chinese.substring(i - 1, i + 1);
if (keyList != null && (keyList.contains(s))) {
flag = true;
break;
}
}
if ((i - 1 >= 0) && (i + 2 <= length)) { //前向1个,后向1个 固大西
s = chinese.substring(i - 1, i + 2);
if (keyList != null && (keyList.contains(s))) {
flag = true;
break;
}
}
}
if (!flag) {//都没有找到,匹配默认的 读音 大
s = String.valueOf(ch);
for (int x = 0; x < len; x++) {
String py = results[x];
keyList = pinyinMap.get(py.toLowerCase());
if (keyList != null && (keyList.contains(s))) {
String[] pinyinArray = getHanyuStrings(true, ch);
pinyin.append(pinyinArray[x]);
break;
}
}
} else {
String[] pinyinArray = getHanyuStrings(true, ch);
pinyin.append(pinyinArray[resultPos]);
}
}
}
如果是多音字,则去匹配py4j.txt中的字符是否存在找到对应的多音字下标
String[] pinyinArray = getHanyuStrings(true, ch);
pinyin.append(pinyinArray[resultPos]);
...
private String[] getHanyuStrings(boolean withTone, char ch) {
HanyuPinyinOutputFormat format = getHanyuPinyinOutputFormat(withTone);
String[] pinyinArray = new String[0];
try {
pinyinArray = PinyinHelper.toHanyuPinyinStringArray(ch, format);
} catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) {
badHanyuPinyinOutputFormatCombination.printStackTrace();
}
return pinyinArray;
}
五、缺点
判断多音字存在缺陷,只能通过py4j.txt字库中查找,字库资源不完善。
https://github.com/MichealPan9999/chinesetopinyin
py4j汉语转拼音多音字处理的更多相关文章
- C# 汉语转拼音
汉语转拼音或首字母 通常不少网站上有汉语转拼音功能,今天就小记下这段汉语转拼音的代码,自己测试ok,现把代码贴出来,以备日后使用: 效果 用法很简单后台使用到了两个类文件,一个是:ConvertHzT ...
- java:工具(汉语转拼音,压缩包,EXCEL,JFrame窗口和文件选择器,SFTP上传下载,FTP工具类,SSH)
1.汉语转拼音: import net.sourceforge.pinyin4j.PinyinHelper; import net.sourceforge.pinyin4j.format.HanyuP ...
- java 汉语转拼音(全拼,首字母)
import java.util.*; import net.sourceforge.pinyin4j.PinyinHelper;import net.sourceforge.pinyin4j.for ...
- JS汉语转拼音脚本
测试代码: var anhui = "安徽"; //获得全拼 pinyin.getFullChars(anhui); //获得首拼 pinyin.getCamelChars(anh ...
- js汉语转拼音(全拼、首字母、拼音首字母)
新建js文件first_alphabet.js // JavaScript Document // 汉字拼音首字母列表 本列表包含了20902个汉字,用于配合 ToChineseSpell //函数使 ...
- 汉语转拼音pinyin4j
分享一个将汉语转成拼音的工具包:pinyin4j-2.5.0.jar,下载地址:http://download.csdn.net/detail/abc_key/7629141 使用例如以下代码 imp ...
- Java-汉字繁体拼音转换
import com.github.stuxuhai.jpinyin.ChineseHelper; import com.github.stuxuhai.jpinyin.PinyinFormat; i ...
- C#编写的通过汉字得到拼音和五笔码
public static class SpellAndWbConfig { #region 变量声明 // XML文件读取实例 /// <summary> /// XML文件读取实例 / ...
- .net 生成拼音码与五笔码
首先加入配置文件: <?xml version="1.0" encoding="utf-8" ?> <CodeConfig> <S ...
随机推荐
- 【webpack】使用DllPlugin拆分模块
开发过程中,我们经常需要引入大量第三方库,这些库并不需要随时修改或调试,我们可以使用DllPlugin和DllReferencePlugin单独构建它们. 具体使用如下: const HtmlWebp ...
- Ant使用指南
ant 使用指南 参考:http://www.cnblogs.com/hoojo/archive/2013/06/14/java_ant_project_target_task_run.html 一 ...
- spring4 注入参数
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- 执行maven install跳过执行maven test方法(网上搜的记录一下,方面以后使用)
直接在pom文件加上这段配置就可以了 <plugin> <groupId>org.apache.maven.plugins</groupId> ...
- ASP.NET MVC 入门
ASP.NET MVC 入门 (Learning ASP.NET MVC) 传统的WebForm发展到如今出现不少的缺陷, 比如为了解决Http的无状态WebForm模式使用了ViewsState来保 ...
- layer兼容性问题
一.Layer 弹出层在ie8错乱的解决办法 弹出层在火狐.谷歌.360极速模式.IE6下都能100%面积正常显示,但在IE8和360的兼容模式下只显示弹出层下半部分或右半部分的内容,在主页面加上: ...
- JVM内存分配 -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=512m
https://blog.csdn.net/u012882327/article/details/69525166
- 获取异步API数据
异步操作应该是以前学习 ajax 时才被明确提及,就目前的理解,同步就是同一时间只能做一件事,如果使用 ajax同步模式,则代码会卡在 xhr.send() 这里,只有请求响应的过程全部完成了才会执行 ...
- LeetCode Two Add Two Numbers (JAVA)
问题简介:输入两个数字链表,输出求和后的链表(链表由数字位数倒序组成) 问题详解: 给定两个非空链表,表示两个非负整数. 数字以相反的顺序存储,每个节点包含一位数字.对两个整数作求和运算,将结果倒序作 ...
- linux 安装matlab
转自: https://www.cnblogs.com/Amedeo/archive/2018/06/03/9129925.html 一.下载“Crack”和”ISO”文件 下载地址如下所示:http ...