现在我们的手机上基本都会有一个记事本,用起来倒也还算方便,记事本这种东东,如果我想要自己实现,该怎么做呢?今天我们就通过自定义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

以上。

android自定义View之NotePad出鞘记的更多相关文章

  1. android自定义View之钟表诞生记

    很多筒子觉得自定义View是高手的象征,其实不然.大家觉得自定义View难很多情况下可能是因为自定义View涉及到了太多的类和API,把人搞得晕乎乎的,那么今天我们就从最简单的绘图API开始,带大家来 ...

  2. Android自定义View之ProgressBar出场记

    关于自定义View,我们前面已经有三篇文章在介绍了,如果筒子们还没阅读,建议先看一下,分别是android自定义View之钟表诞生记.android自定义View之仿通讯录侧边栏滑动,实现A-Z字母检 ...

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

    我们的手机通讯录一般都有这样的效果,如下图: OK,这种效果大家都见得多了,基本上所有的android手机通讯录都有这样的效果.那我们今天就来看看这个效果该怎么实现. 一.概述 1.页面功能分析 整体 ...

  4. Android 自定义View及其在布局文件中的使用示例(三):结合Android 4.4.2_r1源码分析onMeasure过程

    转载请注明出处 http://www.cnblogs.com/crashmaker/p/3549365.html From crash_coder linguowu linguowu0622@gami ...

  5. Android自定义View 画弧形,文字,并增加动画效果

    一个简单的Android自定义View的demo,画弧形,文字,开启一个多线程更新ui界面,在子线程更新ui是不允许的,但是View提供了方法,让我们来了解下吧. 1.封装一个抽象的View类   B ...

  6. (转)[原] Android 自定义View 密码框 例子

    遵从准则 暴露您view中所有影响可见外观的属性或者行为. 通过XML添加和设置样式 通过元素的属性来控制其外观和行为,支持和重要事件交流的事件监听器 详细步骤见:Android 自定义View步骤 ...

  7. Android 自定义View合集

    自定义控件学习 https://github.com/GcsSloop/AndroidNote/tree/master/CustomView 小良自定义控件合集 https://github.com/ ...

  8. Android 自定义View (五)——实践

    前言: 前面已经介绍了<Android 自定义 view(四)-- onMeasure 方法理解>,那么这次我们就来小实践下吧 任务: 公司现有两个任务需要我完成 (1)监测液化天然气液压 ...

  9. Android 自定义 view(四)—— onMeasure 方法理解

    前言: 前面我们已经学过<Android 自定义 view(三)-- onDraw 方法理解>,那么接下我们还需要继续去理解自定义view里面的onMeasure 方法 推荐文章: htt ...

随机推荐

  1. mac 修改密码后 频繁输入钥匙串问题修复方法

    就一句话就是 清空钥匙串缓存 下面是具体方法 进入硬盘目录-->资源库-->Keychains 删除里面的文件夹(这个文件夹里面有 keychain-2.db keychain-2.db- ...

  2. ☀【动画】过渡 transition

    CSS3 动画系列3-transition(过渡) √http://www.css88.com/archives/5403 如果丘处机没有路过牛家村,中国将是最发达国家 <!DOCTYPE ht ...

  3. 如何删除已上线的IAP项

    cleared for sale to NO. then Delete.

  4. Linux下归档与压缩工具笔记

    tar具体使用笔记 归档工具 tar 语法 功能 选项 常见搭配 压缩工具 bzip2 工具 使用方法 gzip 工具 zip 工具 归档工具 tar tar是一个开源的Linux/Unix中最广泛使 ...

  5. import project后,出现Unable to get system library for the project

    import project 后,出现Unable to get system library for the project. 这是因为在import 一个项目的时候,没有指定android sdk ...

  6. Get ListView items from other windows z

    This is more difficult than one might think. In order to get the information you're looking for, you ...

  7. hunnu---11547 你的组合数学学得如何?

    解析:比较简单的DP,从左向右一个一个连续着放,dp[X][Y]表示到第X个硬币的时候Y状态的方案数,Y=0表示x左边那个不是正面的,Y=1表示x左边那个是正面 如果左边不是正面,那么当前放正面的就把 ...

  8. loadrunner SQL2008

    1. 下载 JDBC 驱动(sqljdbc4.jar) 2. 在 run-time setting 下的 classpath 把 JDBC 驱动引入 /* * LoadRunner Java scri ...

  9. python导入模块时的路径疑惑

    有一个事儿,以前没注意,今天发现了,记录一下. 假设一个python文件a.py中,有一段代码,是打印当前路径的.当单独执行a.py文件的时候,打印的是a.py的位置. 但是当a.py文件被其他pyt ...

  10. Datatable转换成List实体对象列表 几个实例

    一, /// <summary> /// 将Datatable转换为List集合 /// </summary> /// <typeparam name="T&q ...