Android开发制作带有侧边栏的联系人列表

首先需要下载pinyin4j-2.5.0.jar包,这是下载链接https://sourceforge.net/projects/pinyin4j/,下载完成之后在lib文件夹下面能够找到该jar包。

1,先自定义一个IndexView:


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
/*
* 1,绘制26个字母。分为以下几步:1,把26个字母放入数组中,2,itemView和Wordtext的宽度和高度
* itemViewWidth=viewWith;
* itemViewHeight=viewHeight/26;
* wordWidth=(自定义一个矩形).getWidth();
* wordHeight=(自定义一个矩形).getHeight();
* 自定义矩形Rect rect=new Rect();
*
*按下手指变色
* */

public class IndexView extends View {

    private String[] words={"A","B","C","D","E","F","G","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 itemWidth;
    private int itemHeight;
    private Paint paint;
    private int touchIndex=-1;

    public IndexView(Context context,AttributeSet attrs) {
        super(context, attrs);
        paint=new Paint();
        paint.setColor(Color.WHITE);//设置画笔的颜色为白色
        paint.setTextSize(30);
        paint.setAntiAlias(true);//这只抗锯齿
        paint.setTypeface(Typeface.DEFAULT_BOLD);//设置粗体字
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        itemWidth=getMeasuredWidth();
        itemHeight=getMeasuredHeight()/words.length;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

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

            //字母变色
            if (touchIndex==i){
                //让当前字母变色
                paint.setColor(Color.GRAY);
            }else {
                //其他字母不变色
                paint.setColor(Color.WHITE);
            }

            String word=words[i];
            Rect rect=new Rect();
            paint.getTextBounds(word,0,1,rect);
            int wordWidth=rect.width();
            int wordHeight=rect.height();
            //计算每个字母在视图上的坐标位置
            float wordX=itemWidth/2-wordWidth/2;
            float wordY=itemHeight/2+wordHeight/2+i*itemHeight;
            canvas.drawText(word,wordX,wordY,paint);
        }
    }

    /*
    * 点击变色
    * 1,在down  move中得到点击那个字母height/itemHeight
    * 2,up的时候再次绘制
    * */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
                float Y=event.getY();
                int index= (int) (Y/itemHeight);//字母的索引
                if (index!=touchIndex){
                    touchIndex=index;
                    //点击设置中间字母
                    if (onClickShowWord!=null&&touchIndex<words.length){
                        onClickShowWord.OnIndexChange(words[touchIndex]);
                    }
                    invalidate();
                }
                break;
            case MotionEvent.ACTION_UP:
                touchIndex=-1;
                invalidate();
                break;
        }
        return true;
    }

    private OnIndexChangeListener onClickShowWord;
    public void setOnIndexChangeListener(OnIndexChangeListener l){
        onClickShowWord=l;
    }
    //定义一个借口,实现点击字母,就再屏幕中央出现相应字母
    public interface OnIndexChangeListener{
        void OnIndexChange(String word);
    }
}

MAinActivity代码:


import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

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

public class MainActivity extends AppCompatActivity {

    private Handler handler=new Handler();
    private List<Person> personList;

    private TextView textView_center;
    private IndexView indexView;
    private ListView listView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView_center=findViewById(R.id.tv_word);
        indexView=findViewById(R.id.iv_words);
        listView=findViewById(R.id.lv_main);

        personList=new ArrayList<>();
        initData();

        //点击字母回调实现屏幕中间显示字体
        indexView.setOnIndexChangeListener(new IndexView.OnIndexChangeListener() {
            @Override
            public void OnIndexChange(String word) {
                textView_center.setVisibility(View.VISIBLE);
                textView_center.setText(word);
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        textView_center.setVisibility(View.GONE);
                    }
                }, 1000);
                //点击右边字母进行定位,但是这是定位到最后一个
                for (int i=0;i<personList.size();i++){
                    if (word.equals(personList.get(i).getPinyin().substring(0,1))){
                        listView.setSelection(i);
                        return;//return表示一旦满足这个条件就不再往下循环了,也就是定位到了最后一个
                    }
                }
            }
        });

        listView.setAdapter(new MyAdapter());


    }

    class MyAdapter extends BaseAdapter{

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

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

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

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHloder viewHloder;
            if (convertView==null){
                convertView=View.inflate(MainActivity.this,R.layout.per_item,null);
                viewHloder=new ViewHloder();
                viewHloder.tv_content=convertView.findViewById(R.id.tv_content);
                viewHloder.tv_title=convertView.findViewById(R.id.tv_title);
                convertView.setTag(viewHloder);
            }else {
                viewHloder= (ViewHloder) convertView.getTag();
            }
            Person person=personList.get(position);
            String name=person.getName();
            String word=person.getPinyin().substring(0,1);
            if (position==0){
                viewHloder.tv_title.setVisibility(View.VISIBLE);
                viewHloder.tv_title.setText(word);
            }else {
                if (position>0&&word.equals(personList.get(position-1).getPinyin().substring(0,1))){
                    viewHloder.tv_title.setVisibility(View.GONE);
                }else {
                    viewHloder.tv_title.setVisibility(View.VISIBLE);
                    viewHloder.tv_title.setText(word);
                }
            }
            viewHloder.tv_content.setText(name);
            return convertView;
        }
    }
    class ViewHloder{
        private TextView tv_title;
        private TextView tv_content;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                Log.e("cylog","MainActivity dispatchTouchEvent down");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.e("cylog","MainActivity dispatchTouchEvent move");
                break;
            case MotionEvent.ACTION_UP:
                Log.e("cylog","MainActivity dispatchTouchEvent up");
                break;
        }       return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                Log.e("cylog","MainActivity onTouchEvent down");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.e("cylog","MainActivity onTouchEvent move");
                break;
            case MotionEvent.ACTION_UP:
                Log.e("cylog","MainActivity onTouchEvent up");
                break;
        }
        return super.onTouchEvent(event);
    }

    private void initData(){
        personList.add(new Person("白居易"));
        personList.add(new Person("尚小碗"));
        personList.add(new Person("岳飞"));
        personList.add(new Person("金兀术"));
        personList.add(new Person("钱钟书"));
        personList.add(new Person("陈寅恪"));
        personList.add(new Person("唐僧僧"));
        personList.add(new Person("孙物控"));
        personList.add(new Person("沙和尚"));
        personList.add(new Person("猪刚鬣"));
        personList.add(new Person("赵构"));
        personList.add(new Person("李世民"));
        personList.add(new Person("周文王"));
        personList.add(new Person("吴法克"));
        personList.add(new Person("马克龙"));
        personList.add(new Person("特奥朗"));
        personList.add(new Person("郎平"));
        personList.add(new Person("溥仪"));
        personList.add(new Person("曾国藩"));
        personList.add(new Person("周恩来"));
        personList.add(new Person("毛泽东"));
        personList.add(new Person("刘少奇"));
        personList.add(new Person("张之洞"));
        personList.add(new Person("杨绛"));
        personList.add(new Person("商客云"));
        personList.add(new Person("张壁画"));
        personList.add(new Person("王晓敏"));
        personList.add(new Person("王强"));
        personList.add(new Person("商丘人"));
        personList.add(new Person("李隆基"));

        Collections.sort(personList, new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                return o1.getPinyin().compareTo(o2.getPinyin());
            }
        });
    }
}

3.main_activity:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <ListView
        android:id="@+id/lv_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    <TextView
        android:id="@+id/tv_word"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:background="#44000000"
        android:gravity="center"
        android:layout_centerInParent="true"
        android:text="A"
        android:textSize="30sp"
        android:textColor="#000"
        android:visibility="gone"/>
    <com.example.didi.pull_downproject.IndexView
        android:id="@+id/iv_words"
        android:layout_width="30dp"
        android:layout_height="match_parent"
        android:layout_alignParentRight="true"
        android:background="#f00"/>

</RelativeLayout>

4,Person代码:


public class Person {
    private String name;
    private String pinyin;

    public Person(String name) {
        this.name = name;
        this.pinyin=PinYinUtils.getPinYin(this.name);
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setPinyin(String pinyin) {
        this.pinyin = pinyin;
    }

    public String getName() {
        return name;
    }

    public String getPinyin() {
        return pinyin;
    }
}

5,PinYinUtils类:


import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

public class PinYinUtils {
    /*
    * 得到指定汉字的拼音,注意此类不能被频繁使用,消耗内存*/
    public static String getPinYin(String hanzi){
            String pinyin="";
            HanyuPinyinOutputFormat format=new HanyuPinyinOutputFormat();
            format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
            format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);

            //把多个汉字转换成数组形式
            char[] arry=hanzi.toCharArray();
            for (int i=0;i<arry.length;i++){
                if (Character.isWhitespace(arry[i])){
                    continue;
                }
                //汉字是两个字节存储,长度肯定大于127,所以长度大于127就可以转换成汉字
                if (arry[i]>127){
                    //由于有多音字的存在,如"单shan  单dan"
                    try {
                        String[] pinyinArr=PinyinHelper.toHanyuPinyinStringArray(arry[i],format);
                        if (pinyinArr!=null){
                            pinyin += pinyinArr[0];
                        }else {
                            pinyin += arry[i];
                        }
                    } catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) {
                        badHanyuPinyinOutputFormatCombination.printStackTrace();
                        pinyin += arry[i];
                    }
                }else {
                    //不是汉字
                    pinyin += arry[i];
                }
            }
            return pinyin;
    }
}

6,per_item.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="5dp">
    <TextView
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="35dp"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:background="#44000000"
        android:textSize="20sp"
        android:visibility="gone"
        android:gravity="center_vertical"
        android:text="N"/>
    <TextView
        android:id="@+id/tv_content"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:gravity="center_vertical"
        android:layout_below="@+id/tv_title"
        android:text="春花秋月"
        android:textSize="25sp"
        android:textColor="#000000"
        android:layout_marginTop="2dp"/>

</RelativeLayout>

7,使用到的pinyin4j-2.5.0.jar包:

发布了75 篇原创文章 · 获赞 31 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/yaoyaoyao_123/article/details/90300128
今日推荐