Android 實現漢字轉成拼音,實現ListView的A-Z字母排序,顯現多音字城市排序
今天給大家帶來ListView的A-Z字母排序和過濾搜尋功能並且實現漢字轉成拼音的功能,我們知道一般我們對聯絡人,城市列表等實現A-Z的排序,因為聯絡人和城市列表我們可以直接從資料庫中獲取他的漢字拼音,而對於一般的資料,我們怎麼實現A-Z的排序,我們需要將漢字轉換成拼音就行了,接下來就帶大家實現一般資料的A-Z排序功能,首先先看下效果圖
=========================================================================
本人專案需求右邊索引字母只顯示列表有資料的對應的字母,多音字城市排序(重慶、長沙排在C字母下面),效果圖
================================================================================
上面是一個帶刪除按鈕的EditText,我們在輸入框中輸入可以自動過濾出我們想要的東西,當輸入框中沒有資料自動替換到原來的資料列表,然後下面一個ListView用來顯示資料列表,右側是一個字母索引表,當我們點選不同的字母,ListView會定位到該字母地方,瞭解了佈局之後,我們先看下專案結構吧
我按照專案中類的順序來一一介紹其功能
1.SortModel 一個實體類,裡面一個是ListView的name,另一個就是顯示的name拼音的首字母
package com.example.sortlistview;
public class SortModel {
private String name; //顯示的資料
private String sortLetters; //顯示資料拼音的首字母
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSortLetters() {
return sortLetters;
}
public void setSortLetters(String sortLetters) {
this.sortLetters = sortLetters;
}
}
2.SideBar類就是ListView右側的字母索引View,我們需要使用setTextView(TextView mTextDialog)來設定用來顯示當前按下的字母的TextView,以及使用setOnTouchingLetterChangedListener方法來設定回撥介面,在回撥方法onTouchingLetterChanged(String s)中來處理不同的操作
package com.example.sortlistview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
public class SideBar extends View {
// 觸控事件
private OnTouchingLetterChangedListener onTouchingLetterChangedListener;
// 26個字母
public static String[] b = {"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 final int mNumber=26;//常規字母總數
private int choose = -1;// 選中
private Paint paint = new Paint();
private TextView mTextDialog;
private int textColor;
private int textSize;
private int textSelectorColor;
private int mHeightPixels;
public void setTextView(TextView mTextDialog) {
this.mTextDialog = mTextDialog;
}
public SideBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
getWindowInfo(context);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.SideBar);
textColor = a.getColor(R.styleable.SideBar_sbTextColor, Color.BLACK);
textSize = a.getDimensionPixelSize(R.styleable.SideBar_sbTextSize, 24);
textSelectorColor = a.getColor(R.styleable.SideBar_sbSelectedTextColor, Color.BLACK);
}
public SideBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
getWindowInfo(context);
}
public SideBar(Context context) {
super(context);
getWindowInfo(context);
}
/**
* 重寫這個方法
*/
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 獲取焦點改變背景顏色.
int height = getHeight();// 獲取對應高度
int width = getWidth(); // 獲取對應寬度
//int singleHeight = height / b.length;// 獲取每一個字母的高度
int singleHeight = height / mNumber;// 獲取每一個字母的高度
for (int i = 0; i < b.length; i++) {
paint.setColor(textColor);
// paint.setColor(Color.WHITE);
paint.setTypeface(Typeface.DEFAULT_BOLD);
paint.setAntiAlias(true);
paint.setTextSize(textSize);
// 選中的狀態
if (i == choose) {
paint.setColor(textSelectorColor);
paint.setFakeBoldText(true);
}
// x座標等於中間-字串寬度的一半.
float xPos = width / 2 - paint.measureText(b[i]) / 2;
//float yPos = singleHeight * i + singleHeight;
//(整個高度/2-字母的高度*字母的數量/2)+字母的高度*第幾個+字母高度
float yPos = (height/2-singleHeight*b.length/2)+singleHeight * i + singleHeight;//繪製相對於y座標的中間
canvas.drawText(b[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 oldChoose = choose;
final OnTouchingLetterChangedListener listener = onTouchingLetterChangedListener;
// final int c = (int) (y / getHeight() * b.length);// 點選y座標所佔總高度的比例*b陣列的長度就等於點選b中的個數.
int height = getHeight();// 獲取對應高度
int singleHeight = height / mNumber;// 獲取每一個字母的高度
// 整個螢幕畫素的一半 字母集合對應的畫素高度的一半
final int c = (int) ((y-mHeightPixels/2 + (mHeightPixels/mNumber*b.length/2)) / (singleHeight*b.length) * b.length);// 點選y座標所佔總高度的比例*b陣列的長度就等於點選b中的個數.
switch (action) {
case MotionEvent.ACTION_UP:
setBackgroundDrawable(new ColorDrawable(0x00000000));
choose = -1;//
invalidate();
if (mTextDialog != null) {
mTextDialog.setVisibility(View.INVISIBLE);
}
break;
default:
setBackgroundResource(R.drawable.sidebar_background);
if (oldChoose != c) {
if (c >= 0 && c < b.length) {
if (listener != null) {
listener.onTouchingLetterChanged(b[c]);
}
if (mTextDialog != null) {
mTextDialog.setText(b[c]);
mTextDialog.setVisibility(View.VISIBLE);
}
choose = c;
invalidate();
}
}
break;
}
return true;
}
/**
* 向外公開的方法
*
* @param onTouchingLetterChangedListener
*/
public void setOnTouchingLetterChangedListener(
OnTouchingLetterChangedListener onTouchingLetterChangedListener) {
this.onTouchingLetterChangedListener = onTouchingLetterChangedListener;
}
/**
* 介面
*
* @author coder
*/
public interface OnTouchingLetterChangedListener {
public void onTouchingLetterChanged(String s);
}
/**
* 設定有資料對應的字母索引,並重繪
* @param b
*/
public void setLetter(String[] b){
this.b=b;
requestLayout();
invalidate();
}
/**
* 獲取裝置的螢幕資訊
*
* @return
*/
private void getWindowInfo(Context context) {
// DisplayMetrics類用於螢幕的描述資訊
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
// 獲取螢幕畫素高度 px
int height = displayMetrics.heightPixels;
//獲取狀態列高度
int result = 0;
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = context.getResources().getDimensionPixelSize(resourceId);
}
mHeightPixels=height-result-dip2px(context,48);//控制元件的高度=螢幕高度-狀態列高度-導航欄高度
}
/**
* 根據手機的解析度從 dp 的單位 轉成為 px(畫素)
*/
private static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
}
3.CharacterParser 這個類是將漢字轉換成拼音的類,該拼音沒有聲調的,該類是單例類,其中定義了三個方法,在這個demo中用到的是getSelling(String chs)方法,將片語轉換成拼音
package com.example.sortlistview;
/**
* Java漢字轉換為拼音
*
*/
public class CharacterParser {
private static int[] pyvalue = new int[] {-20319, -20317, -20304, -20295, -20292, -20283, -20265, -20257, -20242, -20230, -20051, -20036, -20032,
-20026, -20002, -19990, -19986, -19982, -19976, -19805, -19784, -19775, -19774, -19763, -19756, -19751, -19746, -19741, -19739, -19728,
-19725, -19715, -19540, -19531, -19525, -19515, -19500, -19484, -19479, -19467, -19289, -19288, -19281, -19275, -19270, -19263, -19261,
-19249, -19243, -19242, -19238, -19235, -19227, -19224, -19218, -19212, -19038, -19023, -19018, -19006, -19003, -18996, -18977, -18961,
-18952, -18783, -18774, -18773, -18763, -18756, -18741, -18735, -18731, -18722, -18710, -18697, -18696, -18526, -18518, -18501, -18490,
-18478, -18463, -18448, -18447, -18446, -18239, -18237, -18231, -18220, -18211, -18201, -18184, -18183, -18181, -18012, -17997, -17988,
-17970, -17964, -17961, -17950, -17947, -17931, -17928, -17922, -17759, -17752, -17733, -17730, -17721, -17703, -17701, -17697, -17692,
-17683, -17676, -17496, -17487, -17482, -17468, -17454, -17433, -17427, -17417, -17202, -17185, -16983, -16970, -16942, -16915, -16733,
-16708, -16706, -16689, -16664, -16657, -16647, -16474, -16470, -16465, -16459, -16452, -16448, -16433, -16429, -16427, -16423, -16419,
-16412, -16407, -16403, -16401, -16393, -16220, -16216, -16212, -16205, -16202, -16187, -16180, -16171, -16169, -16158, -16155, -15959,
-15958, -15944, -15933, -15920, -15915, -15903, -15889, -15878, -15707, -15701, -15681, -15667, -15661, -15659, -15652, -15640, -15631,
-15625, -15454, -15448, -15436, -15435, -15419, -15416, -15408, -15394, -15385, -15377, -15375, -15369, -15363, -15362, -15183, -15180,
-15165, -15158, -15153, -15150, -15149, -15144, -15143, -15141, -15140, -15139, -15128, -15121, -15119, -15117, -15110,