Android仿微信联系人字母排序效果

本文实例为大家分享了Android联系人字母排序的具体代码,供大家参考,具体内容如下

实现思路:首先说下布局,整个是一个相对布局,最下面是一个listview,listview上面是一个自定义的view(右边显示字母),最上面是一个textview(屏幕中间的方块)。

首先说一下右边自定义view,字母是画到view上面的,首先计算一下view的高度,然后除以存放字母数组的长的,得到每个字符的高度;每个字母的宽度都是一样的,所以这里直接设置30sp;

listview显示的是108个梁山好汉的名字;

项目里面使用了一个pinyin4j.jar把每个名字转换为拼音,然后使用charAt(0)获得拼音的第一个字母;

listview的每个item是一个线性布局包裹的两个textview,上面的tv显示的是拼音的第一个字母,下面的tv显示的就是名字;在adapter判断当前条目和上一个条目的拼音首字母是否相同,如果相同隐藏当前item上面的tv;

然后在自定义view设置一个自定义监听;当点击自定义view的时候根据高度判断当前点击的是那个字母,然后根据字母设置listview要跳转的位置;

首先看下布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent" > 

  <ListView
    android:id="@+id/listview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:cacheColorHint="@android:color/transparent" >
  </ListView> 

  <com.wxcontacts.www.view.QuickIndexBar
    android:id="@+id/quickindexbar"
    android:layout_width="30dp"
    android:layout_height="match_parent"
    android:layout_alignParentRight="true"
     /> 

  <!-- 默认隐藏,当点击自定义view的时候显示 -->
  <TextView
    android:visibility="gone"
    android:id="@+id/tv_hint"
    android:gravity="center"
    android:layout_centerInParent="true"
    android:layout_width="60dp"
    android:layout_height="60dp"
    android:background="@drawable/bg_text"
    android:text="A"
    android:textSize="24sp"/> 

</RelativeLayout>

先不着急看MainActivity代码首先看下自定义view的代码:

//自定义view
public class QuickIndexBar extends View{ 

  //画笔
  private Paint paint; 

  String[] lettres={"↑","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","↓"}; 

  //自定义view的宽高
  private int viewHight;
  private int viewWidth;
  //每个文本的高度;(文本高度等于view高度除以文本个数)
  private int cellHeight; 

  //文本的高度
  private float textHeight; 

  private int currentIndex=-1; 

  public OnLetterChangeListen onLetterChangeListen; 

  public OnLetterChangeListen getOnLetterChangeListen(){
    return onLetterChangeListen;
  } 

  public void setOnLetterChangeListener(OnLetterChangeListen onLetterChangeListen){
    this.onLetterChangeListen=onLetterChangeListen;
  }
  //自定义一个字母改变的监听
  public interface OnLetterChangeListen{
    void onLetterChange(String letter);
    void onResert();
  } 

  public QuickIndexBar(Context context) {
    this(context,null);
  }
  public QuickIndexBar(Context context, AttributeSet attrs) {
    this(context, attrs,0);
  } 

  public QuickIndexBar(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    paint=new Paint();
    //设置字体颜色;默认为黑色;我们这里使用黑色
    //paint.setColor(Color.WHITE);
    //设置字体大小
    paint.setTextSize(20);
    //抗锯齿
    paint.setAntiAlias(true);
    //获取字体宽高,因为每个字体宽度不一样,所以获得宽度必须放在循环中做
    //首先获取字体的属性
    FontMetrics fontMetrics = paint.getFontMetrics();
    //下边界 - 上边界
    textHeight = (float) Math.ceil(fontMetrics.descent-fontMetrics.ascent);
  } 

  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //获取文本的宽高
//   getTextWH();
    //每个文本的高度;
    cellHeight=viewHight/lettres.length; 

    //通过循环把字母画出来
    for(int x=0;x<lettres.length;x++){
      String text=lettres[x]; 

      //paint给我们提供了一个测量字体宽度的方法
      float textWidth = paint.measureText(text);
      if(currentIndex==x){
        //当点击某个字母的时候变色
        paint.setColor(Color.GRAY);
      }else{
        paint.setColor(Color.BLACK);
      } 

      /*
       * 参数1:要画的内容   参数23:要画的位置   参数4:画笔
       * 参数23所画的位置指的是字母左下角坐标
       */
      canvas.drawText(text,viewWidth/2-textWidth/2,cellHeight/2+textHeight/2+cellHeight*x,paint);
    } 

  } 

  //测量view的宽高
  @Override
  protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    viewHight =getMeasuredHeight();
    viewWidth =getMeasuredWidth();
  } 

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) { 

    case MotionEvent.ACTION_DOWN:
      //计算当前点击的字母,宽度不用考虑,因为宽度都是一样的,计算高度即可,根据你点击或者移动的高度计算你当前所点击的是哪个字母
      float downY=event.getY();
      currentIndex = (int)downY/cellHeight;
      if(currentIndex<0 || currentIndex>lettres.length-1){
      }else{
        if(onLetterChangeListen!=null){
          onLetterChangeListen.onLetterChange(lettres[currentIndex]);
        }
      }
      //重新绘制;相当于重新调用onDraw()方法
      invalidate();
      break;
    case MotionEvent.ACTION_MOVE:
      float moveY=event.getY();
      currentIndex = (int)moveY/cellHeight;
      if(currentIndex<0 || currentIndex>lettres.length-1){
      }else{
        if(onLetterChangeListen!=null){
          onLetterChangeListen.onLetterChange(lettres[currentIndex]);
        }
      }
      //重新绘制
      invalidate();
      break;
    case MotionEvent.ACTION_UP:
      currentIndex=-1;
      if(onLetterChangeListen!=null){
        onLetterChangeListen.onResert();
      }
      break; 

    default:
      break;
    }
    return true;
  } 

}

下面我为大家准备了一张计算字母xy坐标的图片:

最后是MainActivity的代码:

public class MainActivity extends Activity { 

  private com.wxcontacts.www.view.QuickIndexBar quickIndexBar;
  private ListView mListView;
  //当点击自定义view的时候屏幕中间显示一个方块,显示当前点击的字母,默认是隐藏的,当点击的时候才显示
  private TextView tvHint; 

  private List<HaoHan> hhList=new ArrayList<HaoHan>();
  Context context;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_main);
    tvHint=(TextView) findViewById(R.id.tv_hint);
    context=this;
    //listview 和 自定义view
    mListView=(ListView) findViewById(R.id.listview);
    quickIndexBar=(QuickIndexBar) findViewById(R.id.quickindexbar); 

    initHHListData(); 

    mListView.setAdapter(new MainListViewAdapter(context,hhList)); 

    //给自定义view设置自定义监听,当点击到某个字母的时候弹出吐司显示这个字母;
    //当点击字母的时候遍历集合,找到首字母为点击字母的HaoHan的下标,让listview跳转到响应位置
    quickIndexBar.setOnLetterChangeListener(new QuickIndexBar.OnLetterChangeListen() { 

      @Override
      public void onLetterChange(String letter) { 

        quickIndexBar.setBackgroundResource(R.drawable.bg_text); 

        tvHint.setVisibility(View.VISIBLE);
        tvHint.setText(letter); 

        for(int x=0;x<hhList.size();x++){
          if((hhList.get(x).pinyin.charAt(0)+"").equals(letter)){
            mListView.setSelection(x);
            //找到第一个字母相同的直接结束,不再向下找;
            break;
          }
        }
      } 

      @Override
      //当手指弹起的时候此方法执行
      public void onResert() {
        tvHint.setVisibility(View.GONE);
        quickIndexBar.setBackgroundResource(Color.TRANSPARENT);
      }
    });
  } 

  //初始化集合数据
  private void initHHListData() { 

    HaoHan hh;
    for(int x=0;x<Cheeses.NAMES.length;x++){
      hh=new HaoHan(Cheeses.NAMES[x]);
      hhList.add(hh);
    } 

    //给集合排序
    Collections.sort(hhList); 

  } 

}

源码下载:http://xiazai.jb51.net/201611/yuanma/AndroidWXcontact(jb51.net).rar

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android实现ListView的A-Z字母排序和过滤搜索功能 实现汉字转成拼音

    直入主题,今天给大家带来ListView的A-Z字母排序和过滤搜索功能并且实现汉字转成拼音的功能,我们知道一般我们对联系人,城市列表等实现A-Z的排序,因为联系人和城市列表我们可以直接从数据库中获取他的汉字拼音,而对于一般的数据,我们怎么实现A-Z的排序,我们需要将汉字转换成拼音就行了,接下来就带大家实现一般数据的A-Z排序功能,首先先看下效果图 上面是一个带删除按钮的EditText,我们在输入框中输入可以自动过滤出我们想要的东西,当输入框中没有数据自动替换到原来的数据列表,然后下面一个Lis

  • Android 限制edittext 整数和小数位数 过滤器(详解)

    写了一个过滤器,根据需要限制edittext输入的整数和小数位,如下代码: package allone.verbank.apad.client.component; import android.text.InputFilter; import android.text.Spanned; /** * * @Title: ComponentDigitCtrlFilter.java * @Package allone.verbank.apad.client.component * @Descrip

  • android实现汉字转拼音功能 带多音字识别

    android 汉字转拼音带多音字识别功能,供大家参考,具体内容如下 问题来源 在做地名按首字母排序的时候出现了这样一个bug.长沙会被翻译拼音成zhangsha,重庆会被翻译拼音成zhong qing.于是排序出了问题. 汉字转拼音库和多音字识别库 1.多音字对应的词汇库 2.文字的二进制大小对应的拼音库 关键代码 1.我在这里首先将要转化的文字转化成对应的"gb2312"编码.汉字转化成二进制编码一般占两个字节,如果一个字节返回字符,如果是两个字节算一下偏移量.代码如下 /** *

  • Android仿微信联系人按字母排序

    App只要涉及到联系人的界面,几乎都是按照字母排序以及导航栏的方式.既然这个需求这么火,于是开始学习相关内容,此篇文章是我通过参考网上资料独立编写和总结的,希望多多少少对大家有所帮助,写的不好,还请各位朋友指教. 效果图如下: 实现这个效果,需要三个知识点 : 1:将字符串 进行拼音分类 2:ExpandableListView 二级扩展列表 3:右边字母分类View 我们先一个一个来了解解决方案,再上代码. 实现字母分类: 字母分类又分为三个小要点:一个是将中文转化为拼音,一个是实现按照字母的

  • Android编程之TextView的字符过滤功能分析

    本文实例分析了Android编程之TextView的字符过滤功能.分享给大家供大家参考,具体如下: TextView可以设置接受各式各样的字符,通过过滤指定的字符来满足不同应用的输入和显示要求. 通过xml配置: android:InputType number          接受整数输入 numberSigned    接受有符号整数输入 numberDecimal   接受整数和小数的输入 android:digits 指定接受固定的数字,如android:digits="012345&

  • Android仿微信联系人字母排序效果

    本文实例为大家分享了Android联系人字母排序的具体代码,供大家参考,具体内容如下 实现思路:首先说下布局,整个是一个相对布局,最下面是一个listview,listview上面是一个自定义的view(右边显示字母),最上面是一个textview(屏幕中间的方块). 首先说一下右边自定义view,字母是画到view上面的,首先计算一下view的高度,然后除以存放字母数组的长的,得到每个字符的高度:每个字母的宽度都是一样的,所以这里直接设置30sp: listview显示的是108个梁山好汉的名

  • Android仿微信页面底部导航效果代码实现

    大家在参考本地代码的时候要根据需要适当的修改,里面有冗余代码小编没有删除.好了,废话不多说了,一切让代码说话吧! 关键代码如下所示: .java里面的主要代码 public class MainActivity extends BaseActivity implements TabChangeListener { private Fragment[] fragments; private FragZaiXianYuYue fragZaiXianYuYue; private FragDaoLuJi

  • Android仿微信长按菜单效果

    本文实例为大家分享了Android仿微信长按菜单展示的具体代码,供大家参考,具体内容如下 FloatMenu A menu style pop-up window that mimics WeChat.仿微信的长按菜单. 效果如下 引入方法: Github地址:https://github.com/JavaNoober/FloatMenu dependencies { .... compile 'com.noober.floatmenu:common:1.0.2' } 使用说明 使用方法1: A

  • Android 仿微信底部渐变Tab效果

    先来看一下效果图 除了第三个的发现Tab有所差别外,其他的基本还原了微信的底部Tab渐变效果 每个Tab都是一个自定义View,根据ImageView的tint属性来实现颜色渐变效果,tint属性的使用可以看我的上一篇文章 我将自定义View命名为ShadeView,包含四个自定义属性 意思分别为图标.背景色.底部文本.底部文本大小 <declare-styleable name="ShadeView"> <attr name="icon" for

  • Android仿微信文章悬浮窗效果的实现代码

    序言 前些日子跟朋友聊天,朋友Z果粉,前些天更新了微信,说微信出了个好方便的功能啊,我问是啥功能啊,看看我大Android有没有,他说现在阅读公众号文章如果有人给你发微信你可以把这篇文章当作悬浮窗悬浮起来,方便你聊完天不用找继续阅读,听完是不是觉得这叫啥啊,我大Android微信版不是早就有这个功能了吗,我看文章的时候看到过有这个悬浮按钮,但是我一直没有使用过,试了一下还是挺方便的,就想着自己实现一下这个功能,下面看图,大家都习惯了无图言X 原理 看完动图我们来分析一下,如何在每个页面上都存在一

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

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

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

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

  • Android仿微信activity滑动关闭效果

    Android仿微信activity滑动关闭功能 1.利用具体利用v4包下的slidingPaneLayout实现透明的activity,代码如下: BaseActivity: public class BaseSlideCloseActivity extends AppCompatActivity implements SlidingPaneLayout.PanelSlideListener { @Override protected void onCreate(Bundle savedIns

  • Android仿微信顶/底部菜单栏效果

    本文要实现仿微信微信底部菜单栏+顶部菜单栏,采用ViewPage来做,每一个page对应一个XML,当手指在ViewPage左右滑动时,就相应显示不同的page(其实就是xml)并且同时改变底部菜单按钮的图片变暗或变亮,同时如果点击底部菜单按钮,左右滑动page(其实就是xml)并且改变相应按钮的亮度. 一.布局 1.顶部菜单布局,命名为top_layout.xml <?xml version="1.0" encoding="utf-8"?> <R

随机推荐