public class PinyinHelper {
private static PinyinHelper instance;
private Properties properties = null;
public static String[] getUnformattedHanyuPinyinStringArray(char ch) {
return getInstance().getHanyuPinyinStringArray(ch);
}
private PinyinHelper() {
initResource();
}
public static PinyinHelper getInstance() {
if (instance == null) {
instance = new PinyinHelper();
}
return instance;
}
private void initResource() {
try {
final String resourceName = "/assets/unicode_to_hanyu_pinyin.txt";
// final String resourceName = "/assets/unicode_py.ini";
properties = new Properties();
properties.load(getResourceInputStream(resourceName));
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
private BufferedInputStream getResourceInputStream(String resourceName) {
return new BufferedInputStream(
PinyinHelper.class.getResourceAsStream(resourceName));
}
private String[] getHanyuPinyinStringArray(char ch) {
String pinyinRecord = getHanyuPinyinRecordFromChar(ch);
if (null != pinyinRecord) {
int indexOfLeftBracket = pinyinRecord.indexOf(Field.LEFT_BRACKET);
int indexOfRightBracket = pinyinRecord
.lastIndexOf(Field.RIGHT_BRACKET);
String stripedString = pinyinRecord.substring(indexOfLeftBracket
+ Field.LEFT_BRACKET.length(), indexOfRightBracket);
return stripedString.split(Field.COMMA);
} else
return null;
}
private String getHanyuPinyinRecordFromChar(char ch) {
int codePointOfChar = ch;
String codepointHexStr = Integer.toHexString(codePointOfChar)
.toUpperCase();
String foundRecord = properties.getProperty(codepointHexStr);
return foundRecord;
}
class Field {
static final String LEFT_BRACKET = "(";
static final String RIGHT_BRACKET = ")";
static final String COMMA = ",";
}
public static String[] toHanyuPinyinStringArray(char ch) {
return getUnformattedHanyuPinyinStringArray(ch);
}
}
public class BookEntity {
private String book;
private String author;
private String press;
public BookEntity() {
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getBook() {
return book;
}
public void setBook(String book) {
this.book = book;
}
public String getPress() {
return press;
}
public void setPress(String press) {
this.press = press;
}
public BookEntity(String author, String book, String press) {
this.author = author;
this.book = book;
this.press = press;
}
@Override
public String toString() {
return "BookEntity{" +
"author='" + author + '\'' +
", book='" + book + '\'' +
", press='" + press + '\'' +
'}';
}
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initAuto1();
initAuto2();
}
private void initAuto2() {
List<BookEntity> list = new ArrayList<>();
list.add(new BookEntity("施耐庵", "水浒传", "人民文学出版社"));
list.add(new BookEntity("罗贯中", "三国演义", "人民文学出版社"));
list.add(new BookEntity("吴承恩", "西游记", "三联出版社"));
list.add(new BookEntity("曹雪芹", "红楼梦", "花城出版社"));
MyAdapter adapter = new MyAdapter(this, list);
AutoCompleteTextView auto2 = (AutoCompleteTextView) findViewById(R.id.auto2);
auto2.setAdapter(adapter);
}
private void initAuto1() {
AutoCompleteTextView auto1 = (AutoCompleteTextView) findViewById(R.id.auto1);
String[] bookNames = getResources().getStringArray(R.array.arr);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, bookNames);
auto1.setAdapter(adapter);
}
}
public class MyAdapter extends BaseAdapter implements Filterable {
//所有的书
private List<BookEntity> mList;
//过滤后的书
private List<BookEntity> mFilterBooks;
private Context context;
private LayoutInflater inflater;
//书名拼音全拼的集合,
//假设有两本书,【水浒传,三国演义】,则List集合中有两项数据
//1.[shuihuzhuan,shuihuchuan,shuixuzhuan,shuixuchuan]
//2.[sanguoyanyi]
private List<Set<String>> bookNamePinYin;
//书名拼音简拼的集合
//假设有两本书,【水浒传,三国演义】,则List集合中有两项数据
//1.[shz,shc,sxz,sxc]
//2.[sgyy]
private List<Set<String>> bookNamePY;
//该书是否被加入到过滤结果的集合中
private boolean isNotAdd = true;
public MyAdapter(Context context, List<BookEntity> list) {
this.context = context;
mList = list;
inflater = LayoutInflater.from(context);
initPinYin();
}
private void initPinYin() {
bookNamePinYin = new ArrayList<>();
bookNamePY = new ArrayList<>();
PinYin4j pinYin4j = new PinYin4j();
for (BookEntity bookEntity : mList) {
bookNamePinYin.add(pinYin4j.getAllPinyin(bookEntity.getBook()));
bookNamePY.add(pinYin4j.getPinyin(bookEntity.getBook()));
}
// for (Set<String> strings : bookNamePinYin) {
// Log.d("google_lenve_fb", "initPinYin: " + strings);
// }
// for (Set<String> strings : bookNamePY) {
// Log.d("google_lenve_fb", "initPinYin: " + strings);
// }
}
@Override
public int getCount() {
return mList.size();
}
@Override
public Object getItem(int position) {
return mList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.lv_item, null);
holder = new ViewHolder();
holder.bookName = (TextView) convertView.findViewById(R.id.bookName);
holder.author = (TextView) convertView.findViewById(R.id.author);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
BookEntity bookEntity = mList.get(position);
holder.bookName.setText(bookEntity.getBook());
holder.author.setText(bookEntity.getAuthor());
return convertView;
}
@Override
public Filter getFilter() {
return new MyFilter();
}
class MyFilter extends Filter {
//当搜索条件发生改变时调用,即AutoCompleteTextView中的文本发生改变时调用
//参数constraint表示过滤条件,即AutoCompleteTextView中的文本
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults result = new FilterResults();
if (mFilterBooks == null) {
//将所有的书拷贝到mFilterBooks集合中
mFilterBooks = new ArrayList<>(mList);
}
// for (BookEntity filterBook : mFilterBooks) {
// Log.d("google_lenve_fb", "performFiltering: " + filterBook.toString());
// }
//如果没有过滤条件的话,则过滤结果为mFilterBooks
if (constraint == null || constraint.toString().length() == 0) {
result.values = mFilterBooks;
result.count = mFilterBooks.size();
//如果有过滤条件的话
} else {
//将搜索条件全部转为小写字母
String lowerCase = constraint.toString().toLowerCase();
//保存搜索结果
List<BookEntity> retList = new ArrayList<>();
BookEntity book;
//将所有的书过滤一遍,找出符合条件的书
for (int i = 0; i < mFilterBooks.size(); i++) {
isNotAdd = true;
book = mFilterBooks.get(i);
//如果搜索条件是中文的话
if (book.getBook().contains(lowerCase)) {
if (isNotAdd) {
//将符合条件的书添加到搜索结果集合中
retList.add(book);
isNotAdd = false;
}
//如果搜索条件是拼音的话
} else {
/**************************过滤书名拼音全拼*********************/
if (isNotAdd) {
//获取该书的拼音集合
Set<String> bnPinYin = bookNamePinYin.get(i);
//bnPinYin = [shuixuchuan, shuihuzhuan, shuihuchuan, shuixuzhuan]
Iterator<String> iterator = bnPinYin.iterator();
while (iterator.hasNext()) {
//获取到set集合中的每一项
String next = iterator.next();
if (next.contains(lowerCase)) {
retList.add(book);
isNotAdd = false;
break;
}
}
}
/****************************过滤书名拼音的简拼**********************************/
if (isNotAdd) {
Set<String> bnPY = bookNamePY.get(i);
//bnPY = [sxc, shc, sxz, shz]
Iterator<String> iterator1 = bnPY.iterator();
while (iterator1.hasNext()) {
if (iterator1.next().contains(lowerCase)) {
retList.add(book);
isNotAdd = false;
break;
}
}
}
/****************************过滤作者姓名拼音的全拼**********************************/
/****************************过滤作者姓名拼音的简拼**********************************/
/****************************过滤出版社名称拼音的简拼**********************************/
/****************************过滤出版社名称拼音的全拼**********************************/
}
}
result.values = retList;
result.count = retList.size();
}
return result;
}
//发布过滤结果
//参数result表示performFiltering方法返回的结果
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
mList = (List<BookEntity>) results.values;
if (mList.size() > 0) {
notifyDataSetChanged();
}
}
}
class ViewHolder {
TextView author, bookName;
}
}
public class PinYin4j {
public PinYin4j(){
}
/**
* 字符串集合转换字符串(逗号分隔)
*
* @author wangsong
* @param stringSet
* @return
*/
public String makeStringByStringSet(Set<String> stringSet) {
StringBuilder str = new StringBuilder();
int i = 0;
for (String s : stringSet) {
if (i == stringSet.size() - 1) {
str.append(s);
} else {
str.append(s + ",");
}
i++;
}
return str.toString().toLowerCase();
}
/**
* 获取汉字拼音全拼
*
* @author wangsong
* @param src
* @return Set<String>
*/
public Set<String> getAllPinyin(String src) {
char[] srcChar;
srcChar = src.toCharArray();
//1:多少个汉字
//2:每个汉字多少种读音
String[][] temp = new String[src.length()][];
for (int i = 0; i < srcChar.length; i++) {
char c = srcChar[i];
// 是中文或者a-z或者A-Z转换拼音(我的需求,是保留中文或者a-z或者A-Z)
if (String.valueOf(c).matches("[\\u4E00-\\u9FA5]+")) {
String[] t = PinyinHelper.getUnformattedHanyuPinyinStringArray(c);
temp[i] = new String[t.length];
for(int j=0;j<t.length;j++){
temp[i][j]=t[j].replaceAll("\\d", "");//获取全拼
}
} else if (((int) c >= 65 && (int) c <= 90)
|| ((int) c >= 97 && (int) c <= 122)||c>=48&&c<=57||c==42) {//a-zA-Z0-9*
temp[i] = new String[] { String.valueOf(srcChar[i]) };
} else {
temp[i] = new String[] {"null!"};
}
}
String[] pingyinArray = paiLie(temp);
return array2Set(pingyinArray);//为了去掉重复项
}
/**
* 获取汉字拼音首字母集合
*
* @author wangsong
* @param src
* @return Set<String>
*/
public Set<String> getPinyin(String src) {
char[] srcChar;
srcChar = src.toCharArray();
//1:多少个汉字
//2:每个汉字多少种读音
String[][] temp = new String[src.length()][];
for (int i = 0; i < srcChar.length; i++) {
char c = srcChar[i];
// 是中文或者a-z或者A-Z转换拼音(我的需求,是保留中文或者a-z或者A-Z)
if (String.valueOf(c).matches("[\\u4E00-\\u9FA5]+")) {
String[] t = PinyinHelper.getUnformattedHanyuPinyinStringArray(c);
temp[i] = new String[t.length];
for(int j=0;j<t.length;j++){
temp[i][j]=t[j].substring(0,1);//获取首字母
}
} else if (((int) c >= 65 && (int) c <= 90)
|| ((int) c >= 97 && (int) c <= 122)||c>=48&&c<=57||c==42) {//a-zA-Z0-9*
temp[i] = new String[] { String.valueOf(srcChar[i]) };
} else {
temp[i] = new String[] {"null!"};
}
}
String[] pingyinArray = paiLie(temp);
return array2Set(pingyinArray);//为了去掉重复项
}
/*
* 求2维数组所有排列组合情况
* 比如:{{1,2},{3},{4},{5,6}}共有2中排列,为:1345,1346,2345,2346
*/
private String[] paiLie(String[][] str){
int max=1;
for(int i=0;i<str.length;i++){
max*=str[i].length;
}
String[] result=new String[max];
for(int i = 0; i < max; i++){
String s = "";
int temp = 1; //注意这个temp的用法。
for(int j = 0; j < str.length; j++){
temp *= str[j].length;
s += str[j][i / (max / temp) % str[j].length];
}
result[i]=s;
}
return result;
}
public static <T extends Object> Set<T> array2Set(T[] tArray) {
Set<T> tSet = new HashSet<T>(Arrays.asList(tArray));
// TODO 没有一步到位的方法,根据具体的作用,选择合适的Set的子类来转换。
return tSet;
}
}