日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

android 自定义view仿通讯录

發布時間:2023/12/20 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android 自定义view仿通讯录 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

關于這篇文章 剛開始我心里也不知道從何下手,只能一步步來了。
看下實現效果:

先說下我的步驟:
步驟1:學會使用漢語轉拼音的第三方jar包; compile ‘com.belerweb:pinyin4j:2.5.0’
步驟2:自定義view實現右側字母表
步驟3:然后書寫普通的listview。(里面用到漢語轉拼音)
步驟4:關聯listview和右側的自定義view;

步驟1:
這個沒啥好說的,看下代碼吧;

package com.app.test.pinyinproject;import net.sourceforge.pinyin4j.PinyinHelper; import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType; import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat; import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;/*** Created by mengqiang on 2017/5/8.*/public class PinyinUtils {private static StringBuffer stringBuffer = new StringBuffer();/*** 返回漢語首個漢字的首字母,英文就返回首字母(小寫的)* 例如:你好→n* nihao→n*/public static String getPinyin(String infoString){stringBuffer.setLength(0);String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(infoString.toCharArray()[0]);if(pinyinArray != null){stringBuffer.append(pinyinArray[0].charAt(0));}else{stringBuffer.append(infoString.toCharArray()[0]);}return stringBuffer.toString();}/*** 返回漢語首個漢字的首字母,英文就返回首字母(大寫的)* 例如:你好→N* nihao→N*/public static String getUpPinyin(String infoString){stringBuffer.setLength(0);String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(infoString.toCharArray()[0]);if(pinyinArray != null){stringBuffer.append(pinyinArray[0].toUpperCase().charAt(0));}else{stringBuffer.append(infoString.toUpperCase().toCharArray()[0]);}return stringBuffer.toString();}/*** 獲取漢字字符串的首字母,英文字符不變* 例如:你好→nh* nihao→nihao*/public static String getPinYinHeadChar(String headString) {stringBuffer.setLength(0);char[] chars = headString.toCharArray();HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);for (int i = 0; i < chars.length; i++) {if (chars[i] > 128) {try {stringBuffer.append(PinyinHelper.toHanyuPinyinStringArray(chars[i], defaultFormat)[0].charAt(0));} catch (Exception e) {e.printStackTrace();}} else {stringBuffer.append(chars[0]);}}return stringBuffer.toString();}/*** 獲取漢字字符串的漢語拼音,英文字符不變* 例如:你好→nihao* nihao→nihao*/public static String getPinYinLine(String lineString) {stringBuffer.setLength(0);char[] nameChar = lineString.toCharArray();HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);for (int i = 0; i < nameChar.length; i++) {if (nameChar[i] > 128) {try {stringBuffer.append(PinyinHelper.toHanyuPinyinStringArray(nameChar[i], defaultFormat)[0]);} catch (Exception e) {e.printStackTrace();}} else {stringBuffer.append(nameChar[i]);}}return stringBuffer.toString();} }

步驟2:
(1)首先獲取自定義view的height和wigth,然后將height分為27份heightText(26字母 + “#”),然后用canvas.drawText寫出每一個字母。其中baselinbe的計算需要掌握。
(2)然后就是點擊view怎么獲取字母了。我們可以轉化一下,我們點擊view的時候獲取點擊的坐標(重寫onTouchEvent方法),然后根據坐標計算出應該是哪一個字母。在使用接口回調給activity;

上代碼:

package com.app.test.pinyinproject;import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View;/*** Created by mengqiang on 2017/5/8.*//*** 思路:先將height分為27個heightText,然后將分別將字母寫在自己的區域;* 設置點擊事件實際上就是重寫view內部的TouchEvent方法,然后根據TouchEvent的不同事件做出不同的反應。*/ public class PinyinView extends View {private Paint paint;private int height;private int wight;private float heightText;private OnItemClickListener onItemClickListener;private int color = Color.WHITE;public void setOnItemClickListener(OnItemClickListener onItemClickListener) {this.onItemClickListener = onItemClickListener;}private String[] pinyinArray= {"#","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"};public PinyinView(Context context) {super(context);initView();}public PinyinView(Context context, AttributeSet attrs) {super(context, attrs);initView();}public PinyinView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initView();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);height = getMeasuredHeight();wight = getMeasuredWidth();heightText = ((float)height/(float)27);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawColor(color);for(int i = 0;i < pinyinArray.length;i++){float x = wight/2 - paint.measureText(pinyinArray[i])/2;/*** 知識點:baseLine的計算*/Paint.FontMetrics fontMetrics = paint.getFontMetrics();float y = i * heightText + heightText/2 - (fontMetrics.top + fontMetrics.bottom)/2;canvas.drawText(pinyinArray[i],x,y,paint);}}@Overridepublic boolean onTouchEvent(MotionEvent event) {float coordinateY;switch (event.getAction()){case MotionEvent.ACTION_DOWN:{//點擊Down是顏色是graycolor = Color.GRAY;postInvalidate();//延伸知識點:1:invalidate()和postInvalidate()的區別 2:view的雙緩沖技術break;}case MotionEvent.ACTION_UP:{//UP的時候顏色是whitecoordinateY = event.getY();onItemClickListener.onItemListener(getChar(coordinateY));color = Color.WHITE;postInvalidate();break;}}return true;}/*** 定義接口,用于傳遞所點擊的字母*/interface OnItemClickListener{void onItemListener(String infoString);}/*** 計算coordinateY對應的字母* @param coordinateY 點擊的坐標* @return 返回coordinateY對應的字母*/public String getChar(float coordinateY){for(int i = 0;i < pinyinArray.length;i++){if(heightText * i > coordinateY){return pinyinArray[i - 1];}}return pinyinArray[26];}public void initView(){paint = new Paint();paint.setStyle(Paint.Style.FILL);paint.setColor(Color.BLUE);paint.setAntiAlias(true);paint.setTextSize(20);} }

步驟3:
其實步驟2也是需要多考慮一些東西,比如:我們是使用兩個adapter還是一個adapter,都能實現,再次我們是一個adapter;
我遇到問題一般是這樣解決的:首先它是有什么組成?然后拆分成小部分;最后組合一下。
在這里我們需要書寫adapter和adapter的數據(數據比較,降序排列)。
先說數據比較。我們需要創建一個User類用,

private String name;//名稱private String headChar;//首字母private String comparaChar;//第一個漢字的拼音全稱

然后根據User類的首個漢字的拼音進行比較。

private String[] name = new String[]{"潘粵明", "戴軍", "薛之謙", "藍雨", "任泉", "張杰", "秦俊杰","陳坤", "田亮", "夏雨", "保劍鋒", "陸毅", "喬振宇", "吉杰", "郭敬明", "巫迪文", "歡子", "井柏然","左小祖咒", "段奕宏", "毛寧", "樊凡", "湯潮", "山野", "陳龍", "侯勇", "俞思遠", "馮紹峰", "崔健","杜淳", "張翰", "彭坦", "柏栩栩", "蒲巴甲", "凌瀟肅", "毛方圓", "武藝", "耿樂", "錢泳辰","aaa","13","123654"};public void setListData(){for(int i = 0;i < name.length;i++){User user = new User();user.setName(name[i]);if(PinyinUtils.getUpPinyin(name[i]).matches("[A-Z]")){//首字母user.setHeadChar(PinyinUtils.getUpPinyin(name[i]));}else{user.setHeadChar(PinyinUtils.getUpPinyin("#"));}user.setComparaChar(PinyinUtils.getPinYinLine(name[i]));//比較 (此字段用于比較第一個漢字)list.add(user);}Collections.sort(list, new ComparaUser());// 第一個漢字進行拼音比較(降序);}

然后就是adapter的實現了。

package com.app.test.pinyinproject;import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView;import java.util.List;/*** Created by mengqiang on 2017/5/8.*/public class ListAdapter extends BaseAdapter {private List<User> userList ;private OnItemClickListener onItemClickListener;public OnItemClickListener getOnItemClickListener() {return onItemClickListener;}public void setOnItemClickListener(OnItemClickListener onItemClickListener) {this.onItemClickListener = onItemClickListener;}public ListAdapter(List<User> userList) {this.userList = userList;}@Overridepublic int getCount() {return userList.size();}@Overridepublic Object getItem(int position) {return userList.get(position);}@Overridepublic long getItemId(int position) {return 0;}@Overridepublic View getView(final int position, View convertView, ViewGroup parent) {ItemViewHolder itemViewHolder;if(convertView == null){convertView = View.inflate(parent.getContext(), R.layout.item_layout, null);itemViewHolder = new ItemViewHolder();itemViewHolder.charText = (TextView) convertView.findViewById(R.id.char_text);itemViewHolder.nameText = (TextView) convertView.findViewById(R.id.name_text);convertView.setTag(itemViewHolder);}else{itemViewHolder = (ItemViewHolder) convertView.getTag();}if(position == getPosition(position)){itemViewHolder.charText.setVisibility(View.VISIBLE);itemViewHolder.charText.setText(userList.get(position).getHeadChar());}else{itemViewHolder.charText.setVisibility(View.GONE);}itemViewHolder.nameText.setText(userList.get(position).getName());itemViewHolder.nameText.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {onItemClickListener.onItemCLick(position);}});return convertView;}/*** 計算出該luserist中position第一次對應的charAt下標i,然后判斷i是否等于position。* @param position* @return*/public int getPosition(int position){char charAt = userList.get(position).getHeadChar().charAt(0);for(int i = 0 ;i < userList.size();i++){if(charAt == userList.get(i).getHeadChar().charAt(0)){return i;}}return -1;}class ItemViewHolder{public TextView nameText;public TextView charText;}/*** 用于傳遞點擊了userlist哪一個item。*/interface OnItemClickListener{void onItemCLick(int position);} }

步驟4:
然后就是view和listview怎么關聯呢,根據view接口返回的infoString 獲取position,然后listview滑動到相應的位置

pinyinView.setOnItemClickListener(new PinyinView.OnItemClickListener() {@Overridepublic void onItemListener(String infoString) {/*** 點擊右側的字母表,listview滑動到相應的位置*/for(int i = 0;i < list.size();i++){if(infoString.equals(list.get(i).getHeadChar())){listview.setSelection(i);break;}}}});

感覺這都不難,重點是碰見一個問題之后怎么看待這個問題。

最后付上源碼下載地址:http://download.csdn.net/detail/lmq121210/9836455

總結

以上是生活随笔為你收集整理的android 自定义view仿通讯录的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。