android仿微信好友列表功能

android studio实现微信好友列表功能,注意有一个jar包我没有放上来,请大家到MainActivity中的那个网址里面下载即可,然后把pinyin4j-2.5.0.jar复制粘贴到项目的app/libs文件夹里面,然后clean项目就可以使用了

实现效果图:

(1)在build.gradle中引用第三方的类库

compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
compile files('libs/pinyin4j-2.5.0.jar')

(2)在MainActivity:

public class MainActivity extends AppCompatActivity {
  //参考网址:https://github.com/JanecineJohn/WeChatList
  private RecyclerView contactList;
  private String[] contactNames;
  private LinearLayoutManager layoutManager;
  private LetterView letterView;
  private ContactAdapter adapter;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    contactNames = new String[] {"安然","奥兹","德玛","张三丰", "郭靖", "黄蓉", "黄老邪", "赵敏", "123", "天山童姥", "任我行", "于万亭", "陈家洛", "韦小宝", "$6", "穆人清", "陈圆圆", "郭芙", "郭襄", "穆念慈", "东方不败", "梅超风", "林平之", "林远图", "灭绝师太", "段誉", "鸠摩智"};
    contactList = (RecyclerView) findViewById(R.id.contact_list);
    letterView = (LetterView) findViewById(R.id.letter_view);
    layoutManager = new LinearLayoutManager(this);
    adapter = new ContactAdapter(this, contactNames);
    contactList.setLayoutManager(layoutManager);
    contactList.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));
    contactList.setAdapter(adapter);
    letterView.setCharacterListener(new LetterView.CharacterClickListener() {
      @Override
      public void clickCharacter(String character) {
        layoutManager.scrollToPositionWithOffset(adapter.getScrollPosition(character),0);
      }
      @Override
      public void clickArrow() {
        layoutManager.scrollToPositionWithOffset(0,0);
      }
    });
  }
}
(3)Contact类
public class Contact implements Serializable {
  private String mName;
  private int mType;
  public Contact(String name, int type) {
    mName = name;
    mType = type;
  }
  public String getmName() {
    return mName;
  }
  public int getmType() {
    return mType;
  }
}

(3)listview好友列表适配器,在这里设置显示的用户名和头像,并且添加点击事件  ContactAdapter

public class ContactAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
  private LayoutInflater mLayoutInflater;
  private Context mContext;
  private String[] mContactNames; // 联系人名称字符串数组
  private List<String> mContactList; // 联系人名称List(转换成拼音)
  private List<Contact> resultList; // 最终结果(包含分组的字母)
  private List<String> characterList; // 字母List
  public enum ITEM_TYPE {
    ITEM_TYPE_CHARACTER,
    ITEM_TYPE_CONTACT
  }
  public ContactAdapter(Context context, String[] contactNames) {
    mContext = context;
    mLayoutInflater = LayoutInflater.from(context);
    mContactNames = contactNames;
    handleContact();
  }
  private void handleContact() {
    mContactList = new ArrayList<>();
    Map<String, String> map = new HashMap<>();
    for (int i = 0; i < mContactNames.length; i++) {
      String pinyin = Utils.getPingYin(mContactNames[i]);
      map.put(pinyin, mContactNames[i]);
      mContactList.add(pinyin);
    }
    Collections.sort(mContactList, new ContactComparator());
    resultList = new ArrayList<>();
    characterList = new ArrayList<>();
    for (int i = 0; i < mContactList.size(); i++) {
      String name = mContactList.get(i);
      String character = (name.charAt(0) + "").toUpperCase(Locale.ENGLISH);
      if (!characterList.contains(character)) {
        if (character.hashCode() >= "A".hashCode() && character.hashCode() <= "Z".hashCode()) { // 是字母
          characterList.add(character);
          resultList.add(new Contact(character, ITEM_TYPE.ITEM_TYPE_CHARACTER.ordinal()));
        } else {
          if (!characterList.contains("#")) {
            characterList.add("#");
            resultList.add(new Contact("#", ITEM_TYPE.ITEM_TYPE_CHARACTER.ordinal()));
          }
        }
      }
      resultList.add(new Contact(map.get(name), ITEM_TYPE.ITEM_TYPE_CONTACT.ordinal()));
    }
  }
  @Override
  public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    if (viewType == ITEM_TYPE.ITEM_TYPE_CHARACTER.ordinal()) {
      return new CharacterHolder(mLayoutInflater.inflate(R.layout.item_character, parent, false));
    } else {
      return new ContactHolder(mLayoutInflater.inflate(R.layout.item_contact, parent, false));
    }
  }
  @Override
  public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    if (holder instanceof CharacterHolder) {
      ((CharacterHolder) holder).mTextView.setText(resultList.get(position).getmName());
    } else if (holder instanceof ContactHolder) {
      ((ContactHolder) holder).mTextView.setText(resultList.get(position).getmName());
    }
  }
  @Override
  public int getItemViewType(int position) {
    return resultList.get(position).getmType();
  }
  @Override
  public int getItemCount() {
    return resultList == null ? 0 : resultList.size();
  }
  public class CharacterHolder extends RecyclerView.ViewHolder {
    TextView mTextView;
    CharacterHolder(View view) {
      super(view);
      mTextView = (TextView) view.findViewById(R.id.character);
    }
  }
  public class ContactHolder extends RecyclerView.ViewHolder {
    TextView mTextView;
    ContactHolder(View view) {
      super(view);
      mTextView = (TextView) view.findViewById(R.id.contact_name);
    }
  }
  public int getScrollPosition(String character) {
    if (characterList.contains(character)) {
      for (int i = 0; i < resultList.size(); i++) {
        if (resultList.get(i).getmName().equals(character)) {
          return i;
        }
      }
    }
    return -1; // -1不会滑动
  }
}

(4)ContactComparator  做英文字母的判断

public class ContactComparator implements Comparator<String> {
  @Override
  public int compare(String o1, String o2) {
    int c1 = (o1.charAt(0) + "").toUpperCase().hashCode();
    int c2 = (o2.charAt(0) + "").toUpperCase().hashCode();
    boolean c1Flag = (c1 < "A".hashCode() || c1 > "Z".hashCode()); // 不是字母
    boolean c2Flag = (c2 < "A".hashCode() || c2 > "Z".hashCode()); // 不是字母
    if (c1Flag && !c2Flag) {
      return 1;
    } else if (!c1Flag && c2Flag) {
      return -1;
    }
    return c1 - c2;
  }
}

(5)DividerItemDecoration

public class DividerItemDecoration extends RecyclerView.ItemDecoration {
  private static final int[] ATTRS = new int[]{
      android.R.attr.listDivider
  };
  public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
  public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
  private Drawable mDivider;
  private int mOrientation;
  public DividerItemDecoration(Context context, int orientation) {
    final TypedArray a = context.obtainStyledAttributes(ATTRS);
    mDivider = a.getDrawable(0);
    a.recycle();
    setOrientation(orientation);
  }
  private void setOrientation(int orientation) {
    if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
      throw new IllegalArgumentException("invalid orientation");
    }
    mOrientation = orientation;
  }
  @Override
  public void onDraw(Canvas c, RecyclerView parent) {
    if (mOrientation == VERTICAL_LIST) {
      drawVertical(c, parent);
    } else {
      drawHorizontal(c, parent);
    }
  }
//  @Override
//  public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
//    //super.onDraw(c, parent, state);
//    if (mOrientation == VERTICAL_LIST) {
//      drawVertical(c, parent);
//    } else {
//      drawHorizontal(c, parent);
//    }
//  }
  public void drawVertical(Canvas c, RecyclerView parent) {
    final int left = parent.getPaddingLeft();
    final int right = parent.getWidth() - parent.getPaddingRight();
    final int childCount = parent.getChildCount();
    for (int i = 0; i < childCount; i++) {
      final View child = parent.getChildAt(i);
      final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
          .getLayoutParams();
      final int top = child.getBottom() + params.bottomMargin +
          Math.round(ViewCompat.getTranslationY(child));
      final int bottom = top + mDivider.getIntrinsicHeight();
      mDivider.setBounds(left, top, right, bottom);
      mDivider.draw(c);
    }
  }
  public void drawHorizontal(Canvas c, RecyclerView parent) {
    final int top = parent.getPaddingTop();
    final int bottom = parent.getHeight() - parent.getPaddingBottom();
    final int childCount = parent.getChildCount();
    for (int i = 0; i < childCount; i++) {
      final View child = parent.getChildAt(i);
      final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
          .getLayoutParams();
      final int left = child.getRight() + params.rightMargin +
          Math.round(ViewCompat.getTranslationX(child));
      final int right = left + mDivider.getIntrinsicHeight();
      mDivider.setBounds(left, top, right, bottom);
      mDivider.draw(c);
    }
  }
  @Override
  public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
    if (mOrientation == VERTICAL_LIST) {
      outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
    } else {
      outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
    }
  }
//  @Override
//  public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
//    if (mOrientation == VERTICAL_LIST){
//      outRect.set(0,0,0,mDivider.getIntrinsicHeight());
//    }else {
//      outRect.set(0,0,mDivider.getIntrinsicWidth(),0);
//    }
//  }
}

(6)LetterView

public class LetterView extends LinearLayout{
  private Context mContext;
  private CharacterClickListener mListener;
  public LetterView(Context context,AttributeSet attrs) {
    super(context, attrs);
    mContext = context;//接收传进来的上下文
    setOrientation(VERTICAL);
    initView();
  }
  private void initView(){
    addView(buildImageLayout());
    for (char i = 'A';i<='Z';i++){
      final String character = i + "";
      TextView tv = buildTextLayout(character);
      addView(tv);
    }
    addView(buildTextLayout("#"));
  }
  private TextView buildTextLayout(final String character){
    LinearLayout.LayoutParams layoutParams =
        new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT,1);
    TextView tv = new TextView(mContext);
    tv.setLayoutParams(layoutParams);
    tv.setGravity(Gravity.CENTER);
    tv.setClickable(true);
    tv.setText(character);
    tv.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View view) {
        if (mListener != null){
          mListener.clickCharacter(character);
        }
      }
    });
    return tv;
  }
  private ImageView buildImageLayout() {
    LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1);
    ImageView iv = new ImageView(mContext);
    iv.setLayoutParams(layoutParams);
    iv.setBackgroundResource(R.mipmap.ic_launcher);
    iv.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        if (mListener != null) {
          mListener.clickArrow();
        }
      }
    });
    return iv;
  }
  public void setCharacterListener(CharacterClickListener listener) {
    mListener = listener;
  }
  public interface CharacterClickListener {
    void clickCharacter(String character);
    void clickArrow();
  }
}

(7)Utils

public class Utils {
  public static String getPingYin(String inputString) {
    HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
    format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
    format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
    format.setVCharType(HanyuPinyinVCharType.WITH_V);
    char[] input = inputString.trim().toCharArray();
    String output = "";
    try {
      for (char curchar : input) {
        if (java.lang.Character.toString(curchar).matches("[\\u4E00-\\u9FA5]+")) {
          String[] temp = PinyinHelper.toHanyuPinyinStringArray(curchar, format);
          output += temp[0];
        } else {
          output += java.lang.Character.toString(curchar);
        }
      }
    } catch (BadHanyuPinyinOutputFormatCombination e) {
      e.printStackTrace();
    }
    return output;
  }
}

总结

以上所述是小编给大家介绍的android仿微信好友列表,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • Android中使用listview实现qq/微信好友列表

    首先附上运行结果: 如果你没有学过listview请你先看一看基本知识.不想再说的那么细了 太多了. 首先是listview布局 <?xml version="1.0" encoding="utf-8"?> <ListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/lv_view" android

  • Android仿QQ好友列表实现列表收缩与展开

    ExpandableListView是一个垂直滚动显示两级列表项的视图,与ListView不同的是,它可以有两层:每一层都能够被独立的展开并显示其子项. 好友QQ列表,可以展开,可以收起,在android中,以往用的比较多的是listview,虽然可以实现列表的展示,但在某些情况下,我们还是希望用到可以分组并实现收缩的列表,那就要用到android的ExpandableListView,今天研究了一下这个的用法,也参考了很多资料动手写了一个小demo,实现了基本的功能,下面直接上效果图以及源代码

  • Android仿QQ好友列表分组实现增删改及持久化

    Android自带的控件ExpandableListView实现了分组列表功能,本案例在此基础上进行优化,为此控件添加增删改分组及子项的功能,以及列表数据的持久化. Demo实现效果: GroupListDemo具体实现: ①demo中将列表页面设计为Fragment页面,方便后期调用:在主界面MainActivity中动态添加GroupListFragment页面: MainActivity.java package com.eric.grouplistdemo; import android

  • Android UI仿QQ好友列表分组悬浮效果

    本文实例为大家分享了Android UI仿QQ好友列表分组悬浮效果的具体代码,供大家参考,具体内容如下 楼主是在平板上測试的.图片略微有点大,大家看看效果就好 接下来贴源代码: PinnedHeaderExpandableListView.java 要注意的是 在 onGroupClick方法中parent.setSelectedGroup(groupPosition)这句代码的作用是点击分组置顶, 我这边不须要这个效果.QQ也没实用到,所以给凝视了.大家假设须要能够解开凝视 package c

  • android仿微信好友列表功能

    android studio实现微信好友列表功能,注意有一个jar包我没有放上来,请大家到MainActivity中的那个网址里面下载即可,然后把pinyin4j-2.5.0.jar复制粘贴到项目的app/libs文件夹里面,然后clean项目就可以使用了 实现效果图: (1)在build.gradle中引用第三方的类库 compile 'com.android.support:recyclerview-v7:26.0.0-alpha1' compile files('libs/pinyin4j

  • Android仿微信@好友功能 输入@跳转、删除整块

    最近在做聊天功能的时候,有一个需求是仿照微信做@好友的功能,本来以为挺简单,但是做到这块的时候,发现和想象的有点不一样,什么整块删除,块可编辑,总之,加个@的功能很简单,但是要做和微信的一样还是费了一些功夫,下面是一个demo仅供参考,防止遗忘 先上个效果图 就是这么个功能 1. 分析需求 输入@跳转到联系人界面,选中一个或者多个好友返回到当前界面 按退格键删除整块内容 块内的内容可编辑,编辑完了之后将不附带@功能,只是单纯的文字 2. 开始编码 既然是文本输入首先继承EditText自定义一个

  • Android仿微信通讯录列表侧边栏效果

    先看Android仿微信通讯录列表侧边栏效果图 这是比较常见的效果了吧 列表根据首字符的拼音字母来排序,且可以通过侧边栏的字母索引来进行定位. 实现这样一个效果并不难,只要自定义一个索引View,然后引入一个可以对汉字进行拼音解析的jar包--pinyin4j-2.5.0即可 首先,先来定义侧边栏控件View,只要直接画出来即可. 字母选中项会变为红色,且滑动时背景会变色,此时SideBar并不包含居中的提示文本 public class SideBar extends View { priva

  • Android仿微信语音聊天功能

    本文实例讲述了Android仿微信语音聊天功能代码.分享给大家供大家参考.具体如下: 项目效果如下: 具体代码如下: AudioManager.java package com.xuliugen.weichat; import java.io.File; import java.io.IOException; import java.util.UUID; import android.media.MediaRecorder; public class AudioManager { private

  • 使用qt quick-ListView仿微信好友列表和聊天列表的示例代码

    1.视图模型介绍 在Qml中.常见的View视图有: ListView: 列表视图,视图中数据来自ListModel.XmlListModel或c++中继承自QAbstractItemModel或QAbstractListModel的自定义模型类 TableView: 和excel类似的视图 GridView: 网格视图,类似于home菜单那样,排列着一个个app小图标 PathView: 路径视图,可以根据用户自定义的path路径来显示不一样的视图效果 SwipeView: 滑动视图,使用一组

  • android 仿微信demo——登录功能实现(移动端)

    移动端登录功能实现 登录功能基本和注册一样,唯一不同的是登录可以实现两种登录方式(微信号和手机号),也就是布局不一样.所以需要两个布局,两个activity(这个方法比较简单粗暴,我懒.也可以通过activity动态切换布局,这样只需要一个activity就可以了) 创建两个activity,实现两种登录方式 微信号登录activity LoginUser.java package com.example.wxchatdemo; import android.annotation.Suppres

  • Android仿微信联系人列表字母侧滑控件

    仿微信联系人列表字母侧滑控件, 侧滑控件参考了以下博客: Android实现ListView的A-Z字母排序和过滤搜索功能 首先分析一下字母侧滑控件应该如何实现,根据侧滑控件的高度和字母的数量来平均计算每个字母应该占据的高度. 在View的onDraw()方法下绘制每一个字母 protected void onDraw(Canvas canvas) { super.onDraw(canvas); int height = getHeight();// 获取对应高度 int width = get

  • Android仿微信录制语音功能

    本文实例为大家分享了Android仿微信录制语音的具体代码,供大家参考,具体内容如下 前言 我把录音分成了两部分 1.UI界面,弹窗读秒 2.一个类(包含开始.停止.创建文件名功能) 第一部分 由于6.0权限问题,点击按钮申请权限通过则弹窗,如何申请权限 弹窗布局popw_record.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http:

  • Android仿微信底部菜单栏功能显示未读消息数量

    底部菜单栏很重要,我看了一下很多应用软件都是用了底部菜单栏,这里使用了tabhost做了一种通用的(就是可以像微信那样显示未读消息数量的,虽然之前也做过但是layout下的xml写的太臃肿,这里去掉了很多不必要的层,个人看起来还是不错的,所以贴出来方便以后使用). 先看一下做出来之后的效果: 以后使用的时候就可以换成自己项目的图片和字体了,主框架不用变哈哈, 首先是要布局layout下xml文件 main.xml: <?xml version="1.0" encoding=&qu

随机推荐