android 自定义view仿通讯录
關于這篇文章 剛開始我心里也不知道從何下手,只能一步步來了。
看下實現效果:
先說下我的步驟:
步驟1:學會使用漢語轉拼音的第三方jar包; compile ‘com.belerweb:pinyin4j:2.5.0’
步驟2:自定義view實現右側字母表
步驟3:然后書寫普通的listview。(里面用到漢語轉拼音)
步驟4:關聯listview和右側的自定義view;
步驟1:
這個沒啥好說的,看下代碼吧;
步驟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類用,
然后根據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滑動到相應的位置
感覺這都不難,重點是碰見一個問題之后怎么看待這個問題。
最后付上源碼下載地址:http://download.csdn.net/detail/lmq121210/9836455
總結
以上是生活随笔為你收集整理的android 自定义view仿通讯录的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 服务器CPU经常跑高是什么原因
- 下一篇: MATLAB基础-矩阵输入