通讯录索引SideBarView

来源:互联网 发布:网络棋牌充值漏洞 编辑:程序博客网 时间:2024/05/01 17:42

废话不多说

首先上效果图:


要做的这样的效果 首先导入一个pinyin包

  compile 'com.belerweb:pinyin4j:2.5.1'

接下来做一些准备工作吧

主页面的Xml

       里面用到了自定义的 SideBarView

<RelativeLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:poplar="http://schemas.android.com/apk/res-auto"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="#d5d5d5">    <TextView        android:id="@+id/tv_friends_toolbar"        android:layout_width="match_parent"        android:layout_height="52dp"        android:background="#41c2fc"        android:gravity="center"        android:text="通讯录"        android:textColor="#fff"        android:textSize="20sp"/>    <ListView        android:id="@+id/lv_friends_listView"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_below="@id/tv_friends_toolbar"/>    <com.cooltone.demo.SideBarView        android:id="@+id/sbv_friends_bar"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_below="@id/tv_friends_toolbar"        android:layout_marginBottom="5dp"        android:layout_marginTop="5dp"        poplar:additionalTipOffset="40dp"        poplar:fontColor="#6e6e6e"        poplar:maxBezierHeight="150dp"        poplar:maxBezierWidth="180dp"        poplar:maxFontSize="60"        poplar:minFontSize="32"        poplar:tipFontColor="#41c2fc"        poplar:tipFontSize="72"        poplar:widthOffset="15dp"/>    <TextView        android:id="@+id/tv_friends_center"        android:layout_width="100dp"        android:layout_height="100dp"        android:layout_below="@id/tv_friends_toolbar"        android:layout_centerInParent="true"        android:background="@drawable/sidebar_background"        android:gravity="center"        android:text="A"        android:textColor="#fff"        android:textSize="36sp"        android:visibility="gone"/></RelativeLayout>

上面包红没关系啊 一步步来,记得一会自定义View 要换包名。接下来是listView 条目 布局

<LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <TextView        android:id="@+id/tv_friend_title"        android:layout_width="match_parent"        android:layout_height="20dp"        android:background="#919191"        android:gravity="center_vertical"        android:paddingLeft="20dp"        android:text="A"        android:textSize="14sp"/>    <TextView        android:id="@+id/tv_friend_name"        android:layout_width="match_parent"        android:layout_height="60dp"        android:background="#fff"        android:gravity="center_vertical"        android:paddingLeft="20dp"        android:text="宋江"        android:textColor="#00f"        android:textSize="16sp"/></LinearLayout>
接下来什么呢 ,在drawable文件下 建一个背景吧 sidebar_background

<shape xmlns:android="http://schemas.android.com/apk/res/android"       android:shape="rectangle">    <!-- 通讯录 -->    <corners android:radius="25dp"/>    <solid android:color="#66000000"/></shape>

接下来就是重要人物出场了

建 SideBarView 继承 View 写我们的索引控件 

里面的东西自己想研究下的话, 可以自己研究,本人也不是很懂,用了贝塞尔曲线

/** * 作者:CoolTone * 描述:右侧导航栏字母列表 */public class SideBarView extends View {    private OnTouchLetterChangedListener mListener;    public interface OnTouchLetterChangedListener {        void onTouchLetterChanged(String letter);    }    public void setOnTouchLetterChangedListener(OnTouchLetterChangedListener listener) {        this.mListener = listener;    }    // 向右偏移多少画字符, default 30    float mWidthOffset = 30.0f;    // 最小字体大小    int mMinFontSize = 24;    // 最大字体大小    int mMaxFontSize = 48;    // 提示字体大小    int mTipFontSize = 52;    // 提示字符的额外偏移    float mAdditionalTipOffset = 20.0f;    // 贝塞尔曲线控制的高度    float mMaxBezierHeight = 150.0f;    // 贝塞尔曲线单侧宽度    float mMaxBezierWidth = 240.0f;    // 贝塞尔曲线单侧模拟线量    int mMaxBezierLines = 32;    // 列表字符颜色    int mFontColor = 0xffffffff;    // 提示字符颜色    int mTipFontColor = 0xffd33e48;    private final String[] ConstChar = {"#", "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"};    int mChooseIndex = -1;    Paint mPaint = new Paint();    PointF mTouch = new PointF();    PointF[] mBezier1;    PointF[] mBezier2;    float mLastOffset[] = new float[ConstChar.length]; // 记录每一个字母的x方向偏移量, 数字<=0    PointF mPointF = new PointF();    Scroller mScroller;    boolean mAnimating = false;    float mAnimationOffset;    boolean mHideAnimation = false;    int mAlpha = 255;    Handler mHideWaitingHandler = new Handler() {        @Override        public void handleMessage(Message msg) {            if (msg.what == 1) {                mHideAnimation = true;                mAnimating = false;                SideBarView.this.invalidate();                return;            }            super.handleMessage(msg);        }    };    public SideBarView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        initData(context, attrs);    }    public SideBarView(Context context, AttributeSet attrs) {        super(context, attrs);        initData(context, attrs);    }    public SideBarView(Context context) {        super(context);        initData(null, null);    }    private void initData(Context context, AttributeSet attrs) {        if (context != null && attrs != null) {            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FancyIndexer, 0, 0);            mWidthOffset = a.getDimension(R.styleable.FancyIndexer_widthOffset, mWidthOffset);            // 最小            mMinFontSize = a.getInteger(R.styleable.FancyIndexer_minFontSize, mMinFontSize);            // 最大            mMaxFontSize = a.getInteger(R.styleable.FancyIndexer_maxFontSize, mMaxFontSize);            mTipFontSize = a.getInteger(R.styleable.FancyIndexer_tipFontSize, mTipFontSize);            mMaxBezierHeight = a.getDimension(R.styleable.FancyIndexer_maxBezierHeight, mMaxBezierHeight);            mMaxBezierWidth = a.getDimension(R.styleable.FancyIndexer_maxBezierWidth, mMaxBezierWidth);            mMaxBezierLines = a.getInteger(R.styleable.FancyIndexer_maxBezierLines, mMaxBezierLines);            mAdditionalTipOffset = a.getDimension(R.styleable.FancyIndexer_additionalTipOffset, mAdditionalTipOffset);            // 颜色            mFontColor = a.getColor(R.styleable.FancyIndexer_fontColor, mFontColor);            // 提示颜色            mTipFontColor = a.getColor(R.styleable.FancyIndexer_tipFontColor, mTipFontColor);            a.recycle();        }        mScroller = new Scroller(getContext());        mTouch.x = 0;        mTouch.y = -10 * mMaxBezierWidth;        mBezier1 = new PointF[mMaxBezierLines];        mBezier2 = new PointF[mMaxBezierLines];        calculateBezierPoints();    }    @Override    protected void onDraw(Canvas canvas) {        // 控件宽高        int height = getHeight();        int width = getWidth();        // 单个字母高度        float singleHeight = height / (float) ConstChar.length;        int workHeight = 0;        if (mAlpha == 0)            return;        mPaint.reset();        int saveCount = 0;        if (mHideAnimation) {            saveCount = canvas.save();            canvas.saveLayerAlpha(0, 0, width, height, mAlpha, Canvas.ALL_SAVE_FLAG);        }        for (int i = 0; i < ConstChar.length; i++) {            mPaint.setColor(mFontColor);            mPaint.setAntiAlias(true);            float xPos = width - mWidthOffset;            float yPos = workHeight + singleHeight / 2;            // float adjustX = adjustXPos( yPos, i == mChooseIndex );            // 根据当前字母y的位置计算得到字体大小            int fontSize = adjustFontSize(i, yPos);            mPaint.setTextSize(fontSize);            // 添加一个字母的高度            workHeight += singleHeight;            // 绘制字母            drawTextInCenter(canvas, ConstChar[i], xPos + ajustXPosAnimation(i, yPos), yPos);            // 绘制的字母和当前触摸到的一致, 绘制红色被选中字母            if (i == mChooseIndex) {                mPaint.setColor(mTipFontColor);                mPaint.setFakeBoldText(true);                mPaint.setTextSize(mTipFontSize);                yPos = mTouch.y;                float pos = 0;                if (mAnimating || mHideAnimation) {                    pos = mPointF.x;                    yPos = mPointF.y;                } else {                    pos = xPos + ajustXPosAnimation(i, yPos) - mAdditionalTipOffset;                    mPointF.x = pos;                    mPointF.y = yPos;                }                drawTextInCenter(canvas, ConstChar[i], pos, yPos);            }            mPaint.reset();        }        if (mHideAnimation) {            canvas.restoreToCount(saveCount);        }    }    /**     * @param canvas  画板     * @param string  被绘制的字母     * @param xCenter 字母的中心x方向位置     * @param yCenter 字母的中心y方向位置     */    private void drawTextInCenter(Canvas canvas, String string, float xCenter, float yCenter) {        Paint.FontMetrics fm = mPaint.getFontMetrics();        float fontHeight = mPaint.getFontSpacing();        float drawY = yCenter + fontHeight / 2 - fm.descent;        if (drawY < -fm.ascent - fm.descent)            drawY = -fm.ascent - fm.descent;        if (drawY > getHeight())            drawY = getHeight();        mPaint.setTextAlign(Paint.Align.CENTER);        canvas.drawText(string, xCenter, drawY, mPaint);    }    private int adjustFontSize(int i, float yPos) {        // 根据水平方向偏移量计算出一个放大的字号        float adjustX = Math.abs(ajustXPosAnimation(i, yPos));        int adjustSize = (int) ((mMaxFontSize - mMinFontSize) * adjustX / mMaxBezierHeight) + mMinFontSize;        return adjustSize;    }    /**     * x 方向的向左偏移量     *     * @param i    当前字母的索引     * @param yPos y方向的初始位置     * @return     */    private float ajustXPosAnimation(int i, float yPos) {        float offset;        if (this.mAnimating || this.mHideAnimation) {            // 正在动画中或在做隐藏动画            offset = mLastOffset[i];            if (offset != 0.0f) {                offset += this.mAnimationOffset;                if (offset > 0)                    offset = 0;            }        } else {            // 根据当前字母y方向位置, 计算水平方向偏移量            offset = adjustXPos(yPos);            // 当前触摸的x方向位置            float xPos = mTouch.x;            float width = getWidth() - mWidthOffset;            width = width - 60;            // 字母绘制时向左偏移量 进行修正, offset需要是<=0的值            if (offset != 0.0f && xPos > width)                offset += (xPos - width);            if (offset > 0)                offset = 0;            mLastOffset[i] = offset;        }        return offset;    }    private float adjustXPos(float yPos) {        float dis = yPos - mTouch.y; // 字母y方向位置和触摸时y值坐标的差值, 距离越小, 得到的水平方向偏差越大        if (dis > -mMaxBezierWidth && dis < mMaxBezierWidth) {            // 在2个贝赛尔曲线宽度范围以内 (一个贝赛尔曲线宽度是指一个山峰的一边)            // 第一段 曲线            if (dis > mMaxBezierWidth / 4) {                for (int i = mMaxBezierLines - 1; i > 0; i--) {                    // 从下到上, 逐个计算                    if (dis == -mBezier1[i].y) // 落在点上                        return mBezier1[i].x;                    // 如果距离dis落在两个贝塞尔曲线模拟点之间, 通过三角函数计算得到当前dis对应的x方向偏移量                    if (dis > -mBezier1[i].y && dis < -mBezier1[i - 1].y) {                        return (dis + mBezier1[i].y) * (mBezier1[i - 1].x - mBezier1[i].x) / (-mBezier1[i - 1].y + mBezier1[i].y) + mBezier1[i].x;                    }                }                return mBezier1[0].x;            }            // 第三段 曲线, 和第一段曲线对称            if (dis < -mMaxBezierWidth / 4) {                for (int i = 0; i < mMaxBezierLines - 1; i++) {                    // 从上到下                    if (dis == mBezier1[i].y) // 落在点上                        return mBezier1[i].x;                    // 如果距离dis落在两个贝塞尔曲线模拟点之间, 通过三角函数计算得到当前dis对应的x方向偏移量                    if (dis > mBezier1[i].y && dis < mBezier1[i + 1].y) {                        return (dis - mBezier1[i].y) * (mBezier1[i + 1].x - mBezier1[i].x) / (mBezier1[i + 1].y - mBezier1[i].y) + mBezier1[i].x;                    }                }                return mBezier1[mMaxBezierLines - 1].x;            }            // 第二段 峰顶曲线            for (int i = 0; i < mMaxBezierLines - 1; i++) {                if (dis == mBezier2[i].y)                    return mBezier2[i].x;                // 如果距离dis落在两个贝塞尔曲线模拟点之间, 通过三角函数计算得到当前dis对应的x方向偏移量                if (dis > mBezier2[i].y && dis < mBezier2[i + 1].y) {                    return (dis - mBezier2[i].y) * (mBezier2[i + 1].x - mBezier2[i].x) / (mBezier2[i + 1].y - mBezier2[i].y) + mBezier2[i].x;                }            }            return mBezier2[mMaxBezierLines - 1].x;        }        return 0.0f;    }    @Override    public boolean dispatchTouchEvent(MotionEvent event) {        final int action = event.getAction();        final float y = event.getY();        final int oldmChooseIndex = mChooseIndex;        final OnTouchLetterChangedListener listener = mListener;        final int c = (int) (y / getHeight() * ConstChar.length);        switch (action) {            case MotionEvent.ACTION_DOWN:                if (this.getWidth() > mWidthOffset) {                    if (event.getX() < this.getWidth() - mWidthOffset)                        return false;                }                mHideWaitingHandler.removeMessages(1);                mScroller.abortAnimation();                mAnimating = false;                mHideAnimation = false;                mAlpha = 255;                mTouch.x = event.getX();                mTouch.y = event.getY();                if (oldmChooseIndex != c && listener != null) {                    if (c > 0 && c < ConstChar.length) {                        listener.onTouchLetterChanged(ConstChar[c]);                        mChooseIndex = c;                    }                }                invalidate();                break;            case MotionEvent.ACTION_MOVE:                mTouch.x = event.getX();                mTouch.y = event.getY();                invalidate();                if (oldmChooseIndex != c && listener != null) {                    if (c >= 0 && c < ConstChar.length) {                        listener.onTouchLetterChanged(ConstChar[c]);                        mChooseIndex = c;                    }                }                break;            case MotionEvent.ACTION_UP:            case MotionEvent.ACTION_CANCEL:                mTouch.x = event.getX();                mTouch.y = event.getY();                mScroller.startScroll(0, 0, (int) mMaxBezierHeight, 0, 500);                mAnimating = true;                postInvalidate();                break;        }        return true;    }    @Override    public void computeScroll() {        super.computeScroll();        if (mScroller.computeScrollOffset()) {            if (mAnimating) {                float x = mScroller.getCurrX();                mAnimationOffset = x;            } else if (mHideAnimation) {                mAlpha = 255 - mScroller.getCurrX();            }            invalidate();        } else if (mScroller.isFinished()) {            if (mAnimating) {                mHideWaitingHandler.sendEmptyMessage(1);            } else if (mHideAnimation) {                mHideAnimation = false;                this.mChooseIndex = -1;                mTouch.x = -10000;                mTouch.y = -10000;            }        }    }    /**     * 计算出所有贝塞尔曲线上的点     * 个数为 mMaxBezierLines * 2 = 64     */    private void calculateBezierPoints() {        PointF mStart = new PointF();   // 开始点        PointF mEnd = new PointF();     // 结束点        PointF mControl = new PointF(); // 控制点        // 计算第一段红色部分 贝赛尔曲线的点        // 开始点        mStart.x = 0.0f;        mStart.y = -mMaxBezierWidth;        // 控制点        mControl.x = 0.0f;        mControl.y = -mMaxBezierWidth / 2;        // 结束点        mEnd.x = -mMaxBezierHeight / 2;        mEnd.y = -mMaxBezierWidth / 4;        mBezier1[0] = new PointF();        mBezier1[mMaxBezierLines - 1] = new PointF();        mBezier1[0].set(mStart);        mBezier1[mMaxBezierLines - 1].set(mEnd);        for (int i = 1; i < mMaxBezierLines - 1; i++) {            mBezier1[i] = new PointF();            mBezier1[i].x = calculateBezier(mStart.x, mEnd.x, mControl.x, i / (float) mMaxBezierLines);            mBezier1[i].y = calculateBezier(mStart.y, mEnd.y, mControl.y, i / (float) mMaxBezierLines);        }        // 计算第二段蓝色部分 贝赛尔曲线的点        mStart.y = -mMaxBezierWidth / 4;        mStart.x = -mMaxBezierHeight / 2;        mControl.y = 0.0f;        mControl.x = -mMaxBezierHeight;        mEnd.y = mMaxBezierWidth / 4;        mEnd.x = -mMaxBezierHeight / 2;        mBezier2[0] = new PointF();        mBezier2[mMaxBezierLines - 1] = new PointF();        mBezier2[0].set(mStart);        mBezier2[mMaxBezierLines - 1].set(mEnd);        for (int i = 1; i < mMaxBezierLines - 1; i++) {            mBezier2[i] = new PointF();            mBezier2[i].x = calculateBezier(mStart.x, mEnd.x, mControl.x, i / (float) mMaxBezierLines);            mBezier2[i].y = calculateBezier(mStart.y, mEnd.y, mControl.y, i / (float) mMaxBezierLines);        }    }    /**     * 贝塞尔曲线核心算法     *     * @param start     * @param end     * @param control     * @param val     * @return 公式及动图, 维基百科: https://en.wikipedia.org/wiki/B%C3%A9zier_curve     * 中文可参考此网站: http://blog.csdn.net/likendsl/article/details/7852658     */    private float calculateBezier(float start, float end, float control, float val) {        float t = val;        float s = 1 - t;        float ret = start * s * s + 2 * control * s * t + end * t * t;        return ret;    }}
之后来,当然是善后啦 因为里面会包红呀!

接下来在values里面创建attrs文件

    <!-- 通讯录 -->    <declare-styleable name="FancyIndexer">        <attr name="widthOffset" format="dimension"/>        <attr name="minFontSize" format="integer"/>        <attr name="maxFontSize" format="integer"/>        <attr name="tipFontSize" format="integer"/>        <attr name="maxBezierHeight" format="dimension"/>        <attr name="maxBezierWidth" format="dimension"/>        <attr name="maxBezierLines" format="integer"/>        <attr name="additionalTipOffset" format="dimension"/>        <attr name="fontColor" format="color"/>        <attr name="tipFontColor" format="color"/>    </declare-styleable>

做完这些估计就不会包红了吧! 因为我这写完了没有什么红 所以我也记不清了!

这里因为要给好友列表排序 当然少不了拼音 和 实体类

FriendEntity实体类

/** * 作者: CoolTone * 描述: 好友列表实体类 */public class FriendEntity implements Comparable<FriendEntity> {    private String name;    private String pinyin;    public FriendEntity() {    }    @Override    public int compareTo(FriendEntity another) {        return pinyin.compareTo(another.pinyin);    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getPinyin() {        return pinyin;    }    public void setPinyin(String pinyin) {        this.pinyin = pinyin;    }    @Override    public String toString() {        return "FriendEntity{" +                "name='" + name + '\'' +                ", pinyin='" + pinyin + '\'' +                '}';    }}

对于上面要说一句 不要忘了 很重要哦!排序用的

    @Override    public int compareTo(FriendEntity another) {        return pinyin.compareTo(another.pinyin);    }
接下来 PinyinUtil 帮助类

/** * 作者: CoolTone * 描述: 通讯录 拼音 帮助类 */public class PinyinUtil {    /**     * 根据汉字获取对应的拼音     *     * @param str     * @return     */    public static String getPinyin(String str) {        // 设置输出配置        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();        // 设置大写        format.setCaseType(HanyuPinyinCaseType.UPPERCASE);        // 设置不需要音调        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);        StringBuilder sb = new StringBuilder();        // 获取字符数组        char[] charArray = str.toCharArray();        for (int i = 0; i < charArray.length; i++) {            char c = charArray[i];            if (Character.isWhitespace(c)) { // 如果是空格, 跳过当前的循环                continue;            }            if (c > 128 || c < -127) {  // 可能是汉字                try {   // 根据字符获取对应的拼音                    String s = PinyinHelper.toHanyuPinyinStringArray(c, format)[0];                    sb.append(s);                } catch (BadHanyuPinyinOutputFormatCombination e) {                    e.printStackTrace();                }            } else {                // ~!@#$%^&*()_+{}|:"<>?\/1234567890                // 不需要转换, 直接添加                // 根据字符获取对应的拼音                sb.append(c);            }        }        return sb.toString();    }}
这个工具里面有注释就不多说了!

接下来是Adapter的工具类 因为本人比较喜欢用ListView 所以这个父类的Adapter 很有用

/** * 作者: CoolTone * 描述: 父类Adapter */public abstract class SecondAdapter<T> extends BaseAdapter {    private List<T> mData;           // 数据信息    private LayoutInflater mInflater;// 填充布局    private Context mContext;        // 上下文    public SecondAdapter(Context context) {        mData = new ArrayList<>();        mInflater = LayoutInflater.from(context);        mContext = context;    }    @Override    public int getCount() {        return mData.size();    }    @Override    public T getItem(int position) {        return mData.get(position);    }    @Override    public long getItemId(int position) {        return position;    }    public List<T> getData() {        return mData;    }    public LayoutInflater getInflater() {        return mInflater;    }    public Context getContext() {        return mContext;    }    /**     * 添加集合     */    public void addAll(List<T> data) {        mData.addAll(data);        notifyDataSetChanged();    }    /**     * 清除集合     */    public void clear() {        mData.clear();        notifyDataSetChanged();    }}
然后就是写 FriendAdapter 主要赋值嘛 

这里面要做一些逻辑处理:

比如判断是否是拼音,是否拼音的第一位等等

/** * 作者: CoolTone * 描述: 数据Adapter */public class FriendAdapter extends SecondAdapter<FriendEntity> {    public FriendAdapter(Context context) {        super(context);    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        if (convertView == null) {            convertView = getInflater().inflate(R.layout.item_friend, null);        }        ItemViewHolder holder = (ItemViewHolder) convertView.getTag();        if (holder == null) {            holder = new ItemViewHolder(convertView);            convertView.setTag(holder);        }        holder.bindView(position);        return convertView;    }    class ItemViewHolder {        private final TextView mName;        private final TextView mTitle;        public ItemViewHolder(View itemView) {            mName = ((TextView) itemView.findViewById(R.id.tv_friend_name));            mTitle = (TextView) itemView.findViewById(R.id.tv_friend_title);        }        public void bindView(int position) {            FriendEntity friend = getData().get(position);            String pinyin = friend.getPinyin();            if (!pinyin.isEmpty()) {                String s = String.valueOf(pinyin.charAt(0));                if ((s.charAt(0) <= 'Z' && s.charAt(0) >= 'A') || (s.charAt(0) <= 'z' && s.charAt(0) >= 'a')) {                    oneYesLetter(position, friend, s);                } else {                    oneNoLetter(position, friend, s);                }            }        }        // 第一位是否是字母 Y        private void oneYesLetter(int position, FriendEntity friend, String currentLetter) {            String indexStr = null;            if (position == 0) {    // 如果是第一位                indexStr = currentLetter;            } else {                // 获取上一个拼音                String preLetter = getData().get(position - 1).getPinyin().charAt(0) + "";                if (!TextUtils.equals(currentLetter, preLetter)) {                    indexStr = currentLetter;   // 当跟上一个不同时, 赋值, 显示                }            }            mTitle.setVisibility(indexStr == null ? View.GONE : View.VISIBLE);            mTitle.setText(indexStr);            mName.setText(friend.getName());        }        // 第一位是否是字母 N        private void oneNoLetter(int position, FriendEntity friend, String currentLetter) {            String indexStr = null;            if (position == 0) {  // 如果是第一位                indexStr = currentLetter;            }            mTitle.setVisibility(indexStr == null ? View.GONE : View.VISIBLE);            mTitle.setText("#");            mName.setText(friend.getName());        }    }}

这就完了! 但是还有写主程序呀!你逗我

/** * 作者: CoolTone * 描述: 好友列表 */public class MainActivity extends AppCompatActivity implements SideBarView.OnTouchLetterChangedListener {    private ArrayList<FriendEntity> mFriends;    private FriendAdapter mAdapter;    private ListView mListView;    private SideBarView mSideView;    private TextView mLetter;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();        initData();        setListener();    }    private void setListener() {        mSideView.setOnTouchLetterChangedListener(this);    }    private void initData() {        mFriends = new ArrayList<>();        mAdapter = new FriendAdapter(this);        mListView.setAdapter(mAdapter);        String[] names = new String[]{"逗霸最伟大", "鬧夠了就去吃藥", "破灭等于拥有", "贪恋剧情小丑",                "若隐若现", "我叫意志力", "龍飛鳳舞", "别拿爱情说宿命",                "青春帅气先森", "年华仅是无效信", "年华仅是无效信", "中国好同桌", "折磨",                "马子大", "不哭的理由", "唱歌跑调那叫范", "爱4太给力", "你与寂寞有染",};        for (int i = 0; i < names.length; i++) {            FriendEntity friend = new FriendEntity();            friend.setName(names[i]);            friend.setPinyin(PinyinUtil.getPinyin(names[i]));            mFriends.add(friend);        }        Collections.sort(mFriends); // 这里千万不能忘        mAdapter.addAll(mFriends);        mAdapter.notifyDataSetChanged();    }    private void initView() {        mListView = ((ListView) findViewById(R.id.lv_friends_listView));        mSideView = ((SideBarView) findViewById(R.id.sbv_friends_bar));        mLetter = ((TextView) findViewById(R.id.tv_friends_center));    }    @Override    public void onTouchLetterChanged(String letter) {//        showLetter(letter);        if (!mFriends.isEmpty()) {            for (int i = 0; i < mFriends.size(); i++) {                FriendEntity friend = mFriends.get(i);                String s = String.valueOf(friend.getPinyin().charAt(0));                if (TextUtils.equals(s, letter)) { // 匹配成功, 中断循环, 跳转到i位置                    mListView.setSelection(i);                    break;                }            }        }    }//    /**//     * 显示字母提示//     *//     * @param letter//     *///    protected void showLetter(String letter) {//        mLetter.setVisibility(View.VISIBLE);//        mLetter.setText(letter);////        // 取消掉刚刚所有的演示操作//        mHandler.removeCallbacksAndMessages(null);//        mHandler.postDelayed(new Runnable() {//            @Override//            public void run() {//                // 隐藏//                mCenter.setVisibility(View.GONE);//            }//        }, 500);//    }}

嗯哼大功告成了吧! 反正我已经晕了 应该没有丢下东西才对 

注意事项:好友列表数据  在给Adapter 添加数据之前千万不要忘了 Collections.sort(); 排序

for (int i = 0; i < names.length; i++) {      FriendEntity friend = new FriendEntity();      friend.setName(names[i]);      friend.setPinyin(PinyinUtil.getPinyin(names[i]));      mFriends.add(friend);}Collections.sort(mFriends); // 这里千万不能忘mAdapter.addAll(mFriends);mAdapter.notifyDataSetChanged();

Demo下载地址:http://download.csdn.net/detail/qq_35352552/9797827






1 0
原创粉丝点击