html 字母列表通讯录,仿微信通讯录字母排序列表

先看下效果图

8a7722d59b20?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

Gif_20180425_103334.gif

在这里我们先分析下效果,左边是一个按照字母排序的并有子列表,右边是直接一个字母的排列,屏幕中间有一个显示你点击了右边的那个字母的显示。

在这里我们先去处理右边的字母列表。我们先去自定义一个view,把26个字母和“#”放到一个数组里面,再用画笔在ondraw()里面画出来。

@Override

protected void onDraw(Canvas canvas) {

// 画26个字母

int itemHeight = (getHeight() - getPaddingTop() - getPaddingBottom()) / mLetters.length;

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

// 知道每个字母的中心位置 1 字母的高度一半 2 字母高度一般+前面字符的高度

int letterCenterY = i * itemHeight + itemHeight / 2 + getPaddingTop();

// 基线,基于中心位置, 知道中心位置还不会基线,看一下之前的视频

Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();

int dy = (int) ((fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom);

int baseLine = letterCenterY + dy;

// x 绘制在最中间 = 宽度/2 - 文字/2

int textWidth = (int) mPaint.measureText(mLetters[i]);

int x = getWidth() / 2 - textWidth / 2;

if (!isUp){

// 当前字母 高亮 用两个画笔(最好) 改变颜色

if (mLetters[i].equals(mCurrentTouchLetter)) {

mPaint.setColor(Color.RED);

canvas.drawText(mLetters[i], x, baseLine, mPaint);

} else {

mPaint.setColor(Color.BLUE);

canvas.drawText(mLetters[i], x, baseLine, mPaint);

}

}else {

mPaint.setColor(Color.BLUE);

canvas.drawText(mLetters[i], x, baseLine, mPaint);

}

}

}

当我们在这个字母列表上面滑动的时候,被点击到的字母会变色,这就需要有两个颜色的画笔去分别画不同的字母。

我们可以在onTouchEvent方法里面拿到按下和滑动的事件,在MotionEvent.ACTION_DOWN和MotionEvent.ACTION_MOVE的时候处理字母的变色。我们首先得那个我们点击的是哪个字母,我们可以拿到当前点击位置的y方向的距离去除以每个字母的高度,然后取整就知道那个字母被点击了,这时候调用invalidate方法去重新绘制字母列表,这样就可以实现当那个字母被点击或者是滑动时被覆盖的字母变色的效果。然后在这里我们写一个回调,去让页面中间的那个textview知道如何去显示那个字母被点击了。

@Override

public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

case MotionEvent.ACTION_MOVE:

// 计算出当前触摸字母 获取当前的位置

float currentMoveY = event.getY();

// 位置 = currentMoveY / 字母高度 , 通过位置获取字母 优化?

int itemHeight = (getHeight() - getPaddingTop() - getPaddingBottom()) / mLetters.length;

currentPosition = (int) (currentMoveY / itemHeight);

if (currentPosition < 0)

currentPosition = 0;

if (currentPosition > mLetters.length - 1)

currentPosition = mLetters.length - 1;

// 要判断 ?

mCurrentTouchLetter = mLetters[currentPosition];

if (mListener != null) {

mListener.touch(mCurrentTouchLetter, true, currentPosition);

}

isUp = false;

// 重新绘制

invalidate();

break;

case MotionEvent.ACTION_UP:

if (mListener != null) {

mListener.touch(mCurrentTouchLetter, false, currentPosition);

}

isUp = true;

// 重新绘制

invalidate();

break;

}

return true;

}

private LetterTouchListener mListener;

public void setOnLetterTouchListener(LetterTouchListener listener) {

this.mListener = listener;

}

// 接口回掉其他View会不会使用?

public interface LetterTouchListener {

void touch(CharSequence letter, boolean isTouch,int currentPosition);

}

我们ManActivity的布局文件是这样的

android:layout_width="match_parent"

android:layout_height="match_parent"

>

android:id="@+id/rv_letter"

android:layout_width="match_parent"

android:layout_height="match_parent"/>

android:layout_width="match_parent"

android:layout_height="match_parent">

android:id="@+id/letter_tv"

android:layout_width="wrap_content"

android:layout_centerInParent="true"

android:text="A"

android:visibility="gone"

android:textSize="16sp"

android:textColor="#FF0000"

android:layout_height="wrap_content" />

android:id="@+id/letter_side_bar"

android:layout_width="wrap_content"

android:layout_alignParentRight="true"

android:paddingLeft="10dp"

android:paddingRight="10dp"

android:layout_height="match_parent" />

在ManActivity里面我们给RecyclerView添加数据,先给RecyclerView添加字母列表,在RecyclerView的布局文件在添加一个子RecyclerView。

android:orientation="vertical"

xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"

android:layout_height="wrap_content">

android:id="@+id/tv_text"

android:textSize="15sp"

android:background="#9999"

android:textColor="#fff"

android:layout_width="match_parent"

android:layout_height="50dp" />

android:id="@+id/rv_child"

android:layout_width="match_parent"

android:layout_height="wrap_content"/>

给子RecyclerView添加数据之后,在会掉里面,当右边的列表那个被惦记了,就将父RecyclerView的那个对应位置的条目滚动到顶部,这样效果就实现了

@Override

public void touch(CharSequence letter,boolean isTouch,int current) {

if(isTouch) {

mLetterTv.setVisibility(View.VISIBLE);

mLetterTv.setText(letter);

rvLetter.scrollToPosition(current);

//让RecyclerView滚动到顶部

if (current != -1) {

rvLetter.scrollToPosition(current);

LinearLayoutManager mLayoutManager =

(LinearLayoutManager) rvLetter.getLayoutManager();

mLayoutManager.scrollToPositionWithOffset(current, 0);

}

}else{

mLetterTv.setVisibility(View.GONE);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值