Android聊天软件的开发(四)--通讯录

一,好友排序

   好友排序是按照昵称拼音进行A-Z排序。效果如下图:

 

   对好友昵称进行排序,需要先将首字转换为ASCII码,然后根据ASCII码得到对应的拼音,最后根据拼音进行A-Z排序。点击按压右边的字母栏,会同步更新列表显示,并且显示当前点击的字母。

   代码实现:
   1. ContactsModel:好友列表实体。其中,如果用户昵称为成龙,则sortLetter为C,sortPinyin为CHEN。
   另外,photo(头像)属性由于是以String类型在客户端与服务器之间传输,而在客户端显示需要Drawable类型,所以photo要在String和Drawable之间转换。
public class ContactsModel{
	/**昵称首汉字的拼音首字母。用于显示*/
	private String sortLetter;
	/**昵称首汉字的全拼音。用于排序*/
	private String sortPinyin;
	private String userId;
	private String name;
	private String gender;
	private Drawable photo;
	
	public Drawable getPhoto() {
		return photo;
	}
	public void setPhoto(Drawable photo) {
		this.photo = photo;
	}
	public void setPhoto(String photo) {
		this.photo = ViewUtils.StringToDrawable(photo);
	}
	//...
}

   String和Drawable转换类
public class ViewUtils {	
	
	/**
	 * 将照片存储为字符串形式(经过BASE64编码)
	 */
	public static String DrawableToString(Drawable drawable) {
		if(drawable == null)
		{
			return "";
		}
		BitmapDrawable bd = (BitmapDrawable)drawable;
		Bitmap bmp = bd.getBitmap();
		if(bmp == null)
			return "";
		ByteArrayOutputStream stream = new ByteArrayOutputStream();
		//压缩图片
		bmp.compress(Bitmap.CompressFormat.PNG, 60, stream);
		byte[] b = stream.toByteArray();
		// Base64Coder编码,将图片流以字符串形式存储下来
		return Base64Coder.encodeLines(b);
	}

	/**
	 * 将Base64Coder编码后的字符串转换为Drawable
	 */
	public static Drawable StringToDrawable(String encodeStr) {
		if(encodeStr==null || encodeStr.isEmpty())
		{
			return null;
		}
		//Base64Coder解码
		ByteArrayInputStream in = new ByteArrayInputStream(Base64Coder.decodeLines(encodeStr));
		Bitmap dBitmap = BitmapFactory.decodeStream(in);
		Drawable drawable = new BitmapDrawable(dBitmap);
		return drawable;
	}
}

   其中,Base64Coder不是SDK库函数,可以在  http://www.source-code.biz/base64coder/java/ 获得。

   2. SideBar:自定义View,右侧字母索引。setTextView用于设置显示字母的TextView,比如上图的S字母框(该TextView的显示和隐藏已在内部实现,无需调用者操作)。setOnTouchingLetterChangedListener用于设置按压字母的回调函数,在OnTouchingLetterChangedListener函数中处理相应操作,如更新ListView显示。
public class SideBar extends View {
	/**触摸事件*/
	private OnTouchingLetterChangedListener mOnTouchingLetterChangedListener;
	/**26个字母*/
	public static String[] mLetters = { "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 boolean mIsPress;
	/**选中字母位置*/
	private int mChoose = -1;
	private Paint mPaint = new Paint();

	private TextView mTextDialog;

	public SideBar(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		setBackgroundDrawable(new ColorDrawable(0xFFFFFFFF));
	}

	public SideBar(Context context, AttributeSet attrs) {
		super(context, attrs);
		setBackgroundDrawable(new ColorDrawable(0xFFFFFFFF));
	}

	public SideBar(Context context) {
		super(context);
		setBackgroundDrawable(new ColorDrawable(0xFFFFFFFF));
	}

	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		
		// 获取焦点改变背景颜色.
		int height = getHeight();// 获取对应高度
		int width = getWidth(); // 获取对应宽度
		int singleHeight = height / mLetters.length;// 获取每一个字母的高度

		if(mIsPress)//处于按压态
		{
			for (int i = 0; i < mLetters.length; i++) {
				//字体改为黑色粗体
				mPaint.setColor(Color.parseColor("#000000"));
				mPaint.setTypeface(Typeface.DEFAULT_BOLD);
				mPaint.setAntiAlias(true);
				mPaint.setTextSize(18);
				// 选中的状态
				if (i == mChoose) {
					mPaint.setColor(Color.parseColor("#FFFFFF"));
					mPaint.setFakeBoldText(true);
				}
				// x坐标等于中间-字符串宽度的一半.
				float xPos = width / 2 - mPaint.measureText(mLetters[i]) / 2;
				float yPos = singleHeight * i + singleHeight;
				canvas.drawText(mLetters[i], xPos, yPos, mPaint);
				mPaint.reset();// 重置画笔
			}
		}else//正常状态
		{
			for (int i = 0; i < mLetters.length; i++) {
				mPaint.setColor(Color.parseColor("#E0E0E0"));
				mPaint.setTypeface(Typeface.DEFAULT);
				mPaint.setAntiAlias(true);
				mPaint.setTextSize(16);
				// x坐标等于中间-字符串宽度的一半.
				float xPos = width / 2 - mPaint.measureText(mLetters[i]) / 2;
				float yPos = singleHeight * i + singleHeight;
				canvas.drawText(mLetters[i], xPos, yPos, mPaint);
				mPaint.reset();// 重置画笔
			}
		}

	}

	@Override
	public boolean dispatchTouchEvent(MotionEvent event) {
		final int action = event.getAction();
		final float y = event.getY();// 点击y坐标
		final int oldChoose = mChoose;
		final OnTouchingLetterChangedListener listener = mOnTouchingLetterChangedListener;
		// 点击y坐标所占总高度的比例*mLetters数组的长度就等于点击mLetters中的个数.
		final int c = (int) (y / getHeight() * mLetters.length);

		switch (action) {
		case MotionEvent.ACTION_UP:
			setBackgroundDrawable(new ColorDrawable(0xFFFFFFFF));
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值