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

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

411a68ff674863d8b83db1553d9bf145.png3f7ce19b55b6f8da8f45774dee462b9b.png

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

d934e954ef14be6715f5952bf97a7576.png

bg_hitchar.png

4c740c8f57635a9d779eb35da310299f.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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值