android ListView根據(jù)字母排序和定位

示例圖

1悔详,右邊的檢索SideBar

源碼:

public class SideBarextends View {

private char[]l;

? ? private SectionIndexersectionIndexter =null;

? ? private ListViewlist;

? ? private TextViewmDialogText;

? ? Bitmapmbitmap;

? ? private int type =1;

? ? private int color =0xff858c94;

? ? public SideBar(Context context) {

super(context);

? ? ? ? init();

? ? }

public SideBar(Context context, AttributeSet attrs) {

super(context, attrs);

? ? ? ? init();

? ? }

private void init() {

l =new char[] {'!','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','#'};

? ? ? ? mbitmap = BitmapFactory.decodeResource(getResources(),

? ? ? ? ? ? ? ? R.drawable.scroll_bar_search_icon);

? ? }

public SideBar(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

? ? ? ? init();

? ? }

public void setListView(ListView _list) {

list = _list;

? ? ? ? ChooseCityAdapter ad = (ChooseCityAdapter) _list.getAdapter(); //listview適配器

? ? ? ? sectionIndexter = ad;

? ? }

public void setTextView(TextView mDialogText) {

this.mDialogText = mDialogText;

? ? }

@Override

? ? public boolean onTouchEvent(MotionEvent event) {

super.onTouchEvent(event);

? ? ? ? int i = (int) event.getY();

? ? ? ? int idx = i / (getMeasuredHeight() /l.length);

? ? ? ? if (idx >=l.length) {

idx =l.length -1;

? ? ? ? }else if (idx <0) {

idx =0;

? ? ? ? }

if (event.getAction() == MotionEvent.ACTION_DOWN

? ? ? ? ? ? ? ? || event.getAction() == MotionEvent.ACTION_MOVE) {

setBackgroundResource(R.drawable.scrollbar_bg);

? ? ? ? ? ? mDialogText.setVisibility(View.VISIBLE);

? ? ? ? ? ? if (idx ==0) {

mDialogText.setText("Search");

? ? ? ? ? ? ? ? mDialogText.setTextSize(16);

? ? ? ? ? ? }else {

mDialogText.setText(String.valueOf(l[idx]));

? ? ? ? ? ? ? ? mDialogText.setTextSize(34);

? ? ? ? ? ? }

if (sectionIndexter ==null) {

sectionIndexter = (SectionIndexer)list.getAdapter();

? ? ? ? ? ? }

int position =sectionIndexter.getPositionForSection(l[idx]);

? ? ? ? ? ? if (position == -1) {

return true;

? ? ? ? ? ? }

list.setSelection(position);

? ? ? ? }else {

mDialogText.setVisibility(View.INVISIBLE);

? ? ? ? }

if (event.getAction() == MotionEvent.ACTION_UP) {

setBackgroundDrawable(new ColorDrawable(0x00000000));

? ? ? ? }

return true;

? ? }

@Override

? ? protected void onDraw(Canvas canvas) {

Paint paint =new Paint();

? ? ? ? paint.setColor(color);

? ? ? ? paint.setTextSize(24);

? ? ? ? paint.setStyle(Paint.Style.FILL);

? ? ? ? paint.setTextAlign(Paint.Align.CENTER);

? ? ? ? float widthCenter = getMeasuredWidth() /2;

? ? ? ? if (l.length >0) {

float height = getMeasuredHeight() /l.length;

? ? ? ? ? ? for (int i =0; i

if (i ==0 &&type !=2) {

canvas.drawBitmap(mbitmap, widthCenter -7, (i +1)

* height - height /2, paint);

? ? ? ? ? ? ? ? }else

? ? ? ? ? ? ? ? ? ? canvas.drawText(String.valueOf(l[i]), widthCenter,

? ? ? ? ? ? ? ? ? ? ? ? ? ? (i +1) * height, paint);

? ? ? ? ? ? }

}

this.invalidate();

? ? ? ? super.onDraw(canvas);

? ? }

}

2佩憾,適配器的更改

適配器實(shí)現(xiàn)SectionIndexer接口救斑,實(shí)現(xiàn)它的方法

@Override

public Object[]getSections() {

return new Object[0];

}

public int getSectionForPosition(int position) {

String letter = FirstLetterUtil.getFirstLetter(lists.get(position).getName()).toUpperCase();

? return letter.charAt(0);

}

public int getPositionForSection(int section) {

for (int i =0; i < getCount(); i++) {

String letter = FirstLetterUtil.getFirstLetter(lists.get(i).getName()).toUpperCase();

? ? ? char firstChar = letter.toUpperCase().charAt(0);

? ? ? if (firstChar == section) {

return i;

? ? ? }

}

return -1;

}

3,關(guān)聯(lián)listview與SideBar

sideBar.setListView(lv_listview);

sideBar.setTextView(tv_textview);

4.其他

1岸霹,獲取漢字名稱首字母

public class FirstLetterUtil {

????private static int BEGIN =45217;

? ? private static int END =63486;

? ? // 按照聲母表示栖忠,這個(gè)表是在GB2312中的出現(xiàn)的第一個(gè)漢字蝌戒,也就是說(shuō)“啊”是代表首字母a的第一個(gè)漢字召烂。

? ? // i, u, v都不做聲母, 自定規(guī)則跟隨前面的字母

? ? private static char[]chartable = {'啊', '芭', '擦', '搭', '蛾', '發(fā)', '噶', '哈',

? ? ? ? ? ? '哈', '擊', '喀', '垃', '媽', '拿', '哦', '啪', '期', '然', '撒', '塌', '塌',

? ? ? ? ? ? '塌', '挖', '昔', '壓', '匝', };

? ? // 二十六個(gè)字母區(qū)間對(duì)應(yīng)二十七個(gè)端點(diǎn)

? ? // GB2312碼漢字區(qū)間十進(jìn)制表示

? ? private static int[]table =new int[27];

? ? // 對(duì)應(yīng)首字母區(qū)間表

? ? private static char[]initialtable = {'a', 'b', 'c', 'd', 'e', 'f', 'g',

? ? ? ? ? ? 'h', 'h', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',

? ? ? ? ? ? 't', 't', 'w', 'x', 'y', 'z', };

? ? // 初始化

? ? static {

????????for (int i =0; i <26; i++) {

????????????table[i] =gbValue(chartable[i]);// 得到GB2312碼的首字母區(qū)間端點(diǎn)表碱工,十進(jìn)制。

? ? ? ? }

????????table[26] =END;// 區(qū)間表結(jié)尾

? ? }

/**

? ? * 根據(jù)一個(gè)包含漢字的字符串返回一個(gè)漢字拼音首字母的字符串 最重要的一個(gè)方法奏夫,思路如下:一個(gè)個(gè)字符讀入怕篷、判斷、輸出

? ? */

? ? public static StringgetFirstLetter(String sourceStr) {

????????String result ="";

? ? ? ? String str = sourceStr.toLowerCase();

? ? ? ? int StrLength = str.length();

? ? ? ? int i;

? ? ? ? try {

????????????for (i =0; i < StrLength; i++) {

????????????????result +=Char2Initial(str.charAt(i));

? ? ? ? ? ? }

????????}catch (Exception e) {

????????????result ="";

? ? ? ? }

????return result;

? ? }

/**

? ? * 輸入字符,得到他的聲母,英文字母返回對(duì)應(yīng)的大寫字母,其他非簡(jiǎn)體漢字返回 '0'

*/

? ? private static char Char2Initial(char ch) {

// 對(duì)英文字母的處理:小寫字母轉(zhuǎn)換為大寫酗昼,大寫的直接返回

? ? ? ? if (ch >='a' && ch <='z') {

????????????return ch;

? ? ? ? }

????????if (ch >='A' && ch <='Z') {

????????????return ch;

? ? ? ? }

// 對(duì)非英文字母的處理:轉(zhuǎn)化為首字母廊谓,然后判斷是否在碼表范圍內(nèi),

? ? ? ? // 若不是麻削,則直接返回蒸痹。

? ? ? ? // 若是,則在碼表內(nèi)的進(jìn)行判斷碟婆。

? ? ? ? int gb =gbValue(ch);// 漢字轉(zhuǎn)換首字母

? ? ? ? if ((gb END))// 在碼表區(qū)間之前电抚,直接返回

? ? ? ? {

????????????return ch;

? ? ? ? }

????????int i;

? ? ? ? for (i =0; i <26; i++) {// 判斷匹配碼表區(qū)間,匹配到就break,判斷區(qū)間形如“[,)”

? ? ? ? ? ? if ((gb >=table[i]) && (gb

????????????????break;

? ? ? ? ? ? }

????????}

????????if (gb ==END) {// 補(bǔ)上GB2312區(qū)間最右端

? ? ? ? ? ? i =25;

? ? ? ? }

????????return initialtable[i]; // 在碼表區(qū)間中竖共,返回首字母

? ? }

/**

? ? * 取出漢字的編碼 cn 漢字

? ? */

? ? private static int gbValue(char ch) {// 將一個(gè)漢字(GB2312)轉(zhuǎn)換為十進(jìn)制表示。

? ? ? ? String str =new String();

? ? ? ? str += ch;

? ? ? ? try {

????????????byte[] bytes = str.getBytes("GB2312");

? ? ? ? ? ? if (bytes.length <2) {

????????????????return 0;

? ? ? ? ? ? }

????????????return (bytes[0] <<8 &0xff00) + (bytes[1] &0xff);

? ? ? ? }catch (Exception e) {

????????????return 0;

? ? ? ? }

}

}

2俺祠,listview數(shù)據(jù)排序

Collections.sort(cityLists, new Comparator() {

@Override

? ? public int compare(CityBean lhs, CityBean rhs) {

????????String letter1 = FirstLetterUtil.getFirstLetter(lhs.getName()).toUpperCase();

? ? ? ? String letter2 = FirstLetterUtil.getFirstLetter(rhs.getName()).toUpperCase();

? ? ? ? //這里主要是用來(lái)對(duì)ListView里面的數(shù)據(jù)根據(jù)ABCDEFG...來(lái)排序

? ? ? ? if (letter1.equals("@") || letter2.equals("#")) {

????????????return -1;

? ? ? ? }else if (letter1.equals("#")????|| letter2.equals("@")) {

????????????return 1;

? ? ? ? }else {

? ? ? ? ? ? ? ?return letter1.compareTo(letter2);

? ? ? ? }

}

});

3公给,適配器字母控件的顯示隱藏

String currentStr = FirstLetterUtil.getFirstLetter(cityBean.getName()).toUpperCase().substring(0,1);

String index =null;

if (position ==0) {

index = currentStr;

}else {

String lastStr = FirstLetterUtil.getFirstLetter(lists.get(position -1).getName()).toUpperCase().substring(0,1);

? if (!TextUtils.equals(lastStr,currentStr)) {

index = currentStr;

? }

}

viewHolder.tv_letter.setText(currentStr);

//首字母相同的姓氏只顯示第一個(gè)名字上面的首字母,其他的隱藏掉

viewHolder.tv_letter.setVisibility(index ==null ? View.GONE : View.VISIBLE);

**********************END*********************


我是靜染星辰,私人微信:azxy986753

歡迎添加微信蜘渣,互相學(xué)習(xí)淌铐,互相進(jìn)步!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蔫缸,一起剝皮案震驚了整個(gè)濱河市腿准,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌拾碌,老刑警劉巖吐葱,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異校翔,居然都是意外死亡弟跑,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門防症,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)孟辑,“玉大人哎甲,你說(shuō)我怎么就攤上這事∷撬裕” “怎么了炭玫?”我有些...
    開封第一講書人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)貌虾。 經(jīng)常有香客問(wèn)我吞加,道長(zhǎng),這世上最難降的妖魔是什么酝惧? 我笑而不...
    開封第一講書人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任榴鼎,我火速辦了婚禮,結(jié)果婚禮上晚唇,老公的妹妹穿的比我還像新娘巫财。我一直安慰自己,他們只是感情好哩陕,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開白布平项。 她就那樣靜靜地躺著,像睡著了一般悍及。 火紅的嫁衣襯著肌膚如雪闽瓢。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,255評(píng)論 1 308
  • 那天心赶,我揣著相機(jī)與錄音揭蜒,去河邊找鬼。 笑死中姜,一個(gè)胖子當(dāng)著我的面吹牛剪勿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播耻姥,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼销钝,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了琐簇?” 一聲冷哼從身側(cè)響起蒸健,我...
    開封第一講書人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎婉商,沒(méi)想到半個(gè)月后似忧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡据某,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年橡娄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片癣籽。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡挽唉,死狀恐怖滤祖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情瓶籽,我是刑警寧澤匠童,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站塑顺,受9級(jí)特大地震影響汤求,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜严拒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一扬绪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧裤唠,春花似錦挤牛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至航瞭,卻和暖如春诫硕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背刊侯。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工章办, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人滨彻。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓纲菌,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親疮绷。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容