zoukankan      html  css  js  c++  java
  • 自己定义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

  • 相关阅读:
    搜索部分学习小结
    递归与搜索部分知识点小结
    匿名函数
    监督学习和非监督学习
    单变量线性回归
    神经网络(2)
    html
    javascript
    win10+celery4.x以上+redis的天坑
    Django-Views
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5192831.html
Copyright © 2011-2022 走看看