Android 自定義通訊錄(仿Ios反彈效果+模糊搜尋+檢視手機通訊錄+拉伸導航條)
現在很多手機APP都用到通訊錄功能,在通訊錄的基礎上新增好友,查詢好友,獲取哪些好友和自己在玩同一款APP,這就需要去獲取手機通訊好友資訊,並把這些資訊展示出來!這些就需要列表展示通訊錄好友。但發現Android手機的通訊錄效果比Ios效果差很多,自己決定仿照Ios效果開發個自定義的通訊錄功能來。
結合之前自己做過的通訊錄功能以及自定義listview反彈效果和自定義搜尋框。仿照一個比較全功能的通訊錄來,現在把自己成品貼出來,分享下,另外這個專案會在github不斷更新和完善!
-
貼出效果圖:
自定義控制元件涉及有:
- 自定義ListView
- 自定義EditText
- 自定義觸壓顯示字母View
JListView
反彈效果無非就是在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
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
如發現問題、或者其他建議,可以在我的GitHub上提issues,或者部落格留言,博主會第一時間來處理。謝謝!