您的位置:首页 > 移动开发 > 微信开发

android高仿微信联系人选择

2016-01-09 16:38 671 查看




















如题,仿造微信联系人选择。



实现起来也是相当的简单。



ChineseToEnglish为网上找的中文转拼音的类,

CompareSort是实现联系人list的排序类

SideBarView右侧的字母条

User UserAdapter 测试数据类

主要看下SideBarView

package com.jadyn.contactslist.contact;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import com.jadyn.contactslist.R;

/**
* Created by Administrator on 2016/1/8.
*/
public class SideBarView extends View{
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 int selectPos = -1;

private final int defaultNormalColor = Color.TRANSPARENT;
private final int defaultPressColor = Color.parseColor("#1F000000");
private final int defaultTextSize = 30;
private final int defaultNorTextColor = Color.parseColor("#cc181818");
private final int defaultPressTextColor = Color.parseColor("#ff000000");

private int sideBarBgNorColor;
private int sideBarBgPressColor;
private int sideBarTextSize;
private int sideBarNorTextColor;
private int sideBarPressTextColor;

public SideBarView(Context context) {
this(context, null);
}

public SideBarView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
init();
}

public SideBarView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SideBarView, defStyleAttr, 0);
sideBarBgNorColor = typedArray.getColor(R.styleable.SideBarView_sidebar_nor_background,defaultNormalColor);
sideBarBgPressColor = typedArray.getColor(R.styleable.SideBarView_sidebar_press_background,defaultPressColor);
sideBarTextSize = typedArray.getInt(R.styleable.SideBarView_sidebar_text_size, defaultTextSize);
sideBarNorTextColor = typedArray.getColor(R.styleable.SideBarView_sidebar_text_color_nor, defaultNorTextColor);
sideBarPressTextColor = typedArray.getColor(R.styleable.SideBarView_sidebar_text_color_press, defaultPressTextColor);

typedArray.recycle();

init();
}

Paint paint;
Paint paintSelect;
private void init() {
paint= new Paint() ;
paint.setAntiAlias(true);
paint.setColor(sideBarNorTextColor);
paint.setTypeface(Typeface.DEFAULT_BOLD);
paint.setTextSize(sideBarTextSize);
paintSelect= new Paint() ;
paintSelect.setAntiAlias(true);
paintSelect.setTypeface(Typeface.DEFAULT_BOLD);
paintSelect.setTextSize(sideBarTextSize);
paintSelect.setColor(sideBarPressTextColor);

}
int height;
int width;
int perHeight;

@Override
public boolean onTouchEvent(MotionEvent event) {

float x = event.getY();
//计算点击位置所在的position
int position = (int) (x / perHeight);

switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
//点击字母条变色
setBackgroundColor(sideBarBgPressColor);
//点击时回调
selectPos = position;
if(listener != null)
listener.onLetterSelected(b[selectPos]);
invalidate();
break;

case MotionEvent.ACTION_MOVE:
//切换到其他字母时执行
if(position != selectPos){

selectPos = position;
if(listener != null)
listener.onLetterChanged(b[selectPos]);
invalidate();
}

break;

case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
setBackgroundColor(sideBarBgNorColor);
if(listener != null){
listener.onLetterReleased(b[selectPos]);
}
break;
}

return true;
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

height = getHeight();
width = getWidth();
perHeight = height / b.length;
for (int i = 0; i < b.length; i++) {
//画字母
canvas.drawText(b[i],width/2 - paint.measureText(b[i])/2,perHeight * i+perHeight,paint);
//选中的字母变色
if(selectPos == i){
canvas.drawText(b[i],width/2 - paint.measureText(b[i])/2,perHeight * i+perHeight,paintSelect);
}
}
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = resolveMeasure(widthMeasureSpec, true);
int height = resolveMeasure(heightMeasureSpec,false);
setMeasuredDimension(width,height);
}

private int resolveMeasure(int measureSpec ,boolean isWidth) {

int result = 0 ;
int padding = isWidth ? getPaddingLeft() + getPaddingRight() : getPaddingTop() + getPaddingBottom();

// 获取宽度测量规格中的mode
int mode = MeasureSpec.getMode(measureSpec);

// 获取宽度测量规格中的size
int size = MeasureSpec.getSize(measureSpec);

switch (mode){
case MeasureSpec.EXACTLY:
result = size;
break;
case MeasureSpec.AT_MOST:
case MeasureSpec.UNSPECIFIED:
float textWidth = paint.measureText(b[0]);
if(isWidth){
result = getSuggestedMinimumWidth() > textWidth ? getSuggestedMinimumWidth() : (int) textWidth;
result += padding;
result = Math.min(result,size);
}else{
result = size;
result = Math.max(result,size);
}

break;
}

return result;
}

public float dp2px(float dp) {
final float scale = getResources().getDisplayMetrics().density;
return dp * scale + 0.5f;
}

@Override
protected int getSuggestedMinimumWidth() {
return (int) dp2px(25);
}

public interface LetterSelectListener{
void onLetterSelected(String letter);
void onLetterChanged(String letter);
void onLetterReleased(String letter);
}

private LetterSelectListener listener;
public void setOnLetterSelectListen(LetterSelectListener listen){
this.listener = listen;
}
}


然后写一个排序的Comparator

//@标签代表A前面的那些,#代表除了A-Z以外的其他标签
public class CompareSort implements Comparator<User> {
@Override
public int compare(User user1, User user2) {
if(user1.getLetter().equals("@") || user2.getLetter().equals("@")){
//通讯录前面的item(公众号,标签......)
return user1.getLetter().equals("@") ? -1:1;
}
//user1属于#标签,放到最后面
else if(!user1.getLetter().matches("[A-z]+")){
return 1;
//user2属于#标签,放到最后面
}else if(!user2.getLetter().matches("[A-z]+")){
return -1;
}else {
return user1.getLetter().compareTo(user2.getLetter());
}
}
}


public class UserAdapter extends BaseAdapter{
private Context mContext;
private ArrayList<User> users;
public UserAdapter(Context context) {
this.mContext = context;
users = new ArrayList<>();
}
public void setData(List<User> data){
this.users.clear();
this.users.addAll(data);
}
@Override
public int getCount() {
return users.size();
}
@Override
public Object getItem(int position) {
return users.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = LayoutInflater.from(mContext).inflate(R.layout.item, null);
viewHolder.tvTitle = (TextView) convertView.findViewById(R.id.title);
viewHolder.tvName = (TextView) convertView.findViewById(R.id.name);
viewHolder.tvItem = (LinearLayout) convertView.findViewById(R.id.item);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.tvName.setText(users.get(position).getName());
viewHolder.tvItem.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(mContext,users.get(position).getName(),Toast.LENGTH_SHORT).show();
}
});
//当前的item的title与上一个item的title不同的时候回显示title(A,B,C......)
if(position == getFirstLetterPosition(position) && !users.get(position).getLetter().equals("@")){
viewHolder.tvTitle.setVisibility(View.VISIBLE);
viewHolder.tvTitle.setText(users.get(position).getLetter().toUpperCase());
}else {
viewHolder.tvTitle.setVisibility(View.GONE);
}
return convertView;
}

/**
* 顺序遍历所有元素.找到position对应的title是什么(A,B,C?)然后找这个title下的第一个item对应的position
*
* @param position
* @return
*/
private int getFirstLetterPosition(int position) {

String letter = users.get(position).getLetter();
int cnAscii = ChineseToEnglish.getCnAscii(letter.toUpperCase().charAt(0));
int size = users.size();
for (int i = 0; i < size; i++) {
if(cnAscii == users.get(i).getLetter().charAt(0)){
return i;
}
}
return -1;
}

/**
* 顺序遍历所有元素.找到letter下的第一个item对应的position
* @param letter
* @return
*/
public int getFirstLetterPosition(String letter){
int size = users.size();
for (int i = 0; i < size; i++) {
if(letter.charAt(0) == users.get(i).getLetter().charAt(0)){
return i;
}
}
return -1;
}

class ViewHolder {
TextView tvName;
TextView tvTitle;
LinearLayout tvItem;
}
}


public class MainActivity extends ActionBarActivity implements SideBarView.LetterSelectListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

init();

}

ListView mListview;
UserAdapter mAdapter;
TextView mTip;
private void init() {
mListview = (ListView) findViewById(R.id.listview);
SideBarView sideBarView = (SideBarView) findViewById(R.id.sidebarview);
String[] contactsArray = getResources().getStringArray(R.array.data);
String[] headArray = getResources().getStringArray(R.array.head);
mTip = (TextView) findViewById(R.id.tip);

//模拟添加数据到Arraylist
int length = contactsArray.length;
ArrayList<User> users = new ArrayList<>();
for (int i = 0; i < length; i++) {
User user = new User();
user.setName(contactsArray[i]);
String firstSpell = ChineseToEnglish.getFirstSpell(contactsArray[i]);
String substring = firstSpell.substring(0, 1).toUpperCase();
if(substring.matches("[A-Z]")){
user.setLetter(substring);
}else {
user.setLetter("#");
}
users.add(user);
}

for (int i = 0; i < headArray.length; i++) {
User user = new User();
user.setName(headArray[i]);
user.setLetter("@");
users.add(user);
}

//排序
Collections.sort(users, new CompareSort());

//设置数据
mAdapter = new UserAdapter(this);
mAdapter.setData(users);
mListview.setAdapter(mAdapter);

//设置回调
sideBarView.setOnLetterSelectListen(this);

}

@Override
public void onLetterSelected(String letter) {
setListviewPosition(letter);
mTip.setText(letter);
mTip.setVisibility(View.VISIBLE);
}

@Override
public void onLetterChanged(String letter) {
setListviewPosition(letter);
mTip.setText(letter);
}

@Override
public void onLetterReleased(String letter) {
mTip.setVisibility(View.GONE);
}

private void setListviewPosition(String letter){
int firstLetterPosition = mAdapter.getFirstLetterPosition(letter);
if(firstLetterPosition != -1){
mListview.setSelection(firstLetterPosition);
}
}

}


上面代码比较少,所以就懒得说了。有兴趣的可以下载来看看





















代码下载

https://github.com/JadynChan/ContactsList

http://download.csdn.net/detail/recall2012/9397297
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: