Android通訊錄簡單實現

類似於Android中通訊錄的實現

開發中難免會遇到類似於通訊錄的開發,做出來供大家參考。
實現圖
在這裏插入圖片描述
圖一爲點擊右方的字母實現圖,鏈表會到F的那個條目
圖二爲效果圖

具體代碼
這裏需要導入一個 pinyin4j-2.5.0.jar 包是將漢字轉爲拼音的jar包和一個 nineoldandroids-2.4.0.jar包這是我的代碼中用的一個動畫效果

首先主頁面
QuickIndexBarActivity.java

package com.example.custom_view;

import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.Window;
import android.widget.ListView;
import android.widget.TextView;

import com.nineoldandroids.view.ViewHelper;
import com.nineoldandroids.view.ViewPropertyAnimator;

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

public class QuickIndexBarActivity extends AppCompatActivity {

    private MyQuickIndexBar mQuickIndexBar;
    private ListView mLv;
    private List<PinYinInfo> list = new ArrayList<PinYinInfo>();
    private TextView mTv_window;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_quick_index_bar);
        initView();

    }

    private void initView() {
        mLv = findViewById(R.id.lv);
        mTv_window = findViewById(R.id.tv_window);
        mQuickIndexBar = findViewById(R.id.my_quickIndexbar);
        list = getStrList();
        Collections.sort(list);
        MyAdapter adapter = new MyAdapter(QuickIndexBarActivity.this, list);
        mLv.setAdapter(adapter);
        mQuickIndexBar.setOnItemtClickListenner(new MyQuickIndexBar.onItemClickListenner() {
            @Override
            public void getOnImtemPosition(String letter) {
                for (int i = 0; i < list.size(); i++) {
                    String strLetter = list.get(i).getmPinYinName().charAt(0) + "";
                    if (letter.equalsIgnoreCase(strLetter)) {
                        mLv.setSelection(i);
                        break;
                    }
                }
                showCurrentTvWindow(letter);
            }
        });
        ViewHelper.setScaleX(mTv_window, 0F);
        ViewHelper.setScaleY(mTv_window, 0F);
    }


    private Handler mHandler = new Handler();
    private boolean mFlag;

    private void showCurrentTvWindow(String letter) {
        if (!mFlag) {
            mFlag = true;
            ViewPropertyAnimator.animate(mTv_window).setDuration(450).scaleX(1.0F).start();
            ViewPropertyAnimator.animate(mTv_window).setDuration(450).scaleY(1.0F).start();
        }
        mTv_window.setText(letter);
        mHandler.removeCallbacksAndMessages(null);
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                mFlag = false;
                ViewPropertyAnimator.animate(mTv_window).setDuration(450).scaleX(0.0F).start();
                ViewPropertyAnimator.animate(mTv_window).setDuration(450).scaleY(0.0F).start();
            }
        }, 2000);
    }

    public List<PinYinInfo> getStrList() {
        list.add(new PinYinInfo("北京"));
        list.add(new PinYinInfo("深圳"));
        list.add(new PinYinInfo("廣州"));
        list.add(new PinYinInfo("天津"));
        list.add(new PinYinInfo("河北"));
        list.add(new PinYinInfo("河南"));
        list.add(new PinYinInfo("山西"));
        list.add(new PinYinInfo("湖北"));
        list.add(new PinYinInfo("湖南"));
        list.add(new PinYinInfo("遼寧"));
        list.add(new PinYinInfo("上海"));
        list.add(new PinYinInfo("寧夏"));
        list.add(new PinYinInfo("內蒙古"));
        list.add(new PinYinInfo("重慶"));
        list.add(new PinYinInfo("四川"));
        list.add(new PinYinInfo("貴州"));
        list.add(new PinYinInfo("吉林"));
        list.add(new PinYinInfo("廣西"));
        list.add(new PinYinInfo("陝西"));
        list.add(new PinYinInfo("新疆"));
        list.add(new PinYinInfo("黑龍江"));
        list.add(new PinYinInfo("福建"));
        list.add(new PinYinInfo("江蘇"));
        list.add(new PinYinInfo("江西"));
        list.add(new PinYinInfo("安徽"));
        list.add(new PinYinInfo("大連"));
        list.add(new PinYinInfo("鄂爾多斯"));
        list.add(new PinYinInfo("東莞"));
        list.add(new PinYinInfo("滄州"));
        list.add(new PinYinInfo("長春"));
        list.add(new PinYinInfo("成都"));
        list.add(new PinYinInfo("海南"));
        list.add(new PinYinInfo("香港"));
        list.add(new PinYinInfo("北小營"));
        list.add(new PinYinInfo("臺灣"));
        list.add(new PinYinInfo("保定"));
        list.add(new PinYinInfo("包頭"));
        list.add(new PinYinInfo("北海"));
        list.add(new PinYinInfo("澳門"));
        list.add(new PinYinInfo("安陽"));
        list.add(new PinYinInfo("鞍山"));
        list.add(new PinYinInfo("西藏"));
        list.add(new PinYinInfo("安慶"));
        list.add(new PinYinInfo("浙江"));
        list.add(new PinYinInfo("雲南"));
        list.add(new PinYinInfo("甘肅"));
        list.add(new PinYinInfo("山東"));
        return list;
    }
}

activity_quick_index_bar.class

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


    <ListView
        android:id="@+id/lv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:divider="@color/colorPrimaryDark"
        android:dividerHeight="0.1dp"
        android:scrollbars="none"></ListView>

    <com.example.custom_view.MyQuickIndexBar
        android:id="@+id/my_quickIndexbar"
        android:layout_width="30dp"
        android:layout_height="match_parent"
        android:layout_alignParentRight="true"
        android:background="#FF00FF" />


    <TextView
        android:id="@+id/tv_window"
        android:layout_width="115dp"
        android:layout_height="115dp"
        android:layout_centerInParent="true"
        android:background="@drawable/tv_window_bg"
        android:gravity="center"
        android:text="A"
        android:textSize="40sp"
        android:textStyle="bold" />


</RelativeLayout>

佈局中MyQuickIndexBar會報錯,這就得看你創的項目名了,自己根據情況修改。

MyQuickIndexBar.java

package com.example.custom_view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
public class MyQuickIndexBar extends View {
    private String[] mStrArr = {"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"};

    public MyQuickIndexBar(Context context) {
        this(context, null);
    }

    public MyQuickIndexBar(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyQuickIndexBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }


    private int mWidth;
    private float mCellHeight;

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = getMeasuredWidth();
        mCellHeight = getMeasuredHeight() * 1F / mStrArr.length;
    }

    private Paint mPaint;

    private void init() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.BLACK);
        //以文本的中心線爲起始點開始繪製文本
        mPaint.setTextAlign(Paint.Align.CENTER);
        mPaint.setTextSize(50);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        for (int i = 0; i < mStrArr.length; i++) {
            float x = mWidth / 2;
            float y = mCellHeight / 2 + getTextHeight(mStrArr[i]) / 2 + i * mCellHeight + 10;
            mPaint.setColor(mLastIndex == i ? Color.parseColor("#FFFF00") : Color.BLACK);
            canvas.drawText(mStrArr[i], x, y, mPaint);
        }
        super.onDraw(canvas);
    }

    private float getTextHeight(String text) {
        Rect rect = new Rect();
        mPaint.getTextBounds(text, 0, text.length(), rect);
        return rect.bottom;
    }


    private int mLastIndex = -1;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
                int index = (int) (event.getY() / mCellHeight);
                if (index>-1&&index<mStrArr.length) {
                    Log.e("wew", mStrArr[index] + "");
                    if (mListenner != null) {
                        mListenner.getOnImtemPosition(mStrArr[index]);
                    }
                }
                mLastIndex = index;
                break;
            case MotionEvent.ACTION_UP:
                Log.e("assaas", "action_up");
                mLastIndex = -1;
                break;

        }
        //重繪 (重新繪製View)
        invalidate();
        return true;
    }


    private onItemClickListenner mListenner;

    public interface onItemClickListenner {
        void getOnImtemPosition(String letter);
    }

    public void setOnItemtClickListenner(onItemClickListenner listenner) {
        this.mListenner = listenner;
    }


}

MyAdapter.java

package com.example.custom_view;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import java.util.List;
public class MyAdapter extends BaseAdapter {
    private Context mContext;
    private List<PinYinInfo> mList;

    public MyAdapter(Context context, List<PinYinInfo> strList) {
        this.mContext = context;
        this.mList = strList;

    }

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

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null)
            convertView = View.inflate(mContext, R.layout.list_item, null);
        ViewHolder viewHolder = ViewHolder.getViewHolder(convertView);

        String currentStrLetter = mList.get(position).getmPinYinName().charAt(0) + "";

        if (position > 0) {
            String lastStrLetter = mList.get(position - 1).getmPinYinName().charAt(0) + "";

            if (lastStrLetter.equals(currentStrLetter)) {
                viewHolder.tv_letter.setVisibility(View.GONE);
            } else {
                viewHolder.tv_letter.setText(currentStrLetter);
                viewHolder.tv_letter.setVisibility(View.VISIBLE);
            }
        } else {
            viewHolder.tv_letter.setText(currentStrLetter);
            viewHolder.tv_letter.setVisibility(View.VISIBLE);
        }
        viewHolder.tv_name.setText(mList.get(position).getmName());
        return convertView;
    }


    public static class ViewHolder {
        private TextView tv_letter, tv_name;

        public ViewHolder(View convertView) {
            tv_letter = convertView.findViewById(R.id.tv_letter);
            tv_name = convertView.findViewById(R.id.tv_name);
        }

        public static ViewHolder getViewHolder(View convertView) {
            ViewHolder viewHolder = (ViewHolder) convertView.getTag();
            if (viewHolder == null) {
                viewHolder = new ViewHolder(convertView);
                convertView.setTag(viewHolder);
            }
            return viewHolder;
        }

    }
}

list_item.class

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


    <TextView
        android:id="@+id/tv_letter"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#33000000"
        android:gravity="center_vertical"
        android:padding="4dp"
        android:text="A"
        android:textSize="14sp"
        android:textStyle="bold" />


    <TextView
        android:id="@+id/tv_name"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center_vertical"
        android:paddingBottom="7dp"
        android:paddingLeft="4dp"
        android:paddingTop="7dp"
        android:text="阿爾山"
        android:textSize="23sp" />

</LinearLayout>

PinYinlinfo.java

package com.example.custom_view;

import android.text.TextUtils;

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 str) {
        String pinyin = "";
        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
        format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);

        if (!TextUtils.isEmpty(str)) {
            char[] mCharArr = str.toCharArray();

            if (mCharArr != null && mCharArr.length > 0) {

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

                    char c = mCharArr[i];

                    //  TODO UTF-8格式下  1個漢字==2個字節   1個字節(-128----127)
                    if (c > 127) {
                        //不一定是漢字,也不一定是字母
                        try {
                            String[] strArr = PinyinHelper.toHanyuPinyinStringArray(c, format);
                            pinyin += strArr[0];

                        } catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) {
                            badHanyuPinyinOutputFormatCombination.printStackTrace();
                            pinyin += c;
                        }
                    } else {
                        //一定不是漢字,有可能是字母或者標點或者數字
                        pinyin += c;
                    }
                }

            }
        }

        return pinyin;
    }

}

PinYinUtils.java

package com.example.custom_view;

import android.text.TextUtils;

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 str) {
        String pinyin = "";
        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
        format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);

        if (!TextUtils.isEmpty(str)) {
            char[] mCharArr = str.toCharArray();

            if (mCharArr != null && mCharArr.length > 0) {

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

                    char c = mCharArr[i];

                    //  TODO UTF-8格式下  1個漢字==2個字節   1個字節(-128----127)
                    if (c > 127) {
                        //不一定是漢字,也不一定是字母
                        try {
                            String[] strArr = PinyinHelper.toHanyuPinyinStringArray(c, format);
                            pinyin += strArr[0];

                        } catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) {
                            badHanyuPinyinOutputFormatCombination.printStackTrace();
                            pinyin += c;
                        }
                    } else {
                        //一定不是漢字,有可能是字母或者標點或者數字
                        pinyin += c;
                    }
                }

            }
        }

        return pinyin;
    }

}

終於完成了,有什麼問題可以評論!