Android中仿微信实现联系人列表 按字母排序分组 自定义通讯录导航栏View,下边是效果图:

1. 自定义View

public class SideBar extends View {

// 触摸事件

private OnTouchingLetterChangedListener onTouchingLetterChangedListener;

// 26个字母"☆", "#",

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 choose = -1;// 选中

private Paint paint = new Paint();

private TextView mTextDialog;

public void setTextView(TextView mTextDialog) {

this.mTextDialog = mTextDialog;

}

public SideBar(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

}

public SideBar(Context context, AttributeSet attrs) {

super(context, attrs);

}

public SideBar(Context context) {

super(context);

}

/**

* 重写这个方法

*/

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

// 获取焦点改变背景颜色.

int height = getHeight();// 获取对应高度

int width = getWidth(); // 获取对应宽度

int singleHeight = height / b.length;// 获取每一个字母的高度

for (int i = 0; i < b.length; i++) {

paint.setColor(getResources().getColor(R.color.black));

paint.setTypeface(Typeface.DEFAULT);

paint.setAntiAlias(true);

paint.setTextSize(24);

// 选中的状态

if (i == choose) {

paint.setColor(getResources().getColor(R.color.yellow));

paint.setFakeBoldText(true);

}

// x坐标等于中间-字符串宽度的一半.

float xPos = width / 2 - paint.measureText(b[i]) / 2;

float yPos = singleHeight * i + singleHeight;

canvas.drawText(b[i], xPos, yPos, paint);

paint.reset();// 重置画笔

}

}

@SuppressWarnings("deprecation")

@Override

public boolean dispatchTouchEvent(MotionEvent event) {

final int action = event.getAction();

final float y = event.getY();// 点击y坐标

final int oldChoose = choose;

final OnTouchingLetterChangedListener listener = onTouchingLetterChangedListener;

final int c = (int) (y / getHeight() * b.length);// 点击y坐标所占总高度的比例*b数组的长度就等于点击b中的个数.

switch (action) {

case MotionEvent.ACTION_UP:

setBackgroundDrawable(new ColorDrawable(0x00000000));//

choose = -1;// up 时是否显示选中颜色

invalidate();

if (mTextDialog != null) {

mTextDialog.setVisibility(View.INVISIBLE);

}

if (listener != null) {

listener.noTouchLetter();

}

break;

default:

setBackgroundResource(R.drawable.sidebar_background);//

setAlpha((float) 0.7);

if (oldChoose != c) {

if (c >= 0 && c < b.length) {

if (listener != null) {

listener.onTouchingLetterChanged(b[c]);

}

if (mTextDialog != null) {

mTextDialog.setText(b[c]);

mTextDialog.setTextColor(Color.WHITE);

mTextDialog.setVisibility(View.VISIBLE);

}

choose = c;

invalidate();

}

}

break;

}

return true;

}

/**

* 向外公开的方法

*

* @param onTouchingLetterChangedListener

*/

public void setOnTouchingLetterChangedListener(OnTouchingLetterChangedListener onTouchingLetterChangedListener) {

this.onTouchingLetterChangedListener = onTouchingLetterChangedListener;

}

/**

* 接口

*

* @author coder

*

*/

public interface OnTouchingLetterChangedListener {

public void onTouchingLetterChanged(String s);

public void noTouchLetter();

}

}

2. drawable下新建 sidebar_background.xml

3. color

#000000

#F99503

4. mipmap

search_goods

bg_hitchar.png

5.Activity代码

public class FriendSListActivity extends AppCompatActivity implements View.OnClickListener{

private TextView tvSearchFriend;

private RecyclerView rvShowNeighbourList;

private SideBar sideBar;

private TextView textView;

private FriendListRvAdapter friendListRvAdapter;

public static ListmDatas = new ArrayList<>();

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_bbb);

initView();

setAdapter();

}

private void initView() {

tvSearchFriend=findViewById(R.id.tv_search_friend);

rvShowNeighbourList = findViewById(R.id.rv_show_neighbour_list);

textView = findViewById(R.id.tv_show_selete_zm);

sideBar = findViewById(R.id.side_bar);

tvSearchFriend.setOnClickListener(this);

}

@Override

public void onClick(View v) {

switch (v.getId()){

case R.id.tv_search_friend:

Intent intent = new Intent(NeighbourListActivity.this,SearchActivity.class);

startActivity(intent);

overridePendingTransition(0, 0);

break;

}

}

private void setListener() {

sideBar.setOnTouchingLetterChangedListener(new SideBar.OnTouchingLetterChangedListener() {

@Override

public void onTouchingLetterChanged(String s) {

// sideBar.setTextView(textView);

textView.setVisibility(View.VISIBLE);

textView.setText(s);

for(int i = 0;i

6.Activity页面布局代码

7. 实体类User

public class User implements MultiItemEntity ,Serializable {

int itemType;

String userImg;

String userName;

String userSign;

String userNmaeFirstLetter;

public String getUserSign() {

return userSign;

}

public void setUserSign(String userSign) {

this.userSign = userSign;

}

public String getUserImg() {

return userImg;

}

public void setUserImg(String userImg) {

this.userImg = userImg;

}

public String getUserName() {

return userName;

}

public void setUserName(String userName) {

this.userName = userName;

}

public String getUserNmaeFirstLetter() {

return userNmaeFirstLetter;

}

public void setUserNmaeFirstLetter(String userNmaeFirstLetter) {

this.userNmaeFirstLetter = userNmaeFirstLetter;

}

public void setItemType(int itemType) {

this.itemType = itemType;

}

@Override

public int getItemType() {

return itemType;

}

}

8. 适配器

public class FriendListRvAdapter extends BaseMultiItemQuickAdapterimplements Filterable {

private MyFilter myFilter;

private ListmDatas;

private Context context;

private ArrayListmOriginalValues;

private final Object mLock = new Object();

public FriendListRvAdapter(Listdata) {

super(data);

mDatas = data;

addItemType(1, R.layout.first_letter_text);

addItemType(2, R.layout.letter_list);

}

@Override

protected void convert(BaseViewHolder helper, User item) {

switch (helper.getItemViewType()) {

case 1:

setFirstLetter(helper,item);

break;

case 2:

setUserList(helper,item);

break;

}

}

private void setUserList(BaseViewHolder helper, User item) {

helper.setText(R.id.tv_user_name,item.getUserName());

helper.setText(R.id.tv_user_sign,item.getUserSign());

Glide.with(mContext).load(item.getUserImg()).into((ImageView) helper.getView(R.id.iv_user_img));

}

private void setFirstLetter(BaseViewHolder helper, User item) {

helper.setText(R.id.tv_first_letter,item.getUserNmaeFirstLetter());

}

@Override

public Filter getFilter() {

if (myFilter == null) {

myFilter = new MyFilter();

}

return myFilter;

}

class MyFilter extends Filter {

@Override

protected FilterResults performFiltering(CharSequence prefix) {

// 持有过滤操作完成之后的数据。该数据包括过滤操作之后的数据的值以及数量。 count:数量 values包含过滤操作之后的数据的值

FilterResults results = new FilterResults();

if (mOriginalValues == null) {

synchronized (mLock) {

// 将list的用户 集合转换给这个原始数据的ArrayList

mOriginalValues = new ArrayList(mDatas);

}

}

if (prefix == null || prefix.length() == 0) {

synchronized (mLock) {

ArrayListlist = new ArrayList(

mOriginalValues);

results.values = list;

results.count = list.size();

}

} else {

// 做正式的筛选

String prefixString = prefix.toString().toLowerCase();

// 声明一个临时的集合对象 将原始数据赋给这个临时变量

final ArrayListvalues = mOriginalValues;

final int count = values.size();

// 新的集合对象

final ArrayListnewValues = new ArrayList(

count);

for (int i = 0; i < count; i++) {

// 如果姓名的前缀相符或者电话相符就添加到新的集合

final User value = (User) values.get(i);

// Log.i("coder", "PinyinUtils.getAlpha(value.getUsername())"

// + PinyinUtils.getAlpha(value.getUsername()));

// if (PinyinUtils.getAlpha(value.getUsername()).startsWith(

// prefixString)

// || value.getPhonenum().startsWith(prefixString)||value.getUserName().startsWith(prefixString)) {

//

// newValues.add(value);

// }

}

// 然后将这个新的集合数据赋给FilterResults对象

results.values = newValues;

results.count = newValues.size();

}

return results;

}

@Override

protected void publishResults(CharSequence constraint,

FilterResults results) {

// 重新将与适配器相关联的List重赋值一下

mDatas = (List) results.values;

if (results.count > 0) {

notifyDataSetChanged();

} else {

// notifyDataSetInvalidated();

}

}

}

}

9. RecyclerView两种布局:

(1)first_letter_text.xml

(2)letter_list.xml

android 好友字母分组,Android好友联系人按字母排序分组,自定义通讯录导航栏View...相关推荐

  1. Android好友联系人按字母排序分组,自定义通讯录导航栏View

    Android中仿微信实现联系人列表 按字母排序分组 自定义通讯录导航栏View,下边是效果图: 1. 自定义View public class SideBar extends View {// 触摸 ...

  2. Android 通讯录导航栏

    这几天无意间翻到之前写的一篇关于自定义通讯录导航栏的博客,文章中只是做了一点点简单介绍,写的并不完整.由于这段时间比较空闲,索性把整篇文章重新整理一遍. 这样的一个控件实现起来不难,需要对自定义vie ...

  3. android自适应拉伸图片,Android 启动页-解决图片被拉伸和压缩问题,适配虚拟导航栏...

    Android 启动页设置非常简单 //styles.xml 设置主题 @drawable/bg_splash true //activity使用主题,这时点击app图标,就会显示@drawable/ ...

  4. Android 开发:(十四)NavigationBar篇-自定义顶部导航栏

    本篇记录了navigation bar顶部导航栏的自定义方法,抛砖引玉,简单实现了常用的布局,在此基础上可添加较复杂的布局. 第一步:新建NavigationBar文件,继承与FrameLayout. ...

  5. Android 自定义底部导航栏消息显示

    转载请标明出处: http://blog.csdn.net/tyzlmjj/article/details/47186249 本文出自:[M家杰的博客] 概述 底部导航栏的做法多种多样,这次主要用到了 ...

  6. android 自定义标签导航栏,自定义导航栏app下载-自定义导航栏(Custom Navigation Bar) 安卓版v0.4.3-PC6安卓网...

    自定义导航栏(Custom Navigation Bar)app是款非常好用的实用工具,自定义导航栏能让你自己设置个性的导航栏,再也不用为单调的导航栏而发愁,独特且唯一,感兴趣的朋友就来下载自定义导航 ...

  7. android webview监听软键盘弹出和隐藏来修改虚拟导航栏颜色

    最近项目中用到了webview,然后里面有输入框,当我们点击输入框的时候,软键盘挡住了布局,这就尴尬了,并且产品说,只有在软键盘弹出的时候底部的虚拟导航栏为黑色,软键盘隐藏的时候虚拟导航栏应该也隐藏. ...

  8. android底部导航栏网络请求有冲突,Android 自定义底部导航栏 CustomizeTabLayout(支持访问网络图片、本地图片)...

    先看效果 网络图片(使用第三方库Glide加载图片) GIF1.gif 本地图片 GIF2.gif 使用方法 xml(布局可关联鸿洋大神的AutoLinearLayout可完美适配) activity ...

  9. android应用去掉状态栏_Android 显示、隐藏状态栏和导航栏

    Android 显示.隐藏状态栏和导航栏 控制状态栏显示,Activity的主题中配置全屏属性 true 控制状态栏显示,在setContentView之前设置全屏的flag getWindow(). ...

最新文章

  1. 终于不会看不懂LSTM了
  2. ios加速计(可以用来检测摇动,自定义反应灵敏度)
  3. 安卓开发创建活动,布局,添加按钮,she使用Toast,设菜单,使菜单相关联等操作...
  4. C语言描述栈的实现及操作(数组实现)
  5. 汉诺塔VII(递推,模拟)
  6. Docker收购Orchard,SAP支持OpenStack,ODF等
  7. swift 计算label的行数方法
  8. Specify 的含义 ------ 转载
  9. X-006 FriendlyARM tiny4412 u-boot移植之Debug串口用起来
  10. python 解析pb文件_利用Python解析json文件
  11. Linux音频驱动开发概括
  12. 别人改出了新BUG,怎么看?
  13. linux i3 桌面,Linux 桌面平铺管理器 - i3wm
  14. 石溪分校 计算机研究生专业,纽约州立大学石溪分校计算机科学专业
  15. 人工智能的历史(History of artificial intelligence)
  16. 第二章 03 藤蔓生长
  17. AI虚拟人物 数字人直播,不用出镜,不用露脸的直播方式(附教程 软件)
  18. [Pandas] 缺失值删除 df.dropna()
  19. python读取和写入 gzip和bz2格式的压缩文件中的数据
  20. 小白用户怎么才能让电脑换IP?

热门文章

  1. Live Home 3D Pro for mac(3D家居设计软件)
  2. 双极化天线及其下倾技术(转)
  3. 蓝桥杯【第13届省赛】Python 实现
  4. 基于普中科技的单片机开发实验仪编写的数字表
  5. 前端设计一一个人博客网站怎么进行公安备案?
  6. TensorFlow2 入门指南 | 04 分类问题实战之手写数字识别
  7. 黄学东等多名华人当选,2023美国工程院院士名单出炉
  8. 网络字节序与地址转换函数
  9. 华为HCIP-DATACOM题库解析161-190(821)
  10. 成为一名合格且优秀的渗透工程师需要那些知识储备?