自绘View(仿酷狗歌单右侧字母导航条)

来源:互联网 发布:汇电商淘宝插件 编辑:程序博客网 时间:2024/06/05 11:54

 今天给大家带来的是仿酷狗歌单右侧字母导航条,其实不仅是这里,只要是要用到字母导航的地方大概都是这么做的,直接给大家上代码,注释比较齐全了:

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.csdn.net/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);
    }
}

原创粉丝点击