现在很多手机APP都用到通讯录功能,在通讯录的基础上添加好友,查找好友,获取哪些好友和自己在玩同一款APP,这就需要去获取手机通讯好友信息,并把这些信息展示出来!这些就需要列表展示通讯录好友。但发现Android手机的通讯录效果比Ios效果差很多,自己决定仿照Ios效果开发个自定义的通讯录功能来。
结合之前自己做过的通讯录功能以及自定义listview反弹效果和自定义搜索框。仿照一个比较全功能的通讯录来,现在把自己成品贴出来,分享下,另外这个项目会在github不断更新和完善!
贴出效果图:
自定义控件涉及有:
- 自定义ListView
- 自定义EditText
- 自定义触压显示字母View
反弹效果无非就是在ListView的头部加上个布局和脚部加上个布局,之后再重写onTounchEvent方法,判断tounch事件,做个逻辑处理。
onTounchEvent代码如下:
case MotionEvent.ACTION_DOWN://触摸按下
mLastY = ev.getRawY();//触摸点相对于屏幕的Y坐标,记录在mLastY
break;
case MotionEvent.ACTION_MOVE://触摸移动
final float deltaY = ev.getRawY() - mLastY;//用正负值判断移动方向
mLastY = ev.getRawY();
if (getFirstVisiblePosition() == 0 && deltaY > 0) {//向下拉取,更新头部高度
updateHeaderHeight(deltaY / OFFSET_RADIO);
} else if (getLastVisiblePosition() == mTotalItemCount - 1 && deltaY < 0) {//向上拉去,更新尾部高度
updateFooterHeight(-deltaY / OFFSET_RADIO);
}
break;
case MotionEvent.ACTION_UP://触摸抬起
if (getFirstVisiblePosition() == 0) {
resetHeaderHeight();//重置
} else if (getLastVisiblePosition() == mTotalItemCount - 1) {
resetFooterHeight();//重置
}
这里面是更新头部、脚部高度代码原理就是获取头部、脚部布局高度,在上下拉的力度进行重新设置布局高度。
这里面我就贴出头部代码:
private void setVisibleHeaderHeight(int height) {//设置头部显示的高度
if (height < 0)
height = 0;
LayoutParams lp = (LayoutParams) headerLayout.getLayoutParams();
lp.height = height;
headerLayout.setLayoutParams(lp);
}
自定义ListView还涉及一个字母导航条,原理就是把导航条的视图添加到ListView来,重写onMeasure获取子控件的宽高并记录,重写onLayout画出导航条的位置。
JClearEditText自定义搜索框,附加删除按钮,跟其他自定义控件一样新建构造函数,不过在这里需要提的一点是在构造函数中需要设置AttributeSet为edittextsytle。
public JClearEditText(Context context, AttributeSet attrs) {
// 这里构造方法也很重要,不加自定义EditText的很多属性就失效了
this(context, attrs, android.R.attr.editTextStyle);
}
之后,设置关闭按钮和搜索小图标,这个图片都是通过读取getResources()资源获取Drawable对象,通过setCompoundDrawables和setBounds结合设置图片(Edittext继承TextView包含这两种方法)。其他监听事件和隐藏图片这些就不在这里说了,有兴趣可以查看源码。
JIndexBarView导航条原理就是把字母逐个画出来,通过重写onDraw:
@Override
protected void onDraw(Canvas canvas) {
if (mListSections != null && mListSections.size() > 1) {
float sectionHeight = (getMeasuredHeight()*mListSections.size()/26)/ mListSections.size();
float paddingTop = (sectionHeight - (mIndexPaint.descent() - mIndexPaint.ascent())) / 2;
for (int i = 0; i < mListSections.size(); i++) {
float paddingLeft = (getMeasuredWidth() - mIndexPaint.measureText(getSectionText(mListSections.get(i)))) / 2;
canvas.drawText(getSectionText(mListSections.get(i)),
paddingLeft,
mJIndexBarMargin + (sectionHeight * i) + paddingTop + mIndexPaint.descent(),
mIndexPaint);
}
}
super.onDraw(canvas);
}
之后在加个是JAdapter适配器,并且读取手机通讯录信息,把信息结合下,就可以实现了!
目前项目已做成aar,方便开发者调用 用法-
Android Studio
引入依赖,依赖包最新版本请查看项目在github说明
compile 'com.soubw:jcontactlib:0.1.2'
添加继承实体对象JContacts(可直接使用JContacts实体对象,根据自己是否需要扩展实体属性)
实例为添加自己拓展实体属性
public class MainBean extends JContacts implements Serializable {
private String wxj;
public String getWxj() {
return wxj;
}
public void setWxj(String wxj) {
this.wxj = wxj;
}
public MainBean(){
super();
}
}
添加继承JAdapter
public class MainAdapter extends JAdapter {
public MainAdapter(Context context, List<MainBean> jContactsList, JListView lvList, int indexBarViewId, int previewViewId, int itemLayoutId, int sectionLayoutId, View loadingView) {
super(context, jContactsList, lvList, indexBarViewId, previewViewId, itemLayoutId, sectionLayoutId, loadingView);
}
@Override
public void convert(JViewHolder holder, JContacts bean, int type) {
MainBean b = (MainBean) bean;
switch (type) {
case TYPE_ITEM:
holder.setText(R.id.row_title,bean.getjName()+b.getWxj());
break;
case TYPE_SECTION:
holder.setText(R.id.row_title,bean.getjFirstWord());
break;
}
}
}
调用
mAdaptor = new MainAdapter(this,
jContactsList,//联系人列表
(JListView) findViewById(R.id.lvList),//JListView对象
R.layout.jcontact_index_bar_view,//导航条视图
R.layout.jcontact_preview_view,//预览字母背景图
R.layout.jcontact_row_view,//列表内容view
R.layout.jcontact_section_row_view,//列表字母view
mLoadingView//加载LoadingView
);
0.1.0版本以后
新增可自己选择搜索框的背景框和图标,以及提示文字
<com.soubw.jcontactlib.JListView
android:id="@+id/lvList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:dividerHeight="0.1dp"
android:divider="@android:color/black"
jcontact:jClearEditTextBg="@drawable/jclearedittext_bg"
jcontact:jClearEditTextCloseBg="@drawable/jclearedittext_close_bg"
jcontact:jClearEditTextIconBg="@drawable/jclearedittext_icon_bg"
jcontact:jClearEditTextNotice="请输入关键字"
android:scrollbars="none"/>
详细可以参考Demo
具体详细信息可以查看下源码:https://github.com/WX-JIN/JContact
有不足之处,望提出改正,谢谢!
共同學習,寫下你的評論
評論加載中...
作者其他優質文章