自定义View----点击滑动选择字母列表

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

首先需要把所有的字母绘制出来:

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

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-26 17:53:27

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

Android 自定义view实现上下滑动,大众点评,美团地图导航界面。

主函数: package com.example.slideview; import com.example.fdadsf.R; import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.LinearLayout; import android.widget.ListView; import android.app.Activity; /** * 滑动菜单Demo主Activity *

【Android】自定义View —— 滑动的次数选择器

[关键词] 自定义View 次数选择器 滑动 [问题] 实现一个可滑动的次数选择器: [效果图] 「原型图」 「实现图」 [分析] 对外提供简单的Change监听接口: 如果处于两者之间就需要做判断:大于一半就自动跳转到下一个,小于一半,则回到上一个: 通过Scroller及其startScroll()方法来实现回弹效果: 要灵活控制刻度的最小值和最大值,因为可能随着需求的更改,这个值很容易发生改变(即处理好对应关系): 在自定义View中只画刻度和文字,至于红色的指针和外面的透明渐变图层则可以

Android 自定义View合集

自定义控件学习 https://github.com/GcsSloop/AndroidNote/tree/master/CustomView 小良自定义控件合集 https://github.com/Mr-XiaoLiang 自定义控件三部曲 http://blog.csdn.net/harvic880925?viewmode=contents Android 从0开始自定义控件之View基础知识与概念 http://blog.csdn.net/airsaid/article/details/5

Android自定义View之仿QQ侧滑菜单实现

最近,由于正在做的一个应用中要用到侧滑菜单,所以通过查资料看视频,学习了一下自定义View,实现一个类似于QQ的侧滑菜单,顺便还将其封装为自定义组件,可以实现类似QQ的侧滑菜单和抽屉式侧滑菜单两种菜单. 下面先放上效果图: 我们这里的侧滑菜单主要是利用HorizontalScrollView来实现的,基本的思路是,一个布局中左边是菜单布局,右边是内容布局,默认情况下,菜单布局隐藏,内容布局显示,当我们向右侧滑,就会将菜单拉出来,而将内容布局的一部分隐藏,如下图所示: 下面我们就一步步开始实现一个

android自定义View之仿通讯录侧边栏滑动,实现A-Z字母检索

我们的手机通讯录一般都有这样的效果,如下图: OK,这种效果大家都见得多了,基本上所有的Android手机通讯录都有这样的效果.那我们今天就来看看这个效果该怎么实现. 一.概述 1.页面功能分析 整体上来说,左边是一个ListView,右边是一个自定义View,但是左边的ListView和我们平常使用的ListView还有一点点不同,就是在ListView中我对所有的联系人进行了分组,那么这种效果的实现最常见的就是两种思路: 1.使用ExpandableListView来实现这种分组效果 2.使

Android 自定义View——自定义点击事件

每个人手机上都有通讯录,这是毫无疑问的,我们通讯录上有一个控件,在通讯录的最左边有一列从"#"到"Z"的字母,我们通过滑动或点击指定的字母来确定联系人的位置,进而找到联系人.我们这一节就通过开发这个控件,来学如何自定义控件的点击事件. 通讯录列表查找控件界面绘制 首先我们需要先将控件的基本布局绘制出来,这里我们不在做详细的解释,在<Android 自定义View--自定义View控件 >博客中,我们已经详细讲解了如何绘制自定义控件的布局.通讯录列表查找控

Android 自定义 View 实现通讯录字母索引(仿微信通讯录)

一.效果:我们看到很多软件的通讯录在右侧都有一个字母索引功能,像微信,小米通讯录,QQ,还有美团选择地区等等.这里我截了一张美团选择城市的图片来看看: 我们今天就来实现图片中右侧模块的索引功能,包括触摸显示以选中的索引字母.这里我的UI界面主要是参照微信的界面来实现,所以各位也可以对照微信来看看效果,什么都不说了,只有效果图最具有说服力! 二.分析: 我们看到这样的效果我们心理都回去琢磨,他是如何实现的: 首先,它肯定是通过自定义 View 来实现的,因为 Android 没有提供类似这样的控件

自定义View 之利用ViewPager 实现画廊效果(滑动放大缩小)

自定义View 之利用ViewPager 实现画廊效果(滑动放大缩小) 转载请标明出处: http://blog.csdn.net/lisdye2/article/details/52315008 本文出自:[Alex_MaHao的博客] 项目中的源码已经共享到github,有需要者请移步[Alex_MaHao的github] 基本介绍 画廊在很多的App设计中都有,如下图所示: 该例子是我没事的时候写的一个小项目,具体源码地址请访问https://github.com/AlexSmille/Y

Android自定义View(RollWeekView-炫酷的星期日期选择控件)

转载请标明出处: http://blog.csdn.net/xmxkf/article/details/53420889 本文出自:[openXu的博客] 目录: 1分析 2定义控件布局 3定义CustomWeekView 4重写onMeasure 5点击后执行动画 7重置预备控件 源码下载 ??最近收到一个自定义控件的需求,需要做一个日期选择控件,实现图如下: ???? ??一次展示一个星期的5天,中间放大的为当前选中的:如果点击了其中一个日期,比如星期五,那么整体向左滑动,并将星期五慢慢放大