android仿demo————通讯录界⾯功能实现(移动端,服务端)前⾯我们实现了消息界⾯的实现,这篇继续完善功能,实现通讯录界⾯
⽂章⽬录
移动端通讯录界⾯功能实现
通讯录,头部是四个标签(不进⾏分组),下⾯是好友信息且根据呢称⾸字母进⾏排序分组,底部还统计了好友个数,右边是⼀组英⽂字母导航,可滑动并且还可以点击跳转到相应的分组
好友和顶部的四个标签,可以⽤ListViw实现并指定⼀个item布局,分组效果只需要在代码段进⾏判断即可
右边的字母操作⾏可以⾃定义⼀个组件继承AppCompatTextView,为什么要⽤它呢,⽽不⽤TextView呢?因为UI设计限定了⼀个⽂本的宽度,但是⽂本的长度可能⽐较长,如果设定⼀个固定的textSize,就导致⼀部分⽂本⽆法显⽰,⽽AppCompatTextView最显著的特点是可以⾃适应字体宽度⼤⼩变化。这个特点很有⽤,可以让⽂本随着⽂本宽度的变化,限定在⼀个固定范围内完整显⽰出来:
修改通信录界⾯的fragment布局
l
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android="schemas.android/apk/res/android"
tools="schemas.android/tools"
layout_width="match_parent"
layout_height="match_parent"
context="ample.wxchatdemo.MainWeixin">
<ListView
id="@+id/listView"
layout_width="match_parent"
layout_height="match_parent"
divider="@drawable/main_list_divider_line"
dividerHeight="1.5px"
layout_marginBottom="50dp"/>
&ls.SideBar
id="@+id/side_bar"
layout_width="match_parent"
layout_height="match_parent"
layout_alignParentRight="true"
layout_marginBottom="100dp"
layout_marginTop="100dp"
paddingRight="10dp"
textColor="@color/black"
textSize="9sp"/>
</RelativeLayout>
fragment整体布局使⽤相对布局,这样可以通过 android:layout_alignParentRight="true"属性指定右边的⾃定义字母导航(SideBar继承AppCompatTextView)在⽗容器右边(即在屏幕中间的右边),相对布局包括两个组件(ListView,SideBar)
创建⾃定义组件SideBar.java继承AppCompatTextView
SideBar.java
package;
import Context;
import TypedArray;
import Canvas;
import Paint;
import AttributeSet;
import MotionEvent;
public class SideBar extends AppCompatTextView {
private String[] letters =new String[]{"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 Paint textPaint;
private Paint bigTextPaint;
private Paint scaleTextPaint;
private Canvas canvas;
private int itemH;
private int w;
private int h;
/**
* 普通情况下字体⼤⼩
*/
float singleTextH;
/**
* 缩放离原始的宽度
*/
private float scaleWidth;
/**
* 滑动的Y
*/
private float eventY =0;
/**
* 缩放的倍数
*/
private int scaleSize =1;
private int scaleSize =1;
/**
* 缩放个数item,即开⼝⼤⼩
*/
private int scaleItemCount =6;
private ISideBarSelectCallBack callBack;
public SideBar(Context context){
this(context,null);
}
public SideBar(Context context, AttributeSet attrs){
this(context, attrs,0);
}
public SideBar(Context context, AttributeSet attrs,int defStyleAttr){
super(context, attrs, defStyleAttr);
init(attrs);
}
private void init(AttributeSet attrs){
if(attrs !=null){
TypedArray ta =getContext().obtainStyledAttributes(attrs, R.styleable.SideBar); scaleSize = ta.getInteger(R.styleable.SideBar_scaleSize,1);
scaleItemCount = ta.getInteger(R.styleable.SideBar_scaleItemCount,6);
scaleWidth = ta.getDimensionPixelSize(R.styleable.SideBar_scaleWidth,dp(100)); ta.recycle();
}
textPaint =new Paint(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(getCurrentTextColor());
textPaint.setTextSize(getTextSize());
textPaint.setTextAlign(Paint.Align.CENTER);
bigTextPaint =new Paint(Paint.ANTI_ALIAS_FLAG);
bigTextPaint.setColor(getCurrentTextColor());
bigTextPaint.setTextSize(getTextSize()*(scaleSize +3));
bigTextPaint.setTextAlign(Paint.Align.CENTER);
scaleTextPaint =new Paint(Paint.ANTI_ALIAS_FLAG);
scaleTextPaint.setColor(getCurrentTextColor());
scaleTextPaint.setTextSize(getTextSize()*(scaleSize +1));
scaleTextPaint.setTextAlign(Paint.Align.CENTER);
}
public void setDataResource(String[] data){
letters = data;
invalidate();
}
public void setOnStrSelectCallBack(ISideBarSelectCallBack callBack){
this.callBack = callBack;
}
/**
* 设置字体缩放⽐例 * * @param scale
*/
public void setScaleSize(int scale){
scaleSize = scale;
invalidate();
}
/**
* 设置缩放字体的个数,即开⼝⼤⼩ * * @param scaleItemCount
*/
public void setScaleItemCount(int scaleItemCount){
this.scaleItemCount = scaleItemCount;
invalidate();
}
}
private int dp(int px){
final float scale =getContext().getResources().getDisplayMetrics().density;
return(int)(px * scale +0.5f);
}
@Override
public boolean onTouchEvent(MotionEvent event){
Action()){
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
X()>(w -getPaddingRight()- singleTextH -10)){
eventY = Y();
invalidate();
return true;
}else{
eventY =0;
invalidate();
break;
}
case MotionEvent.ACTION_CANCEL:
eventY =0;
invalidate();
return true;
case MotionEvent.ACTION_UP:
X()>(w -getPaddingRight()- singleTextH -10)){
eventY =0;
invalidate();
return true;
}else
break;
}
TouchEvent(event);
}
@Override
protected void onDraw(Canvas canvas){
this.canvas = canvas;
DrawView(eventY);
}
private void DrawView(float y){
int currentSelectIndex =-1;
if(y !=0){
for(int i =0; i < letters.length; i++){
float currentItemY = itemH * i;
float nextItemY = itemH *(i +1);
代码转换if(y >= currentItemY && y < nextItemY){
currentSelectIndex = i;
if(callBack !=null){
}//画⼤的字母
Paint.FontMetrics fontMetrics = FontMetrics();
float bigTextSize = fontMetrics.descent - fontMetrics.ascent;
canvas.drawText(letters[i], w -getPaddingRight()- scaleWidth - bigTextSize, singleTextH + itemH * i, bigTextPaint);
}
}
}
drawLetters(y, currentSelectIndex);
}
private void drawLetters(float y,int index){//第⼀次进来没有缩放情况,默认画原图if(index ==-1){
w =getMeasuredWidth();
w =getMeasuredWidth();
h =getMeasuredHeight();
itemH = h / letters.length;
Paint.FontMetrics fontMetrics = FontMetrics();
singleTextH = fontMetrics.descent - fontMetrics.ascent;
for(int i =0; i < letters.length; i++){
canvas.drawText(letters[i], w -getPaddingRight(), singleTextH + itemH * i, textPaint);
}//触摸的时候画缩放图
}else{//遍历所有字母
for(int i =0; i < letters.length; i++){//要画的字母的起始Y坐标
float currentItemToDrawY = singleTextH + itemH * i;
float centerItemToDrawY;
if(index < i)
centerItemToDrawY = singleTextH + itemH *(index + scaleItemCount);
else
centerItemToDrawY = singleTextH + itemH *(index - scaleItemCount);
float delta =1- Math.abs((y - currentItemToDrawY)/(centerItemToDrawY - currentItemToDrawY));
float maxRightX = w -getPaddingRight();//如果⼤于0,表明在y坐标上⽅
scaleTextPaint.setTextSize(getTextSize()+getTextSize()* delta);
float drawX = maxRightX - scaleWidth * delta;//超出边界直接花在边界上
if(drawX > maxRightX)
canvas.drawText(letters[i], maxRightX, singleTextH + itemH * i, textPaint);
else
canvas.drawText(letters[i], drawX, singleTextH + itemH * i, scaleTextPaint);
}
}
}
public interface ISideBarSelectCallBack {
void onSelectStr(int index, String selectStr);
}
}
右侧字母导航条,包括3个⾃定义的属性,下⾯将给出
在l⽂件添加如下代码
<declare-styleable name="SideBar">
<attr name="scaleSize"format="integer"/>
<attr name="scaleItemCount"format="integer"/>
<attr name="scaleWidth"format="dimension"/>
</declare-styleable>
要在字母导航中点击每⼀个字母可跳转相应分组,需要借助汉字转拼⾳⼯具类和⾃定义字母排序类,我们知道,java中是没有提供接⼝和⽅法让我们直接将汉字转成拼⾳的。在此我选择了使⽤第三⽅jar包的⽅式,因为它体积不⼤⽽且更加准确。
创建汉字转拼⾳⼯具类Cn2Spell.java
Cn2Spell.java
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论