Android 仿微信联系人Demo

项目结构

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >

        <ListView
            android:id="@+id/country_lvcountry"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_gravity="center"
            android:divider="@null" />

        <TextView
            android:id="@+id/dialog"
            android:layout_width="80.0dip"
            android:layout_height="80.0dip"
            android:layout_gravity="center"
            android:background="@drawable/corner_list_single_pressed"
            android:gravity="center"
            android:textColor="#ffffffff"
            android:textSize="30.0dip"
            android:visibility="invisible" />

        <com.example.contactdemo.SideBar
            android:id="@+id/sidrbar"
            android:layout_width="30.0dip"
            android:layout_height="fill_parent"
            android:layout_gravity="right|center" />
    </FrameLayout>

</LinearLayout>

item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/catalog"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1.0"
        android:background="#E0E0E0"
        android:paddingBottom="5dip"
        android:paddingLeft="5dip"
        android:paddingTop="5dip"
        android:text="A"
        android:textColor="#454545" />

    <TextView
        android:id="@+id/title"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="5dip"
        android:layout_weight="1.0"
        android:gravity="center_vertical"
        android:paddingBottom="10dip"
        android:paddingTop="10dip"
        android:text="hhhh"
        android:textColor="#336598" />

</LinearLayout>

SideBar.java

package com.example.contactdemo;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;

public class SideBar extends View {

    private TextView textDialog;
    private OnSelectChangeListener changeListener;

    // 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();

    public SideBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public SideBar(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SideBar(Context context) {
        super(context);
    }

    public void setTextView(TextView textView) {
        this.textDialog = textView;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int width = getWidth();
        int height = getHeight();
        int singleHeight = height / b.length;
        for (int i = 0; i < b.length; i++) {
            paint.setColor(Color.rgb(33, 65, 98));
            paint.setTypeface(Typeface.DEFAULT_BOLD);
            paint.setAntiAlias(true);
            paint.setTextSize(20);
            // 选中状态
            if (i == choose) {
                paint.setColor(Color.parseColor("#3399ff"));
                paint.setFakeBoldText(true);
            }
            float x = width / 2 - paint.measureText(b[i]) / 2;
            float y = singleHeight * i + singleHeight;
            canvas.drawText(b[i], x, y, paint);
            paint.reset();
        }
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        int action = event.getAction();
        final float y = event.getY();// 点击y坐标
        int c = (int) (y / getHeight() * b.length);
        switch (action) {
        case MotionEvent.ACTION_UP:
            setBackgroundResource(R.color.alph);
            choose = -1;
            invalidate();
            if (textDialog != null)
                textDialog.setVisibility(View.INVISIBLE);
            break;

        default:
            setBackgroundColor(Color.parseColor("#28000000"));
            if (choose != c) {
                if (c >= 0 && c < b.length) {
                    if (changeListener != null)
                        changeListener.onSelectChange(b[c]);
                    if (textDialog != null) {
                        textDialog.setText(b[c]);
                        textDialog.setVisibility(View.VISIBLE);
                    }
                    choose = c;
                    invalidate();
                }
            }
            break;
        }
        return true;
    }

    public void setOnSelectChangeListener(OnSelectChangeListener listener) {
        this.changeListener = listener;
    }

    public interface OnSelectChangeListener {
        void onSelectChange(String letter);
    }
}

MyAdapter.java

package com.example.contactdemo;

import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class MyAdapter extends BaseAdapter {

    private List<MyModel> list = null;
    private Context mContext;

    public MyAdapter(List<MyModel> list, Context mContext) {
        this.list = list;
        this.mContext = mContext;
    }

    public void updateListView(List<MyModel> list) {
        this.list = list;
        notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        return this.list.size();
    }

    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View view, ViewGroup parent) {
        ViewHolder viewHolder = null;
        final MyModel mContent = list.get(position);
        if (view == null) {
            viewHolder = new ViewHolder();
            view = LayoutInflater.from(mContext).inflate(R.layout.item, null);
            viewHolder.tvTitle = (TextView) view.findViewById(R.id.title);
            viewHolder.tvLetter = (TextView) view.findViewById(R.id.catalog);
            view.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) view.getTag();
        }
        // 根据position获取分类的首字母的Char ASCII值
        int section = getAsciiForPosition(position);

        // 如果当前位置等于该分类首字母的Char的位置 ,则认为是第一次出现
        if (position == getPositionFroAscii(section)) {
            viewHolder.tvLetter.setVisibility(View.VISIBLE);
            viewHolder.tvLetter.setText(mContent.getSortLetters());
        } else {
            viewHolder.tvLetter.setVisibility(View.GONE);
        }
        viewHolder.tvTitle.setText(this.list.get(position).getName());
        return view;
    }

    /**
     * 根据位置转成首字母的ASCII
     *
     * @param position
     * @return
     */
    public int getAsciiForPosition(int position) {
        int a = list.get(position).getSortLetters().charAt(0);
        return a;
    }

    /**
     * 根据字母的ASCII获取位置
     *
     * @param ascii
     * @return
     */
    public int getPositionFroAscii(int ascii) {
        for (int i = 0; i < list.size(); i++) {
            String abc = list.get(i).getSortLetters();
            char firstChar = abc.toUpperCase().charAt(0);
            if (firstChar == ascii)
                return i;
        }
        return -1;
    }

    class ViewHolder {
        TextView tvLetter;
        TextView tvTitle;
    }
}

MainActivity.java

package com.example.contactdemo;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import com.example.contactdemo.SideBar.OnSelectChangeListener;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity {

    private SideBar sideBar;
    private TextView dialog;
    private ListView sortListView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sideBar = (SideBar) findViewById(R.id.sidrbar);
        dialog = (TextView) findViewById(R.id.dialog);
        sortListView = (ListView) findViewById(R.id.country_lvcountry);
        sideBar.setTextView(dialog);
        List<MyModel> datas = getDatas(getResources().getStringArray(R.array.data));
        Collections.sort(datas, new Comparator<MyModel>() {

            // -1代表o1里的某一个属性比o2的小 0代表等于 1代表大于
            @Override
            public int compare(MyModel o1, MyModel o2) {
                if (o1.getSortLetters().equals("#"))
                    return 1;
                else if (o2.getSortLetters().equals("#"))
                    return -1;
                else
                    return o1.getSortLetters().compareTo(o2.getSortLetters());
            }
        });
        final MyAdapter adapter = new MyAdapter(datas, this);
        sortListView.setAdapter(adapter);

        sideBar.setOnSelectChangeListener(new OnSelectChangeListener() {

            @Override
            public void onSelectChange(String letter) {
                int ascii = letter.charAt(0);
                int position = adapter.getPositionFroAscii(ascii);
                if(position!=-1)
                    sortListView.setSelection(position);
            }
        });
    }

    private List<MyModel> getDatas(String[] array) {
        List<MyModel> datas = new ArrayList<MyModel>();
        for (int i = 0; i < array.length; i++) {
            MyModel sortModel = new MyModel();
            sortModel.setName(array[i]);
            String abc = CharacterParser.getInstance().getSelling(array[i]);
            String sortString = abc.substring(0, 1).toUpperCase();
            // 正则表达式
            if (sortString.matches("[A-Z]")) {
                sortModel.setSortLetters(sortString);
            } else {
                sortModel.setSortLetters("#");
            }
            datas.add(sortModel);
        }
        return datas;
    }
}

源码下载

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-08 12:24:47

Android 仿微信联系人Demo的相关文章

【Android 仿微信通讯录 导航分组列表-上】使用ItemDecoration为RecyclerView打造带悬停头部的分组列表

[Android 仿微信通讯录 导航分组列表-上]使用ItemDecoration为RecyclerView打造带悬停头部的分组列表 一 概述 本文是Android导航分组列表系列上,因时间和篇幅原因分上下,最终上下合璧,完整版效果如下: 上部残卷效果如下:两个ItemDecoration,一个实现悬停头部分组列表功能,一个实现分割线(官方demo) 网上关于实现带悬停分组头部的列表的方法有很多,像我看过有主席的自定义ExpandListView实现的,也看过有人用一个额外的父布局里面套 Rec

Android仿微信朋友圈图片浏览器(支持图片手势缩放,拖动)

※效果 ※使用到的开源库 PhotoView 图片缩放:支持双击缩放,手指捏拉缩放 https://github.com/chrisbanes/PhotoView Universalimageloader 图片下载缓存库 https://github.com/nostra13/Android-Universal-Image-Loader ViewPagerIndicator 分页指示器 https://github.com/JakeWharton/Android-ViewPagerIndicat

Android 仿微信朋友圈发动态功能(相册图片多选)

代码分享 代码名称: 仿微信朋友圈发动态功能(相册图片多选) 代码描述: 仿微信朋友圈发动态功能(相册图片多选) 代码托管地址: http://www.apkbus.com/android-152760-1-1.html 代码作者: 楼主 代码效果图: 本帖最后由 ^.^ 于 2014-7-8 16:23 编辑 <ignore_js_op> <ignore_js_op> <ignore_js_op> DEMO一共13个类 大约2000行代码,童鞋们耐心点看基本思路是:1

Android仿微信UI布局视图(圆角布局的实现)

圆角按钮,或布局可以在xml文件中实现,但也可以使用图片直接达到所需的效果,以前版本的微信就使用了这种方法. 实现效果图:    不得不说,这种做法还是比较方便的. 源代码: MainActivity(没写任何代码,效果全在布局文件中实现): package com.android_settings; import android.app.Activity; import android.os.Bundle; public class MainActivity extends Activity

Android仿微信下拉列表实现

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 本文要实现微信6.1中点击顶部菜单栏的"+"号按钮时,会弹出一个列表框.这里用的了Activity实现,其实最好的方法可以用ActionBar,不过这货好像只支持3.0以后的版本.本文的接上文Android仿微信底部菜单栏+顶部菜单栏(附源码) 效果: 一.仿微信下拉列表布局pop_dialog.xml <?xml version="1.0" encodi

带中文索引的ListView 仿微信联系人列表

由于各种原因,项目经理和产品经理把我做的东西给否定了,所以决定分享出去. 主要功能: 1 .带中文索引的ListView 2.自定义顶部搜索视图,可以对返回按钮,搜索按钮添加事件监听,带动画的咧!~ 3.底部自定义视图,可以对Listview的adapter添加监听,并且回调选中的数目,另外其他的视图都是可以自己添加的 4.右侧的索引视图,根据通讯录的解析后的数据动态生成相关索引列表 5.Adapter的抽象类,想优化自己的Adapter可以看一下,例子中的adapter仅仅是特例特写. 6.分

android必学的两个项目,android仿京东、android仿微信项目(后期持续更新)

本着学习的态度,当前栏目本人上传的资源一概不需要资源下载分 这里分享两个学习android的项目: 1.android仿微信项目,源码地址:http://download.csdn.net/detail/a358763471/8702533 2.android仿京东商城项目,源码地址:http://download.csdn.net/detail/a358763471/8702393

Android仿微信语音聊天

完整代码下载地址: Android仿微信语音聊天 效果图: 分析: 1.自定义Button中要复写onTouchEvent的DOWN,MOVE,UP三种状态,对正常按下,想要取消发送,抬起三种动作进行侦听处理. 2.Dialog共有三种状态,除上图所示的两种外,还有一个录音时间过短的提示.其中录音状态中的音量可以变化. 3.显示录音的ListView的item中有一个录音时长(TextView),一个播放动画(View)和一个头像(ImageView). 4.录音类里有两个成员:录音长度,录音路

腾讯大牛动态教学:Android 仿微信 QQ 图片裁剪,赶紧收藏起来!

前言 在平时开发中,经常需要实现这样的功能,拍照 - 裁剪,相册 - 裁剪.当然,系统也有裁剪的功能,但是由于机型,系统兼容性等问题,在实际开发当中,我们通常会自己进行实现.今天,就让我们一起来看看怎样实现. 这篇博客实现的功能主要有仿微信,QQ 上传图像裁剪功能,包括拍照,从相册选取.裁剪框的样式有圆形,正方形,九宫格. 主要讲解的功能点 使用说明 整体的实现思路 裁剪框的实现 图片缩放的实现,包括放大,缩小,移动,裁剪等 我们先来看看我们实现的效果图 使用说明 有两种调用方式 第一种 第一种