今天给大家带来的是仿酷狗歌单右侧字母导航条,其实不仅是这里,只要是要用到字母导航的地方大概都是这么做的,直接给大家上代码,注释比较齐全了:
1.自定义view部分
public class Letterindex extends View{//创建字母索引数组
private String[] letter = {"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 Paint zmPaint;
//手指当前位置
private int currentPosition = -1;
//每个字母的高度
private int perHight;
//声明标签textview
private TextView tv;
//创建set方法
public void setTv(TextView tv) {
this.tv = tv;
}
public Letterindex(Context context) {
this(context,null);
}
public Letterindex(Context context, AttributeSet attrs) {
this(context,attrs,0);
}
public Letterindex(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//初始化画笔
zmPaint = new Paint();
zmPaint.setAntiAlias(true);
zmPaint.setTextSize(20);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//计算每一个字母的高度
perHight = getMeasuredHeight()/letter.length;
for(int i = 0;i < letter.length;i++){
if(i == currentPosition){
//当手指位置与某个字母相等时,把画笔设为红色
zmPaint.setColor(Color.RED);
}else {
//默认情况为黑色
zmPaint.setColor(Color.BLACK);
}
//1.要绘制的文本
//2.文本的X轴中心点,如果在画笔中没有设置setTextAlign属性,则该参数表示文本的起始位置
//3.文本的基线
//4.画笔
canvas.drawText(letter[i],(getMeasuredWidth()- zmPaint.measureText(letter[i]))/2,perHight*(i+1),zmPaint);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//获取当前点击的手指位置
currentPosition = (int) (event.getY()/perHight);
switch (event.getAction()){
//
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
/*
当手指按下和移动是背景设置为灰色,且让标签textview显示出来,
显示的文字为当前手指位置处的字母,需要注意要做个首尾溢出的判断
避免数组越界
*/
setBackgroundColor(Color.GRAY);
if(tv!= null){
tv.setVisibility(VISIBLE);
if(currentPosition > -1&& currentPosition < letter.length){
tv.setText(letter[currentPosition]);
if(updateLr!=null){
updateLr.update(letter[currentPosition]);
}
}
}
break;
case MotionEvent.ACTION_UP:
//当手指抬起是背景设置为透明,且让标签textview隐藏起来,
setBackgroundColor(Color.TRANSPARENT);
if(tv!= null){
tv.setVisibility(GONE);
}
break;
}
//重绘
invalidate();
return true;
}
public void change(int sectionForPosition) {
for(int i = 0; i < letter.length;i++){
if(letter[i].charAt(0) == sectionForPosition){
currentPosition=i;
break;
}
}
invalidate();
}
public interface updateLetter{
void update(String letter);
}
private updateLetter updateLr;
public void setUpdateLr(updateLetter updateLr) {
this.updateLr = updateLr;
}
}
2.适配器部分
public class MyAdapter extends BaseAdapter implements SectionIndexer{
private List<star> stars;
private Context context;
private LayoutInflater inflater;
public MyAdapter(List<star> stars, Context context) {
this.stars = stars;
this.context = context;
inflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return stars.size();
}
@Override
public Object getItem(int position) {
return stars.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null){
convertView = inflater.inflate(R.layout.item_layout,parent,false);
holder = new ViewHolder();
holder.tv1 = (TextView) convertView.findViewById(R.id.tv1);
holder.user = (TextView) convertView.findViewById(R.id.username);
convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
}
//获取当前item所属的分组
int section = getSectionForPosition(position);
//获取该分组第一个item的position
int positionForSection = getPositionForSection(section);
if(position == positionForSection){
holder.tv1.setVisibility(View.VISIBLE);
holder.tv1.setText(stars.get(position).getFirstLetter());
}else{
holder.tv1.setVisibility(View.GONE);
}
holder.user.setText(stars.get(position).getYiming());
return convertView;
}
@Override
public Object[] getSections() {
return new Object[0];
}
//根据分组名称,获取该分组中第一个item的position
@Override
public int getPositionForSection(int sectionIndex) {
for (int i = 0;i < stars.size();i++){
if(stars.get(i).getFirstLetter().charAt(0) == sectionIndex){
return i;
}
}
return -1;
}
//根据position,获取该item所属的分组
@Override
public int getSectionForPosition(int position) {
return stars.get(position).getFirstLetter().charAt(0);
}
class ViewHolder{
TextView tv1,user;
}
}
3,所用bean类
public class star {
private String yiming;
private String firstLetter;
private String quanpin;
public star(String yiming, String firstLetter, String quanpin) {
this.yiming = yiming;
this.firstLetter = firstLetter;
this.quanpin = quanpin;
}
public star() {
}
public String getYiming() {
return yiming;
}
public void setYiming(String yiming) {
this.yiming = yiming;
}
public String getFirstLetter() {
return firstLetter;
}
public void setFirstLetter(String firstLetter) {
this.firstLetter = firstLetter;
}
public String getQuanpin() {
return quanpin;
}
public void setQuanpin(String quanpin) {
this.quanpin = quanpin;
}
@Override
public String toString() {
return "star{" +
"yiming='" + yiming + '\'' +
", firstLetter='" + firstLetter + '\'' +
", quanpin='" + quanpin + '\'' +
'}';
}
}
4.activity运用
package com.qf.yanxun.alphabeticalindex;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private Letterindex led;
private TextView tv;
private ListView lv;
private List<star> sList;
private MyAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
//通过接口回调来改变listview
changeListview();
//通过监听滑动来设置画笔颜色
changePaintColor();
}
private void changePaintColor() {
lv.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
int sectionForPosition = adapter.getSectionForPosition(firstVisibleItem);
led.change(sectionForPosition);
}
});
}
private void changeListview() {
led.setUpdateLr(new Letterindex.updateLetter() {
@Override
public void update(String letter) {
lv.setSelection(adapter.getPositionForSection(letter.charAt(0)));
}
});
}
private void initView() {
led = ((Letterindex) findViewById(R.id.ldv));
tv = ((TextView) findViewById(R.id.tv));
lv = ((ListView) findViewById(R.id.lv));
led.setTv(tv);
sList = new ArrayList<>();
上篇给大家贴出了这个工具类的实现代码 传送门:http://blog.youkuaiyun.com/qq_35189116/article/details/72673979
ChineseToPinyinHelper helper = ChineseToPinyinHelper.getInstance();
String[] starName = getResources().getStringArray(R.array.arrUsernames);
for (int i = 0;i < starName.length;i++){
star s = new star();
String quanp = helper.getPinyin(starName[i]).toUpperCase();
String firstletter = quanp.substring(0, 1);
if(!firstletter.matches("[A-Z]")){
firstletter = "#";
}
s.setFirstLetter(firstletter);
s.setQuanpin(quanp);
s.setYiming(starName[i]);
sList.add(s);
}
Collections.sort(sList, new Comparator<star>() {
@Override
public int compare(star lhs, star rhs) {
if (lhs.getFirstLetter().equals("#")) {
return 1;
} else if (rhs.getFirstLetter().equals("#")) {
return -1;
} else {
return lhs.getFirstLetter().compareTo(rhs.getFirstLetter());
}
}
});
adapter = new MyAdapter(sList,this);
lv.setAdapter(adapter);
}
}