Android 通訊錄索引效果

通訊錄索引效果,網(wǎng)上很多了,我這里做個(gè)記錄。
效果預(yù)覽
SideBar此類自定義索引的字母
public?class?SideBar?extends?View?{
????//?觸摸事件
????private?OnTouchingLetterChangedListener?onTouchingLetterChangedListener;
????//?26個(gè)字母
????public?static?String[]?A_Z?=?{"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?choose?=?-1;//?選中
????private?Paint?paint?=?new?Paint();
????private?TextView?mTextDialog;
????/**
?????*?為SideBar設(shè)置顯示字母的TextView
?????*
?????*?@param?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);
????}
????/**
?????*?重寫這個(gè)方法
?????*/
????protected?void?onDraw(Canvas?canvas)?{
????????super.onDraw(canvas);
????????//?獲取焦點(diǎn)改變背景顏色.
????????int?height?=?getHeight();//?獲取對(duì)應(yīng)高度
????????int?width?=?getWidth();?//?獲取對(duì)應(yīng)寬度
????????int?singleHeight?=?height?/?A_Z.length?-?2;//?獲取每一個(gè)字母的高度??(這里-2僅僅是為了好看而已)
????????for?(int?i?=?0;?i?????????????paint.setColor(Color.rgb(33,?65,?98));??//設(shè)置字體顏色
????????????paint.setTypeface(Typeface.DEFAULT_BOLD);??//設(shè)置字體
????????????paint.setAntiAlias(true);??//設(shè)置抗鋸齒
????????????paint.setTextSize(30);??//設(shè)置字母字體大小
????????????//?選中的狀態(tài)
????????????if?(i?==?choose)?{
????????????????paint.setColor(Color.parseColor("#3399ff"));??//選中的字母改變顏色
????????????????paint.setFakeBoldText(true);??//設(shè)置字體為粗體
????????????}
????????????//?x坐標(biāo)等于中間-字符串寬度的一半.
????????????float?xPos?=?width?/?2?-?paint.measureText(A_Z[i])?/?2;
????????????float?yPos?=?singleHeight?*?i?+?singleHeight;
????????????canvas.drawText(A_Z[i],?xPos,?yPos,?paint);??//繪制所有的字母
????????????paint.reset();//?重置畫筆
????????}
????}
????@Override
????public?boolean?dispatchTouchEvent(MotionEvent?event)?{
????????final?int?action?=?event.getAction();
????????final?float?y?=?event.getY();//?點(diǎn)擊y坐標(biāo)
????????final?int?oldChoose?=?choose;
????????final?OnTouchingLetterChangedListener?listener?=?onTouchingLetterChangedListener;
????????final?int?c?=?(int)?(y?/?getHeight()?*?A_Z.length);//?點(diǎn)擊y坐標(biāo)所占總高度的比例*b數(shù)組的長(zhǎng)度就等于點(diǎn)擊b中的個(gè)數(shù).
????????switch?(action)?{
????????????case?MotionEvent.ACTION_UP:
????????????????setBackgroundDrawable(new?ColorDrawable(0x00000000));
????????????????choose?=?-1;//
????????????????invalidate();
????????????????if?(mTextDialog?!=?null)?{
????????????????????mTextDialog.setVisibility(View.INVISIBLE);
????????????????}
????????????????break;
????????????default:
????????????????setBackgroundResource(R.color.colorPrimary);
????????????????if?(oldChoose?!=?c)?{??//判斷選中字母是否發(fā)生改變
????????????????????if?(c?>=?0?&&?c?????????????????????????if?(listener?!=?null)?{
????????????????????????????listener.onTouchingLetterChanged(A_Z[c]);
????????????????????????}
????????????????????????if?(mTextDialog?!=?null)?{
????????????????????????????mTextDialog.setText(A_Z[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);
????}
}
xml 調(diào)用? ????????android:layout_width="match_parent"
????????android:layout_height="match_parent">
????????<android.support.v7.widget.RecyclerView
????????????android:id="@+id/mRecyclerView"
????????????android:layout_width="match_parent"
????????????android:layout_height="match_parent"?/>
????????<TextView
????????????android:id="@+id/textDialog"
????????????android:layout_width="80dip"
????????????android:layout_height="80dip"
????????????android:layout_centerInParent="true"
????????????android:layout_gravity="center"
????????????android:gravity="center"
????????????android:textColor="#ffffffff"
????????????android:background="@color/colorPrimary"
????????????android:textSize="30.0dip"
????????????android:visibility="invisible"?/>
????????<你的包名.SideBar
????????????android:id="@+id/sidebar"
????????????android:layout_width="20dip"
????????????android:layout_height="wrap_content"
????????????android:layout_alignParentRight="true"?/>
????RelativeLayout>
ContactActivitypublic?class?ContactActivity?extends?BaseActivity?{
????@Bind(R.id.mRecyclerView)
????RecyclerView?mRecyclerView;
????@Bind(R.id.sidebar)
????SideBar?sidebar;
????@Bind(R.id.textDialog)
????TextView?textDialog;
????private?List?data;
????ContactAdapter?mContactAdapter;
????@Override
????protected?void?onCreate(Bundle?savedInstanceState)?{
????????super.onCreate(savedInstanceState);
????????setContentView(R.layout.activity_contact);
????????sidebar.setTextView(textDialog);
????????//?設(shè)置字母導(dǎo)航觸摸監(jiān)聽
????????sidebar.setOnTouchingLetterChangedListener(new?SideBar.OnTouchingLetterChangedListener()?{
????????????@Override
????????????public?void?onTouchingLetterChanged(String?s)?{
????????????????//?TODO?Auto-generated?method?stub
????????????????//?該字母首次出現(xiàn)的位置
????????????????int?position?=?mContactAdapter.getPositionForSelection(s.charAt(0));
????????????????if?(position?!=?-1)?{
????????????????????mRecyclerView.getLayoutManager().scrollToPosition(position);
????????????????}
????????????}
????????});
????????data?=?getData(getResources().getStringArray(R.array.listpersons));
????????//?數(shù)據(jù)在放在adapter之前需要排序
????????Collections.sort(data,?new?PinyinComparator());
????????for?(int?i?=?0;?i?????????????Log.i("wxl",?"Fpinyin="?+?data.get(i).getFirstPinYin());
????????}
????????LinearLayoutManager?linearLayoutManager?=?new?LinearLayoutManager(this);
????????linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
????????mRecyclerView.setLayoutManager(linearLayoutManager);
????????mContactAdapter?=?new?ContactAdapter(data);
????????mRecyclerView.setAdapter(mContactAdapter);
????}
????private?List?getData(String[]?data)? {
????????List?listarray?=?new?ArrayList();
????????for?(int?i?=?0;?i?????????????String?pinyin?=?PinyinUtils.getPingYin(data[i]);
????????????String?Fpinyin?=?pinyin.substring(0,?1).toUpperCase();
????????????PersonBean?person?=?new?PersonBean();
????????????person.setName(data[i]);
????????????person.setPinYin(pinyin);
????????????//?正則表達(dá)式,判斷首字母是否是英文字母
????????????if?(Fpinyin.matches("[A-Z]"))?{
????????????????person.setFirstPinYin(Fpinyin);
????????????}?else?{
????????????????person.setFirstPinYin("#");
????????????}
????????????listarray.add(person);
????????}
????????return?listarray;
????}
}
persons.xml模擬數(shù)據(jù)
"1.0"?encoding="utf-8"?>
<resources>
????<string-array?name="listpersons">
????????<item>?馬云item>
????????<item>?馬化騰item>
????????<item>?佩蘭item>
????????<item>?奧巴馬item>
????????<item>?普京item>
????????<item>?金三胖item>
????????<item>?暗影軍團(tuán)item>
????????<item>?141特遣隊(duì)item>
????????<item>?沖鋒號(hào)item>
????????<item>?+勝利號(hào)item>
????????<item>?超級(jí)賽亞人item>
????????<item>?金克拉item>
????????<item>?亞古獸item>
????????<item>?數(shù)碼寶貝大冒險(xiǎn)item>
????????<item>?大勝歸來item>
????????<item>?道士下山item>
????????<item>?A利亞克item>
????????<item>?勝利沖鋒龍卷風(fēng)item>
????????<item>?走在冷風(fēng)中item>
????????<item>?外面的世界item>
????????<item>?煩惱歌item>
????????<item>?如果沒有你item>
????????<item>?四季歌item>
????????<item>?南山南item>
????????<item>?+勝利號(hào)item>
????????<item>?光能使者item>
????????<item>?鐵甲小寶item>
????????<item>?皮卡丘item>
????????<item>?奧特曼item>
????????<item>?開普勒452bitem>
????????<item>?神舟20號(hào)item>
????????<item>?屌炸天的結(jié)尾item>
????string-array>
resources>
PersonBeanpublic?class?PersonBean?{
????private?String?Name;
????private?String?PinYin;
????private?String?FirstPinYin;
????public?String?getName()?{
????????return?Name;
????}
????public?void?setName(String?name)?{
????????Name?=?name;
????}
????public?String?getPinYin()?{
????????return?PinYin;
????}
????public?void?setPinYin(String?pinYin)?{
????????PinYin?=?pinYin;
????}
????public?String?getFirstPinYin()?{
????????return?FirstPinYin;
????}
????public?void?setFirstPinYin(String?firstPinYin)?{
????????FirstPinYin?=?firstPinYin;
????}
????public?String?toString()?{
????????return?"姓名:"?+?getName()?+?"???拼音:"?+?getPinYin()?+?"????首字母:"
????????????????+?getFirstPinYin();
????}
}
PinyinUtils這里需要 pinyin4j 包,下載地址:http://pinyin4j.sourceforge.net/
public?class?PinyinUtils?{
????/**
?????*?漢字轉(zhuǎn)拼音
?????*/
????public?static?String?getPingYin(String?inputString)?{
????????HanyuPinyinOutputFormat?format?=?new?HanyuPinyinOutputFormat();
????????format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
????????format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
????????format.setVCharType(HanyuPinyinVCharType.WITH_V);
????????char[]?input?=?inputString.trim().toCharArray();
????????String?output?=?"";
????????try?{
????????????for?(char?curchar?:?input)?{
????????????????if?(java.lang.Character.toString(curchar).matches("[\\u4E00-\\u9FA5]+"))?{
????????????????????String[]?temp?=?PinyinHelper.toHanyuPinyinStringArray(curchar,?format);
????????????????????output?+=?temp[0];
????????????????}?else
????????????????????output?+=?java.lang.Character.toString(curchar);
????????????}
????????}?catch?(BadHanyuPinyinOutputFormatCombination?e)?{
????????????e.printStackTrace();
????????}
????????return?output;
????}
}
PinyinComparator按照字母排序類
public?class?PinyinComparator?implements?Comparator<PersonBean>?{
????@Override
????public?int?compare(PersonBean?lhs,?PersonBean?rhs)?{
????????return?sort(lhs,?rhs);
????}
????private?int?sort(PersonBean?lhs,?PersonBean?rhs)?{
????????//?獲取ascii值
????????int?lhs_ascii?=?lhs.getFirstPinYin().toUpperCase().charAt(0);
????????int?rhs_ascii?=?rhs.getFirstPinYin().toUpperCase().charAt(0);
????????//?判斷若不是字母,則排在字母之后
????????if?(lhs_ascii?65?||?lhs_ascii?>?90)
????????????return?1;
????????else?if?(rhs_ascii?65?||?rhs_ascii?>?90)
????????????return?-1;
????????else
????????????return?lhs.getPinYin().compareTo(rhs.getPinYin());
????}
}
ContactAdapterpublic?class?ContactAdapter?extends?RecyclerView.Adapter<ContactAdapter.ViewHolder>?{
????List?data;
????public?ContactAdapter(List?data) ?{
????????this.data?=?data;
????}
????class?ViewHolder?extends?RecyclerView.ViewHolder?{
????????TextView?nickname;
????????TextView?tag;
????????public?ViewHolder(View?itemView)?{
????????????super(itemView);
????????????nickname?=?(TextView)?itemView.findViewById(R.id.nickname);
????????????tag?=?(TextView)?itemView.findViewById(R.id.tag);
????????}
????}
????@Override
????public?ViewHolder?onCreateViewHolder(ViewGroup?parent,?int?viewType)?{
????????View?view?=?View.inflate(parent.getContext(),?R.layout.contact_item,?null);
????????return?new?ViewHolder(view);
????}
????@Override
????public?void?onBindViewHolder(ViewHolder?holder,?int?position)?{
????????PersonBean?person?=?data.get(position);
????????//?獲取首字母的assii值
????????int?selection?=?person.getFirstPinYin().charAt(0);
????????//?通過首字母的assii值來判斷是否顯示字母
????????int?positionForSelection?=?getPositionForSelection(selection);
????????if?(position?==?positionForSelection)?{//?相等說明需要顯示字母
????????????holder.tag.setVisibility(View.VISIBLE);
????????????holder.tag.setText(person.getFirstPinYin());
????????}?else?{
????????????holder.tag.setVisibility(View.GONE);
????????}
????????holder.nickname.setText(data.get(position).getName());
????}
????public?int?getPositionForSelection(int?selection)?{
????????for?(int?i?=?0;?i?????????????String?Fpinyin?=?data.get(i).getFirstPinYin();
????????????char?first?=?Fpinyin.toUpperCase().charAt(0);
????????????if?(first?==?selection)?{
????????????????return?i;
????????????}
????????}
????????return?-1;
????}
????@Override
????public?int?getItemCount()?{
????????return?data.size();
????}
}
contact_item.xml
<LinearLayout?xmlns:android="http://schemas.android.com/apk/res/android"
????android:layout_width="match_parent"
????android:layout_height="match_parent"
????android:orientation="vertical">
????
????<TextView
????????android:id="@+id/tag"
????????android:layout_width="match_parent"
????????android:layout_height="20dp"
????????android:background="#e6e6e6"
????????android:gravity="center_vertical"
????????android:paddingLeft="10dip"
????????android:text="Z"
????????android:visibility="visible"?/>
????<RelativeLayout
????????android:layout_width="match_parent"
????????android:layout_height="wrap_content">
????????<View
????????????android:id="@+id/view_lv_item_line"
????????????android:layout_width="match_parent"
????????????android:layout_height="0.5dip"
????????????android:layout_marginLeft="10dip"
????????????android:layout_marginRight="20dip"
????????????android:background="#174465"?/>
????????<ImageView
????????????android:id="@+id/iv_lv_item_head"
????????????android:layout_width="wrap_content"
????????????android:layout_height="wrap_content"
????????????android:layout_below="@id/view_lv_item_line"
????????????android:layout_marginLeft="5dp"
????????????android:src="@mipmap/ic_launcher"?/>
????????<TextView
????????????android:id="@+id/nickname"
????????????android:layout_width="wrap_content"
????????????android:layout_height="wrap_content"
????????????android:layout_centerVertical="true"
????????????android:layout_marginLeft="5dip"
????????????android:layout_toRightOf="@id/iv_lv_item_head"
????????????android:text="周華健"?/>
????RelativeLayout>
LinearLayout>
-?End -
評(píng)論
圖片
表情
