Android开发实现根据字母快速定位侧边栏

按首字母对List排列,并根据首字母快速定位的实现,在Android开发中被大量应用,今天我也来亲自实现一下,将这个控件封装起来,也方便以后的使用。大体上可以分为两步来实现这个控件:首先使自己的控件继承于View,并进行图形绘制;然后根据触摸位置计算当前触摸的字母,并实现回调接口的方法。

下面来进行实践:

1.创建自己的控件类并继承于View,注意:不能只声明含有一个构造参数Context的构造函数,这样我们的控件无法在xml文件中调用,因为Android中xml调用控件之间的参数传递是通过构造参数中的AttributeSet参数来进行的,没有这个参数我们的控件不能在xml中使用。在这里我添加了父类View的三个构造函数,这里只需要调用父类的构造函数即可,不需要额外的操作。

public QuicLocationBar(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  // TODO Auto-generated constructor stub
 }

 public QuicLocationBar(Context context, AttributeSet attrs) {
  super(context, attrs);
  // TODO Auto-generated constructor stub
 }

 public QuicLocationBar(Context context) {
  super(context);
  // TODO Auto-generated constructor stub
 }

2.绘制字符:绘制的部分通过复写父类的onDraw方法来实现,并通过Paint来来绘制

1)首先声明一个成员变量来保存我们的字符数组,并初始化一个Paint类的成员变量来帮助我们绘制字符

private String characters[] = { "#", "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 paint = new Paint();

2)根据总的高度除以字符串数组的长度来得到每一个字符的高度,然后循环遍历整个数组来绘制字符

@Override
  protected void onDraw(Canvas canvas) {
  // TODO Auto-generated method stub
  super.onDraw(canvas);
  int width = getWidth();
  int height = getHeight();
   int singleHeight = height / characters.length;
  for (int i = 0; i < characters.length; i++) {
   //对paint进行相关的参数设置
   paint.setColor(getResources().getColor(R.color.myblack));
   paint.setTypeface(Typeface.DEFAULT_BOLD);
   paint.setAntiAlias(true);
   paint.setTextSize(20);
   if (i == choose) {//choose变量表示当前触摸的字符位置,若没有触摸则为-1
    paint.setColor(getResources().getColor(R.color.myred));
    paint.setFakeBoldText(true);
   }
   //计算字符的绘制的位置
   float xPos = width / 2 - paint.measureText(characters[i]) / 2;
   float yPos = singleHeight * i + singleHeight;
   //在画布上绘制字符
   canvas.drawText(characters[i], xPos, yPos, paint);
   paint.reset();//每次绘制完成后不要忘记重制Paint
  }
 }

注意:不要忘记在每次绘制完成后重置Paint

3.处理触摸事件:通过复写父类的dispatchTouchEvent方法来实现

1)首先我们要设计一个回调接口,当我们触摸的字符发生改变时可以执行该回调接口的方法

public interface OnTouchLetterChangedListener {
  public void touchLetterChanged(String s);
 }

2)当发生按下事件或移动事件时,我们根据触摸点的位置计算出当前触摸的字符,如果和我们显示的字符不相同则执行回调接口的方法,并进行View的重绘;当发生抬起事件时我们将当前显示的字符更新为-1,表示当前没有字符显示,并进行View的重绘。

@Override
  public boolean dispatchTouchEvent(MotionEvent event) {
  int action = event.getAction();
  float y = event.getY();
  int c = (int) (y / getHeight() * characters.length);

  switch (action) {
  case MotionEvent.ACTION_UP:
   choose = -1;//
   setBackgroundColor(0x0000);
   invalidate();
   break;

  case MotionEvent.ACTION_DOWN:
  case MotionEvent.ACTION_MOVE:
   setBackgroundColor(getResources().getColor(R.color.darkgray));
   if (choose != c) {
    if (c >= 0 && c < characters.length) {
     if (mOnTouchLetterChangedListener != null) {
      mOnTouchLetterChangedListener
        .touchLetterChanged(characters[c]);
     }
     choose = c;
     invalidate();
    }
   }
   break;
  }
  return true;//返回true表示触摸事件不在向下分发
 }

附上整体源码:

package com.example.test.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;

import com.example.gymapp.R;

public class QuicLocationBar extends View {

 private String characters[] = { "#", "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 int choose = -1;
 private Paint paint = new Paint();
 private OnTouchLetterChangedListener mOnTouchLetterChangedListener;

 public QuicLocationBar(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  // TODO Auto-generated constructor stub
 }

 public QuicLocationBar(Context context, AttributeSet attrs) {
  super(context, attrs);
  // TODO Auto-generated constructor stub
 }

 public QuicLocationBar(Context context) {
  super(context);
  // TODO Auto-generated constructor stub
 }

 public void setOnTouchLitterChangedListener(
   OnTouchLetterChangedListener onTouchLetterChangedListener) {
  this.mOnTouchLetterChangedListener = onTouchLetterChangedListener;
 }

 @Override
 protected void onDraw(Canvas canvas) {
  // TODO Auto-generated method stub
  super.onDraw(canvas);
  int width = getWidth();
  int height = getHeight();
  int singleHeight = height / characters.length;
  for (int i = 0; i < characters.length; i++) {
   // 对paint进行相关的参数设置
   paint.setColor(getResources().getColor(R.color.myblack));
   paint.setTypeface(Typeface.DEFAULT_BOLD);
   paint.setAntiAlias(true);
   paint.setTextSize(20);
   if (i == choose) {// choose变量表示当前显示的字符位置,若没有触摸则为-1
    paint.setColor(getResources().getColor(R.color.myred));
    paint.setFakeBoldText(true);
   }
   // 计算字符的绘制的位置
   float xPos = width / 2 - paint.measureText(characters[i]) / 2;
   float yPos = singleHeight * i + singleHeight;
   // 在画布上绘制字符
   canvas.drawText(characters[i], xPos, yPos, paint);
   paint.reset();// 每次绘制完成后不要忘记重制Paint
  }
 }

 @Override
 public boolean dispatchTouchEvent(MotionEvent event) {
  int action = event.getAction();
  float y = event.getY();
  int c = (int) (y / getHeight() * characters.length);

  switch (action) {
  case MotionEvent.ACTION_UP:
   choose = -1;//
   setBackgroundColor(0x0000);
   invalidate();
   break;

  case MotionEvent.ACTION_DOWN:
  case MotionEvent.ACTION_MOVE:
   setBackgroundColor(getResources().getColor(R.color.darkgray));
   if (choose != c) {
    if (c >= 0 && c < characters.length) {
     if (mOnTouchLetterChangedListener != null) {
      mOnTouchLetterChangedListener
        .touchLetterChanged(characters[c]);
     }
     choose = c;
     invalidate();
    }
   }
   break;
  }
  return true;
 }

 public interface OnTouchLetterChangedListener {
  public void touchLetterChanged(String s);
 }

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android自定义View实现字母导航栏

    很多的Android入门程序猿来说对于Android自定义View,可能都是比较恐惧的,但是这又是高手进阶的必经之路,所有准备在自定义View上面花一些功夫,多写一些文章. 思路分析: 1.自定义View实现字母导航栏 2.ListView实现联系人列表 3.字母导航栏滑动事件处理 4.字母导航栏与中间字母的联动 5.字母导航栏与ListView的联动 效果图: 首先,我们先甩出主布局文件,方便后面代码的说明 <!--?xml version="1.0" encoding=&qu

  • Android仿微信联系人列表字母侧滑控件

    仿微信联系人列表字母侧滑控件, 侧滑控件参考了以下博客: Android实现ListView的A-Z字母排序和过滤搜索功能 首先分析一下字母侧滑控件应该如何实现,根据侧滑控件的高度和字母的数量来平均计算每个字母应该占据的高度. 在View的onDraw()方法下绘制每一个字母 protected void onDraw(Canvas canvas) { super.onDraw(canvas); int height = getHeight();// 获取对应高度 int width = get

  • Android自定义字母导航栏

    本文实例为大家分享了Android字母导航栏的具体代码,供大家参考,具体内容如下 效果 实现逻辑 明确需求 字母导航栏在实际开发中还是比较多见的,城市选择.名称选择等等可能需要到. 现在要做到的就是在滑动控件过程中可以有内容以及 下标的回调,方便处理其他逻辑! 整理思路 1.确定控件的尺寸,防止内容显示不全.相关的逻辑在onMeasure()方法中处理: 2.绘制显示的内容,在按下和抬起不同状态下文字.背景的颜色.相关逻辑在onDraw()方法中: 3.滑动事件的处理以及事件回调.相关逻辑在on

  • Android 实现带字母索引的侧边栏功能

    之前已经用自定义View做出如下这样一个效果了 这两天需要重新拿来使用,发现效果虽然做出来了,不过思路不太对,就重新参考写了一个,用法也更为简单了 首要的自然是需要继承View绘制出侧边栏,并向外提供一个监听字母索引变化的方法 /** * 作者:叶应是叶 * 时间:2017/8/20 11:38 * 描述: */ public class LetterIndexView extends View { public interface OnTouchingLetterChangedListener

  • Android自定义字母选择侧边栏

    本文实例为大家分享了Android自定义字母选择侧边栏的具体代码,供大家参考,具体内容如下 LetterSideBar.java package com.zb.customview.widgets; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.g

  • Android开发实现根据字母快速定位侧边栏

    按首字母对List排列,并根据首字母快速定位的实现,在Android开发中被大量应用,今天我也来亲自实现一下,将这个控件封装起来,也方便以后的使用.大体上可以分为两步来实现这个控件:首先使自己的控件继承于View,并进行图形绘制:然后根据触摸位置计算当前触摸的字母,并实现回调接口的方法. 下面来进行实践: 1.创建自己的控件类并继承于View,注意:不能只声明含有一个构造参数Context的构造函数,这样我们的控件无法在xml文件中调用,因为Android中xml调用控件之间的参数传递是通过构造

  • Android仿微信通讯录滑动快速定位功能

    先给大家展示下效果图: 实现代码如下: 下面简单说下实现原理. public class IndexBar extends LinearLayout implements View.OnTouchListener { private static final String[] INDEXES = new String[]{"#", "A", "B", "C", "D", "E", &qu

  • Android开发笔记之简单基站定位程序的实现

    经过学习,已经对Android程序的开发流程有了个大体的了解,为了提高我们的学习兴趣,在这一节我们将编写一个简单的基站定位程序.现在LBS(Location Based Service,基于位置的服务)移动应用相当流行(如:微信,切客,嘀咕,街旁等),基站定位是这类程序用到的关键性技术之一,我们来揭开它的神秘面纱吧. 在这一节里,我们会接触到事件.TelephonyManager.HTTP通信.JSON的使用等知识点. 在Android操作系统下,基站定位其实很简单,先说一下实现流程: 调用SD

  • Android开发之高德地图实现定位

    在应用开发中,地图开发是经常需要使用的"组件",Google Map虽然有官方教程,无奈用不起来,原因你懂的~~那么国内比较出名的是就是百度地图和高德地图,由于个人喜好,所以选择了高德地图LBS,废话不说,上干货. 1.注册开发者,创建应用 这个几乎是所有开放平台都通用的做法,无外乎注册帐号,成为开发者,然后创建一个Android应用,会为你分配一个key绑定你的服务. 注册key.PNG 2.下载SDK,导入jar包,add to library jar包.PNG 第一个是2D地图的

  • Android开发之自定义view实现通讯录列表A~Z字母提示效果【附demo源码下载】

    本文实例讲述了Android开发之自定义view实现通讯录列表A~Z字母提示效果.分享给大家供大家参考,具体如下: 开发工具:eclipse 运行环境:htc G9 android2.3.3 话不多说,先看效果图 其实左右边的A~Z是一个自定义的View,它直接覆盖在ListView上. MyLetterListView: public class MyLetterListView extends View { OnTouchingLetterChangedListener onTouching

  • 使用WEB工具快速提高Android开发效率

    正所谓工欲善其事,必先利其器.学习并应用优秀的轮子,可以让我们跑的更快,走的更远.这里所指的工具是广义的,泛指能帮助我们开发的东西,或者能提高我们效率的东西,包括:开发工具,监测工具,第三方代码库等. 在Google的广大支持下,便捷开发Android程序的Native工具层出不穷.其实Android开发涉及到的范围也不小,一些Web工具有时候也会带来事半功倍的效果.有些甚至是一些native应用无法做到的.本文,将简单列举一下本人正在使用的一些工具,当然也会持续更新. 查找优秀的参考工程 co

  • Android开发入门环境快速搭建实战教程

    前言 很多朋友都想开始自己的Android开发之旅,但是遇到困难重重.从最开始接触Android开发,从搭建开发环境就花了我大部分时间.所以,作为Android开发第一步,开发环境的搭建,显得基础而重要,下面介绍一种快速搭建Android开发环境的方法,以帮助更多朋友快速上手.话不多说了,来一起看看详细的介绍吧. 方法如下: 在开始之前,我们首先需要了解,当前开发android使用的主流开发平台为eclipse,因此本文讨论的是基于eclipse来做的. 具体需要的各个文件(软件)如下: Ecl

  • 一分钟快速定位Android启动耗时问题

    目录 前言 1. 接入Tencent Matrix 2. 改造Application子类 3.运行,快速定位 总结 前言 Tencent Matrix默认无法监测Application冷启动的耗时方法,本文介绍了如何改造Matrix支持冷启动耗时方法监测.让你一分钟就能给App启动卡顿号脉. 1. 接入Tencent Matrix 1.1 在你项目根目录下的 gradle.properties 中配置要依赖的 Matrix 版本号,如: MATRIX_VERSION=1.0.0 1.2 在你项目

  • Android开发快速实现底部导航栏示例

    目录 Tint 着色器 依赖(AndroidX) 布局 编写渲染颜色选择器-tint_selector_menu_color menu 文件中 icon-nav_bottom_menu BottomNavigationView的点击事件 配合ViewPager实现Tab栏 对应的适配器 Tint 着色器 优点:去除“无用”图片,节省空间 配合BottomNavigationView,实现一个快速,简洁的Tab栏 传统做法:Tab 切换,字体变色.图片变色.至少给我提供八张图,四张默认,四张选中,

随机推荐