zoukankan      html  css  js  c++  java
  • android自定义View之NotePad出鞘记

    现在我们的手机上基本都会有一个记事本,用起来倒也还算方便,记事本这种东东,如果我想要自己实现,该怎么做呢?今天我们就通过自定义View的方式来自定义一个记事本。OK,废话不多说,先来看看效果图。


    整个页面还是很简单的。

    1.自定义View的分类

    OK,那么在正文开始之前,我想先来说说自定义View的分类,自定义View我们一共分为三类

    1.自绘控件

    自绘控件就是我们自定义View继承自已有控件,然后扩展其功能,之前两篇自定义View的博客(android自定义View之钟表诞生记android自定义View之仿通讯录侧边栏滑动,实现A-Z字母检索)都是属于这一种。

    2.继承自现有控件扩展其功能

    有的时候,我们也可以继承自一个现有控件然后扩展其功能,比如我们马上要说的这个Notepad,就是继承自EditText,然后扩展其功能

    3.组合控件

    就是把一些已有的控件组合到一起,形成一个新的控件,这种效果可以参考我之前的博客android自定义UI模板图文详解

    2.实现思路

    OK,说完了自定义View的分类,接下来我们来看看本文要介绍的NotePad的一个实现思路。首先,这种类似于笔记本的背景其实就是一张图片,但是这一条一条的线都是我通过canvas中的drawLine这个API绘制上去的。当我点击回车的时候,我再继续去绘制新的横线即可。这个整体思路也很简单。

    3.代码实现

    首先我来创建一个类,继承自EditText,然后我先来声明几个变量,如下:

        //横线的线宽
        private int lineWidth = 1;
        //横线的颜色
        private int lineColor = Color.BLACK;
        //行间距
        private int spacing_line = 10;
        //内边距
        private int padding = 10;
        //画笔
        private Paint mPaint;

    然后在构造方法 中完成一些初始化的操作,如下:

    public NotePad(Context context) {
            this(context, null);
        }
    
        public NotePad(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public NotePad(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            setFocusableInTouchMode(true);
            setGravity(Gravity.TOP);
            setLineSpacing(spacing_line, 1);
            setPadding(25, 10, padding, 10);
            mPaint = new Paint();
            mPaint.setColor(lineColor);
            mPaint.setStrokeWidth(lineWidth);
        }
    setFocusableInTouchMode方法可以让我的NotePad获得焦点,setGravity让我NotePad中光标的默认位置处于控件的左上角,setLineSpacing方法主要是设置行间距,setPadding就是设置内边距,最后的画笔初始化就不必多说了。

    OK ,完成了初始化的操作之后,接下来我们就可以来完成横线的绘制了,代码如下:

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            //获取屏幕的高度
            int viewHeight = getHeight();
            //获取每行文本的高度
            int lineHeight = getLineHeight();
            //计算每页一共有多少行
            int pageCount = viewHeight / lineHeight;
            //循环绘制横线
            for (int i = 0; i < pageCount; i++) {
                canvas.drawLine(padding, (i + 1) * lineHeight, getWidth() - padding, (i + 1) * lineHeight, mPaint);
            }
            //获取当前文本的总行数
            int lineCount = getLineCount();
            //文本的行数减去每页的行数,剩余的值就是我还要继续绘制的行数
            int extraCount = lineCount - pageCount;
            if (extraCount > 0) {
                for (int i = pageCount; i < lineCount; i++) {
                    canvas.drawLine(padding, (i + 1) * lineHeight, getWidth() - padding, (i + 1) * lineHeight, mPaint);
                }
            }
        }

    代码解释请看注释。

    OK,就是这么简单。最后,我们在布局文件中来引用一下我的这个自定义控件:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="org.lenve.notepad.MainActivity">
    
        <org.lenve.notepad.NotePad
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/background"/>
    </RelativeLayout>
    

    做完这些之后,就可以让你的应用跑起来了。

    源码下载http://download.csdn.net/detail/u012702547/9502328


    以上。


  • 相关阅读:
    The Mac Application Environment 不及格的程序员
    Xcode Plugin: Change Code In Running App Without Restart 不及格的程序员
    The property delegate of CALayer cause Crash. 不及格的程序员
    nil localizedTitle in SKProduct 不及格的程序员
    InApp Purchase 不及格的程序员
    Safari Web Content Guide 不及格的程序员
    在Mac OS X Lion 安装 XCode 3.2 不及格的程序员
    illustrate ARC with graphs 不及格的程序员
    Viewing iPhoneOptimized PNGs 不及格的程序员
    What is the dSYM? 不及格的程序员
  • 原文地址:https://www.cnblogs.com/lenve/p/5865902.html
Copyright © 2011-2022 走看看