因为项目须要,也不想使用网上的写好的控件,于是作死的自己定义了一个控件。特此记录下成功。效果例如以下:

首先须要把全部的字母绘制出来:

private static String letters[] = {
"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 mPaint;
//当前控件的宽高
private int mWidth;
private int mHegiht;
// 每一个文字item的高度
private int letterItemHeight; private void init() {
// 初始化画笔
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(Color.GRAY);
mPaint.setTextSize(32.0f);
} @Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
mWidth = getWidth();
mHegiht = getHeight();
letterItemHeight = mHegiht/letters.length;
} @Override
protected void onDraw(Canvas canvas) { for (int i=0; i<letters.length; i++){
// 计算文字绘制的x值:控件宽度的一半 减去 測量文字宽度的一半
float x = mWidth/2 - mPaint.measureText(letters[i])/2;
float y = (i + 1)*letterItemHeight;
canvas.drawText(letters[i], x, y, mPaint);
}
}

在init方法中初始化画笔及其画笔颜色和画笔大小,在onLayout布局的时候获取当前自己定义View的控件宽高和每一个字母item的高度。接下来是绘制,在绘制的时候须要获取到每一个字母的x、y值。x值即:字母左边缘到控件左边缘的距离:(逗比。图太丑不予评论 orz)



如图,蓝色的框代表自己定义控件。红色框代表字母。紫色线是控件宽度的一半,绿色线是字母文字宽度的一半,粉红色就是要绘制的文字的x值。所以,非常显然 x = 紫色 - 绿色。

y的值计算,因为文字的绘制是基于baseline基准线的。所以每一个字母item的基准线就是(i + 1)letterItemHeight。详细的能够深入学习大神爱哥的自己定义View系列blog

增加Touch事件,并获取所点击的字母:

private OnTouchLettersListener onTouchLettersListener;
@Override
public boolean dispatchTouchEvent(MotionEvent event) { final float y = event.getY();
// 数组下标
final int index = (int)(y/mHegiht*letters.length);
final OnTouchLettersListener listener = onTouchLettersListener;
final int action = event.getAction();
switch (action){
case MotionEvent.ACTION_UP:
setBackgroundColor(getResources().getColor(android.R.color.transparent));
invalidate();
break;
default:
setBackgroundColor(getResources().getColor(R.color.gray));
if (index >= 0 && index < letters.length){
if (listener != null){
//把点击的字母信息回调出去给使用者
listener.onTouchLetters(letters[index]);
}
}
invalidate();
break;
} return true;
} public interface OnTouchLettersListener{
public void onTouchLetters(String s);
} public void setOnTouchLettersListener(OnTouchLettersListener onTouchLettersListener){
this.onTouchLettersListener = onTouchLettersListener;
}

重写dispatchTouchEvent事件方法。首先获取每次点击的相对于当前View的y值,通过y/mHegiht*letters.length就是依据点击的在整个控件大概比例*数组总长度。计算出下标值来获取letters数组中的字母回调出去。(这是一个大概的值,误差也不会大)

在ACTION_UP的时候我们把控件的背景色设置为透明的。其他其他情况设置了一个灰色值。

使用这个自己定义的控件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"> <com.jerry.testproject.view.LetterSiderBar
android:id="@+id/letter"
android:layout_centerInParent="true"
android:layout_width="45dp"
android:layout_height="match_parent" /> </RelativeLayout> package com.jerry.testproject; import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity; import com.jerry.testproject.view.LetterSiderBar;
import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.view.annotation.ViewInject; public class MainActivity extends AppCompatActivity implements LetterSiderBar.OnTouchLettersListener{ @ViewInject(R.id.letter)
private LetterSiderBar mLetterSiderBar; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewUtils.inject(this);
mLetterSiderBar.setOnTouchLettersListener(this);
} // 实现回调的方法
@Override
public void onTouchLetters(String s) {
Snackbar.make(mLetterSiderBar, "你选择了:" + s, Snackbar.LENGTH_SHORT).show();
}
}

这里使用了xUtils开源组件的视图注解方式来初始化控件。以及使用了22.2.0 api支持包design的相似于Toast的提示控件Snackbar来作为提示,AS的开发人员仅仅要引入:compile ‘com.android.support:design:22.2.0’ 就能够使用了。

下面是项目下载地址:

http://download.csdn.net/detail/abren32/8895649

自己定义View----点击滑动选择字母列表的更多相关文章

  1. vue-cli 3.0 实现A-Z字母滑动选择城市列表

    项目地址: https://github.com/caochangkui/vue-cli3 项目代码: 城市列表首页: City.vue <template> <div id=&qu ...

  2. 图文剖析自己定义View的绘制(以自己定义滑动button为例)

    自己定义View一直是横在Android开发人员面前的一道坎. 一.View和ViewGroup的关系 从View和ViewGroup的关系来看.ViewGroup继承View. View的子类.多是 ...

  3. Qt--自定义View

    这是上一篇文章的续篇,关于自定义View. 多个View内部可以映射到同一个数据模型,也可以映射不同的数据结构:可以使用所有数据,也可以只使用部分数据.因为视图层与数据层的分离,操作相对比较灵活. 1 ...

  4. 自己定义View Controller转换动画

    原文链接 : Introduction to Custom View Controller Transitions and Animations 原文作者 : joyce echessa 译文出自 : ...

  5. 自己定义View步骤

     概述 Android已经为我们提供了大量的View供我们使用,可是可能有时候这些组件不能满足我们的需求,这时候就须要自己定义控件了.自己定义控件对于刚開始学习的人总是感觉是一种复杂的技术. 由于 ...

  6. Android自己定义View的实现方法

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/17357967 不知不觉中,带你一步步深入了解View系列的文章已经写到第四篇了.回 ...

  7. Android自己定义View基础篇(三)之SwitchButton开关

    自己定义View基础篇(二) 自己定义View基础篇(一) 自己定义View原理 我在解说之前,先来看看效果图,有图有真相:(转换gif图片效果太差) 那来看看真实图片: 假设你要更改样式,请改动例如 ...

  8. 自己定义View实现水平滚动控件

    前几天项目中须要使用到一个水平可滚动的选择条,类似下图效果(图片是从简书上一位作者那儿找来的,本篇也是在这位作者的文章的基础上改动的,站在大神的肩膀上,哈哈,因为原文没有提供demo,并且实现的效果跟 ...

  9. 【代码笔记】iOS-点击出现选择框

    一,效果图. 二,工程图. 三,代码. RootViewController.h #import <UIKit/UIKit.h> @interface RootViewController ...

随机推荐

  1. scanf函数和printf函数

    C程序实现输出和输入的 主要是printf函数 和 scanf函数,这两个函数是格式输入输出 格式声明由%和格式字符组成 如%d,%f 格式字符:  d格式符:用来输出一个有符号的十进制整数  c格式 ...

  2. ROS使用rqt_console

    打开一个新的终端在里面输入: sudo apt-get install ros-hydro-rqt ros-hydro-rqt-common-plugins ros-hydro-turtlesim 安 ...

  3. 常用的Linux操作命令(一)

    ls 目录 mkdir 创建文件夹 vi 新建文件 :w filename 将文章存入指定的文件名filename :wq 保存并退出编辑文件 :q! 强制离开并放弃编辑的文件 cd 切换到目录/ro ...

  4. MVC上传文件受限制

    mvc自带设置4M一下的字体可以上传,4M以上的字体需要对web.config进行设置 <system.web> <httpRuntime targetFramework=" ...

  5. $()和getElementById()的区别

    jQuery的成功多归功于其强大的选择器. 然而,相信不少初学jQuery的同学都会遇到下面的问题. 在javascript下,我们可以根据getElementById()来获取页面元素.如下: va ...

  6. codevs 1028 花店橱窗布置 KM算法

    题目链接 n个花, m个花瓶, 每个花放到一个花瓶里会产生一个值w[i][j], 一个花只能放到一个花瓶里, 一个花瓶只能放一个花, 求产生的最大值. 带权二分图模板. #include <io ...

  7. java反编译命令javap

    1. 输出所有类和成员 javap -private XX.class 2. 输出分解后的代码 javap -c XX.class

  8. HDOJ-ACM Steps

    在这里放几道Steps里的题目把. find your present (2) Time Limit: 1000/2000 MS (Java/Others) Memory Limit: 32768/1 ...

  9. linux环境变量配置总结

    LD_LIBRARY_PATH: 动态库的查找路径设置:方法一: export  LD_LIBRARY_PATH=LD_LIBRARY_PATH:/XXX 但是登出后就失效方法二: 修改~/.bash ...

  10. HDU ACM 1063 Exponentiation 大实数乘方

    分析:大实数乘方计算. #include<iostream> #include<string> using namespace std; struct BigReal //高精 ...