自定义View之快速索引栏的实现

编程入门 行业动态 更新时间:2024-10-07 12:25:20

<a href=https://www.elefans.com/category/jswz/34/1771438.html style=自定义View之快速索引栏的实现"/>

自定义View之快速索引栏的实现

侧拉索引:音乐APP,即时通讯,电商选择城市,短信验证选择城市都有这个类型的自定义控件
实现步骤:1.绘制A-Z的字母列表(自绘式自定义控件)快速索引栏1.继承View,覆写构造方法,初始化画笔2.在OnDrawer方法里绘制字符3.在OnMesure方法里测量高度4.在OnTouchEvent事件知道用户具体按住了哪个字母5.定义抽象方法,实现监听回调2.响应触摸事件3.提供监听回调4.获取汉字的拼音,首字母5.根据拼音排序6.根据首字母分组7.把监听回调和ListView结合起来当前首字母A上面空的,直接设置数据,判断当前字母与上一个字母是否一致,来确定是显示还是隐藏.1.自定义View
  首先这里去除了标题 在Style
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

public class MyQuickIndex extends View { private Paint paint; private int measuredHeight; private float spaceHeight; private int measuredWidth; private int lastIndex=-1; public MyQuickIndex(Context context) { this(context, null); } public MyQuickIndex(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MyQuickIndex(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); //初始化画笔 initPainter(); } private void initPainter() { paint = new Paint(); //设置风格 paint.setStyle(Paint.Style.STROKE); //设置抗锯齿 paint.setAntiAlias(true); //设置画笔加粗 paint.setTypeface(Typeface.DEFAULT_BOLD); //设置画笔颜色 paint.setColor(Color.WHITE); paint.setTextSize(30); } //准备的数据 //A.要绘制的内容 private static final String[] LETTERS = new String[]{ "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" }; @Override protected void onDraw(Canvas canvas) { //遍历字母数组,计算坐标,进行绘制 for (int i = 0; i < LETTERS.length; i++) { String letter = LETTERS[i]; //计算X轴坐标 float x = measuredWidth * 0.5f - paint.measureText(letter) * 0.5f; float y = spaceHeight * 0.5f + paint.measureText(letter) * 0.5f+i*spaceHeight; canvas.drawText(letter, x,y, paint); } } //获取控件的宽高 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //得到控件宽度 高度 measuredWidth = getMeasuredWidth(); measuredHeight = getMeasuredHeight();//既是控件宽度也是单元格宽度 //单元格的高度 spaceHeight = measuredHeight *1.0f / LETTERS.length; } @Override public boolean onTouchEvent(MotionEvent event) { switch(event.getAction()){ //计算用户按到哪个 字母 case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: //得到当前的Y float y = event.getY(); //得到是第几个indxt int currentIndex = (int) (y / spaceHeight); //判断不是点击同一个字母 if(currentIndex!=lastIndex){ if(currentIndex>=0 && currentIndex<LETTERS.length) { String letter = LETTERS[currentIndex]; Util_Toast.showToast(getContext(),letter); //重新赋值 lastIndex=currentIndex; } } break; default: break; } return true; }}
2.吐司工具类xml引用
public class Util_Toast {private static Toast toast;public static void showToast(Context context ,String msg){if (toast ==null){toast=Toast.makeText(context, "", Toast.LENGTH_SHORT);}toast.setText(msg);toast.show();}}

///分割

1.自定义接口 在MainActivity里进行吐司
public class MyQuickIndex extends View {private Paint paint;private int measuredHeight;private float spaceHeight;private int measuredWidth;public MyQuickIndex(Context context) {this(context, null);}public MyQuickIndex(Context context, AttributeSet attrs) {this(context, attrs, 0);}public MyQuickIndex(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);//初始化画笔
        initPainter();}private void initPainter() {paint = new Paint();//设置风格
        paint.setStyle(Paint.Style.STROKE);//设置抗锯齿
        paint.setAntiAlias(true);//设置画笔加粗
        paint.setTypeface(Typeface.DEFAULT_BOLD);//设置画笔颜色
        paint.setColor(Color.WHITE);paint.setTextSize(30);}//准备的数据
    //A.要绘制的内容
    private static final String[] LETTERS = new String[]{"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"
    };@Override
    protected void onDraw(Canvas canvas) {//遍历字母数组,计算坐标,进行绘制
        for (int i = 0; i < LETTERS.length; i++) {String letter = LETTERS[i];//计算X轴坐标
            float x = measuredWidth * 0.5f - paint.measureText(letter) * 0.5f;float y = spaceHeight * 0.5f + paint.measureText(letter) * 0.5f+i*spaceHeight;canvas.drawText(letter, x,y, paint);}}//获取控件的宽高
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);//得到控件宽度  高度
        measuredWidth = getMeasuredWidth();measuredHeight = getMeasuredHeight();//既是控件宽度也是单元格宽度
        //单元格的高度
        spaceHeight = measuredHeight *1.0f / LETTERS.length;}@Override
    public boolean onTouchEvent(MotionEvent event) {super.onTouchEvent(event);if(mOntouchListener!=null){mOntouchListener.onTouchEvent(this,event,spaceHeight,LETTERS);}return true;}private OntouchListener mOntouchListener;public interface OntouchListener{void onTouchEvent(MyQuickIndex myQuickIndex,MotionEvent event,float spaceHeight,final String[] LETTERS);}public void setmOntouchListener(OntouchListener mOntouchListener) {this.mOntouchListener = mOntouchListener;}
}
MainActivity
public class MainActivity extends AppCompatActivity {private MyQuickIndex mQuickIndex;private int lastIndex=-1;/**
     * View decorView = getWindow().getDecorView();
     * int option = View.SYSTEM_UI_FLAG_FULLSCREEN;
     * decorView.setSystemUiVisibility(option);
     * ActionBar actionBar = getSupportActionBar();
     * actionBar.hide();
     * 隐藏状态栏
     *
     * @param savedInstanceState
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
//        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);initView();mQuickIndex.setmOntouchListener(new MyQuickIndex.OntouchListener() {@Override
            public void onTouchEvent(MyQuickIndex myQuickIndex, MotionEvent event, float spaceHeight, String[] LETTERS) {switch(event.getAction()){//计算用户按到哪个 字母
                    case MotionEvent.ACTION_DOWN:case MotionEvent.ACTION_MOVE://得到当前的Y
                        float y = event.getY();//得到是第几个indxt
                        int currentIndex = (int) (y / spaceHeight);//判断不是点击同一个字母
                        if(currentIndex!=lastIndex){if(currentIndex>=0 && currentIndex<LETTERS.length) {String letter = LETTERS[currentIndex];Util_Toast.showToast(MainActivity.this,letter);//重新赋值
                                lastIndex=currentIndex;}}break;default:break;}}});}private void initView() {mQuickIndex = (MyQuickIndex) findViewById(R.id.quickIndex);}
}

/****************以上仅仅是右边栏的实现************************/

左边栏的实现思路

1.拼音四级的pinyin4j的工具类

public class Util_Pinyin {public static String getPinyin(String string){HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();//不要音标
        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);char[] chars = string.toCharArray();StringBuilder sb = new StringBuilder();for (int i = 0; i < chars.length; i++) {char c = chars[i];//如果是空格,跳过当前循环
           if(Character.isWhitespace(c)){continue;}//如果不是汉字,直接拼写
            if(c>-128 && c<127){sb.append(c);}else{//是汉字 name我们就获取拼音
                try {String s = PinyinHelper.toHanyuPinyinStringArray(c, format)[0];sb.append(s);} catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) {badHanyuPinyinOutputFormatCombination.printStackTrace();}}}return sb.toString();}
}

//TinyPinyin直接使用就可以了  示例代码

String strResource="你  好dasdasdas扣罚款就派送啊啊搜集";
StringBuilder  sb=new StringBuilder() ;
char[] chars = strResource.toCharArray();
for (int i = 0; i <chars.length ; i++) {char aChar = chars[i];if(Character.isWhitespace(aChar)){continue;}String s = Pinyin.toPinyin(aChar);sb.append(s);
}
System.out.println(sb);//输出结果带字母dasdasdas

/*************或者用PinYin的判断
 String strResource="你  好dasdasdas扣罚款就派送啊啊搜集";StringBuilder  sb=new StringBuilder() ;char[] chars = strResource.toCharArray();for (int i = 0; i <chars.length ; i++) {char aChar = chars[i];
//            if(Character.isWhitespace(aChar)){
//                continue;
//            }
            if(Pinyin.isChinese(aChar)){String s = Pinyin.toPinyin(aChar);sb.append(s);}}System.out.println(sb);//不带


//适配器
public class MyAdapter extends BaseAdapter {private List<Bean> list;private Context context;public MyAdapter(List<Bean> list, Context context) {this.list = list;this.context = context;}@Override
    public int getCount() {return list.size();}@Override
    public Object getItem(int i) {return null;}@Override
    public long getItemId(int i) {return 0;}@Override
    public View getView(int i, View view, ViewGroup viewGroup) {ViewHolder holder;if(view==null){holder=new ViewHolder();view=view.inflate(context,R.layout.item,null);holder.tvIndex=view.findViewById(R.id.tv_index);holder.tvName=view.findViewById(R.id.tv_name);view.setTag(holder);}else{holder= (ViewHolder) view.getTag();}Bean bean = list.get(i);//当前首字母
        String currentStr = bean.getPinyin().charAt(0) + "";String indexStr=null;//如果是第一个名字直接显示
        if(i==0){indexStr=currentStr;}else{//判断当前首字母和上一个条目的首字母是否一致,不一致时显示完整item界面
            String lastStr = list.get(i - 1).getPinyin().charAt(0) + "";//判断俩个参数是否一致,不一致时就执行赋值的逻辑
            if(!TextUtils.equals(lastStr,currentStr)){//不一致时直接赋值indexStr
                indexStr=currentStr;}}holder.tvIndex.setText(indexStr);holder.tvName.setText(bean.getName());//做一个判断  如果不一致显示出来 如果一致则隐藏   不等于空说明走了赋值逻辑 说明与当前不一样  是第一次出现
        holder.tvIndex.setVisibility(indexStr != null ? View.VISIBLE:View.GONE);return view;}static class ViewHolder{TextView tvIndex,tvName;}
}
//MainActivity
public class MainActivity extends AppCompatActivity implements MyQuickIndex.OntouchListener, View.OnClickListener {private MyQuickIndex mQuickIndex;private int lastIndex = -1;public static final String[] NAMES = new String[]{"宋江", "卢俊义", "吴用","公孙胜", "关胜", "林冲", "秦明", "呼延灼", "花荣", "柴进", "李应", "朱仝", "鲁智深","武松", "董平", "张清", "杨志", "徐宁", "索超", "戴宗", "刘唐", "李逵", "史进", "穆弘","雷横", "李俊", "阮小二", "张横", "阮小五", " 张顺", "阮小七", "杨雄", "石秀", "解珍"," 解宝", "燕青", "朱武", "黄信", "孙立", "宣赞", "郝思文", "韩滔", "彭玘", "单廷珪","魏定国", "萧让", "裴宣", "欧鹏", "邓飞", " 燕顺", "杨林", "凌振", "蒋敬", "吕方","郭 盛", "安道全", "皇甫端", "王英", "扈三娘", "鲍旭", "樊瑞", "孔明", "孔亮", "项充","李衮", "金大坚", "马麟", "童威", "童猛", "孟康", "侯健", "陈达", "杨春", "郑天寿","陶宗旺", "宋清", "乐和", "龚旺", "丁得孙", "穆春", "曹正", "宋万", "杜迁", "薛永", "施恩","周通", "李忠", "杜兴", "汤隆", "邹渊", "邹润", "朱富", "朱贵", "蔡福", "蔡庆", "李立","李云", "焦挺", "石勇", "孙新", "顾大嫂", "张青", "孙二娘", " 王定六", "郁保四", "白胜","时迁", "段景柱", "小凡哥"};private List<Bean> persons;private ListView mLv;private RelativeLayout mActivityMain;/**
     * View decorView = getWindow().getDecorView();
     * int option = View.SYSTEM_UI_FLAG_FULLSCREEN;
     * decorView.setSystemUiVisibility(option);
     * ActionBar actionBar = getSupportActionBar();
     * actionBar.hide();
     * 隐藏状态栏
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
//        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);initView();mQuickIndex.setmOntouchListener(this);//准备数据
        persons = new ArrayList<>();//排序
        findAndSortData(persons);//适配数据
        MyAdapter myAdapter = new MyAdapter(persons, this);mLv.setAdapter(myAdapter);}private void findAndSortData(List<Bean> persons) {for (int i = 0; i < NAMES.length; i++) {String name = NAMES[i];Bean bean = new Bean(name);persons.add(bean);}Collections.sort(persons);}private void initView() {mQuickIndex = (MyQuickIndex) findViewById(R.id.quickIndex);mLv = (ListView) findViewById(R.id.lv);mQuickIndex.setOnClickListener(this);mActivityMain = (RelativeLayout) findViewById(R.id.activity_main);}@Override
    public void onTouchEvent(MyQuickIndex myQuickIndex, MotionEvent event, float spaceHeight, String[] LETTERS) {switch (event.getAction()) {//计算用户按到哪个 字母
            case MotionEvent.ACTION_DOWN:case MotionEvent.ACTION_MOVE://得到当前的Y
                float y = event.getY();//得到是第几个indxt
                int currentIndex = (int) (y / spaceHeight);//判断不是点击同一个字母
                if (currentIndex != lastIndex) {if (currentIndex >= 0 && currentIndex < LETTERS.length) {String letter = LETTERS[currentIndex];Util_Toast.showToast(MainActivity.this, letter);for (int i = 0; i < persons.size(); i++) {String s = persons.get(i).getPinyin().charAt(0) + "";if(s.equals(letter)){mLv.setSelection(i);break;}}//重新赋值
                        lastIndex = currentIndex;}}break;default:break;}}@Override
    public void onClick(View v) {switch (v.getId()) {case R.id.quickIndex:break;}}
}
//Xml item
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=""
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"><TextView
        android:id="@+id/tv_index"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="#666666"
        android:gravity="center_vertical"
        android:paddingLeft="15dp"
        android:text="A"
        android:textColor="#FFFFFF"
        android:textSize="18sp" /><TextView
        android:id="@+id/tv_name"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center_vertical"
        android:paddingLeft="15dp"
        android:text="宋江"
        android:textSize="22sp" /></LinearLayout>
//MainXml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android=""
    xmlns:tools=""
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
   ><ListView
        android:id="@+id/lv"

        android:layout_width="match_parent"
        android:layout_height="match_parent"></ListView><com.example.administrator.view_suoyin.MyQuickIndex
        android:layout_width="30dp"
        android:id="@+id/quickIndex"
        android:layout_height="match_parent"
        android:background="#006aff"
        android:layout_alignParentRight="true"
        />
</RelativeLayout>

更多推荐

自定义View之快速索引栏的实现

本文发布于:2024-02-28 08:02:34,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1769134.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:自定义   索引   快速   View

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!