最近在研究前辈写的代码,看到了有关于登陆界面的用户名和密码,使用的是自定义EditText的,所以写两篇相关文章来记录。

其实用户名和密码使用的EditText控件非常相似,拿用户名处使用的控件为例,它包括如下功能:

  • 在没内容的时候,不显示清除按钮,在有内容的时候,显示清除按钮
  • 在有内容的时候,点击清除按钮可以删除EditText中的内容

而在密码处使用的控件,包括如下功能:

  • 在没内容的时候,密码可见按钮不可用,在有内容的时候,显示密码可见按钮
  • 在有内容的时候,点击密码可见按钮即可显示密码

话不多说,开始写代码。

1.首先继承EditText,添加三个构造函数,如下:

public DIYEditText(Context context) {
        super(context);
}

public DIYEditText(Context context, AttributeSet attrs) {
        super(context, attrs, android.R.attr.editTextStyle);
}

public DIYEditText(Context context, AttributeSet attrs, int defStyle){
        super(context, attrs, defStyle);
}

2.为你自定义的EditText设置一些简单属性

如背景图片或者是背景颜色,

设置背景图片

设置控件左侧图片,

设置左侧图片

看到此处的getCompoundDrawables()[0],有人会比较疑惑,那么让我们来看一下这个东西到底是什么鬼,F3跳入函数,下面代码,

函数

原来EditText是TextView的子类,而在TextView的上下左右设置4张图片,我们可以通过getCompoundDrawables()函数来获取这四张图片,然后再给它们通过setCompoundDrawables()来赋值,就可以显示我们想要的图片了。

3.右侧删除按钮监听事件的设置

首先我们得在控件没内容的时候,不显示清除按钮,有内容的时候才显示清除按钮,所以我们可以根据内容的长短来实现这一功能,并且继承TextWatcher,实现其中的三个函数,在onTextChanged中调用如下函数,才能实现

    // 设置删除图片
    private void setClearDrawable() {
        if (length() < 1)
            setClearIconVisible(false);
        else
            setClearIconVisible(true);
    }
    /**
     * 设置清除图标的显示与隐藏,调用setCompoundDrawables为EditText绘制上去
     * 
     * @param visible
     */
    protected void setClearIconVisible(boolean visible) {
        setCompoundDrawables(getCompoundDrawables()[0],
                getCompoundDrawables()[1], visible ? mClearDrawable : null,
                getCompoundDrawables()[3]);
    }

删除按钮的点击事件,可以利用onTouchEvent函数来实现,

    /**
     * 点击删除按钮,清理内容
     */
    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            if (getCompoundDrawables()[2] != null) {
                boolean touchable = event.getX() > (getWidth() - getTotalPaddingRight())
                        && (event.getX() < ((getWidth() - getPaddingRight())));

                if (touchable) {
                    this.setText("");
                }
            }
            this.setFocusable(true);
            this.setFocusableInTouchMode(true);
            this.requestFocus();
        }
        return super.onTouchEvent(event);
    }

4.密码所用的EditText与上述的大同小异

这里主要讲解一下,密码是否可见的设置, 首先必须有两个Drawable,一个是密码可见时显示的图片,另外一个是密码不可见时显示的图片,

        mCloseDrawable = getCompoundDrawables()[2];
        mCloseDrawable = getResources().getDrawable(R.drawable.pwd_close);
        mCloseDrawable.setBounds(0, 0,
                (int) (mCloseDrawable.getIntrinsicWidth() * 0.65),
                (int) (mCloseDrawable.getIntrinsicHeight() * 0.65));

        mOpenDrawable = getCompoundDrawables()[2];
        mOpenDrawable = getResources().getDrawable(R.drawable.pwd_open);
        mOpenDrawable.setBounds(0, 0,
                (int) (mCloseDrawable.getIntrinsicWidth() * 0.65),
                (int) (mCloseDrawable.getIntrinsicHeight() * 0.65));

随后设置图片的点击事件,获取当前是否处于可见状态,代码如下:

/**
     * 设置密码是否可见图标
     */
    private void setPwdDrawable(boolean visiable) {
        Drawable right = visiable ? mOpenDrawable : mCloseDrawable;
        setCompoundDrawables(getCompoundDrawables()[0],
                getCompoundDrawables()[1], right, getCompoundDrawables()[3]);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            if (getCompoundDrawables()[2] != null) {
                boolean touchable = event.getX() > (getWidth() - getTotalPaddingRight())
                        && (event.getX() < ((getWidth() - getPaddingRight())));

                if (touchable) {
                    if (this.getInputType() == InputType.TYPE_TEXT_VARIATION_PASSWORD) {
                        this.setInputType(InputType.TYPE_CLASS_TEXT
                                | InputType.TYPE_TEXT_VARIATION_PASSWORD);
                        Editable etable = this.getText();
                        Selection.setSelection(etable, etable.length()); // 隐藏
                        setPwdDrawable(false);
                    } else {
                        this.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);
                        Editable etable = this.getText();
                        Selection.setSelection(etable, etable.length()); // 显示
                        setPwdDrawable(true);
                        this.invalidate();
                    }
                }
            }
        }
        return super.onTouchEvent(event);
    }

整个自定义控件核心代码如上,有何不足请各位多多指教。

代码地址:由于CSDN上传有问题,只能暂时放百度云了。

http://pan.baidu.com/s/1jGXZeiq 密码:brrn

1.出现问题:

今天打包具有双语的Android工程,在引用中报了一个莫名其妙的错误,如下图:问题出现也就是说在打包导出的时候有错误,再来看一下错误,

查看错误 "XXXX" is not translated in "en" (English), "zh" (Chinese)报的是Lint Warnings错误。

2.问题原因

根据错误信息,是说我没有对string文件进行国际化翻译操作,查看报错位置,原来是当前项目引用的一个Library有国际化操作,包含values-en和values-zh两个文件夹,才导致我到处当前项目的时候报出此错误。

3.临时方法

Eclipse->Windows-> Preferences->Android ->Lint Error Checking的Correctness: Messages ->MissingTranslate

临时解决办法把MissingTranslate的Severity的值改为Warning。

4.最终方法

如果你的项目是国际化,或是双语的,那么在项目中创建values-en和values-zh两个文件夹,然后把中文的string.xml放到values-zh问价夹下,把英文的string.xml放到values-en下。

image: feature: abstract-3.jpg credit: dargadgetz

creditlink: http://www.dargadgetz.com/ios-7-abstract-wallpaper-pack-for-iphone-5-and-ipod-touch-retina/

Below is just about everything you'll need to style in the theme. Check the source code to see the many embedded elements within paragraphs.

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
Heading 6

Body text

Lorem ipsum dolor sit amet, test link adipiscing elit. This is strong. Nullam dignissim convallis est. Quisque aliquam.

Smithsonian Image {: .image-right}

This is emphasized. Donec faucibus. Nunc iaculis suscipit dui. 53 = 125. Water is H<sub>2</sub>O. Nam sit amet sem. Aliquam libero nisi, imperdiet at, tincidunt nec, gravida vehicula, nisl. The New York Times <cite>(That’s a citation)</cite>. <u>Underline</u>. Maecenas ornare tortor. Donec sed tellus eget sapien fringilla nonummy. Mauris a ante. Suspendisse quam sem, consequat at, commodo vitae, feugiat in, nunc. Morbi imperdiet augue quis tellus.

HTML and <abbr title="cascading stylesheets">CSS<abbr> are our tools. Mauris a ante. Suspendisse quam sem, consequat at, commodo vitae, feugiat in, nunc. Morbi imperdiet augue quis tellus. Praesent mattis, massa quis luctus fermentum, turpis mi volutpat justo, eu volutpat enim diam eget metus.

Blockquotes

Lorem ipsum dolor sit amet, test link adipiscing elit. Nullam dignissim convallis est. Quisque aliquam.

List Types

Ordered Lists

  1. Item one

    1.  sub item one
    
    1. sub item two
    2. sub item three
  2. Item two

Unordered Lists

  • Item one
  • Item two
  • Item three

Tables

Header1 Header2 Header3
cell1 cell2 cell3
cell4 cell5 cell6
----
cell1 cell2 cell3
cell4 cell5 cell6
=====
Foot1 Foot2 Foot3

{: rules="groups"}

Code Snippets

Syntax highlighting via Pygments

# container {

  float: left;
  margin: 0 -240px 0 0;
  width: 100%;
}

Non Pygments code example

<<span class="hljs-keyword">div</span> <span class="hljs-property">id</span>=<span class="hljs-string">"awesome"</span>>
    <p>This <span class="hljs-keyword">is</span> great <span class="hljs-keyword">isn't</span> <span class="hljs-keyword">it</span>?</p>
</<span class="hljs-keyword">div</span>>

Buttons

Make any link standout more when applying the .btn class.

&lt;a href="#" class="btn btn-success"&gt;Success Button&lt;/a&gt;

<div markdown="0"><a href="#" class="btn">Primary Button</a></div> <div markdown="0"><a href="#" class="btn btn-success">Success Button</a></div> <div markdown="0"><a href="#" class="btn btn-warning">Warning Button</a></div> <div markdown="0"><a href="#" class="btn btn-danger">Danger Button</a></div> <div markdown="0"><a href="#" class="btn btn-info">Info Button</a></div>

前言『Android进程中有许多需要学习的地方,在这里简单介绍一下进程重要性等级的一些知识』 下面是关于进程属性importance的介绍

        /**
         * The relative importance level that the system places on this
         * process.  May be one of {@link #IMPORTANCE_FOREGROUND},
         * {@link #IMPORTANCE_VISIBLE}, {@link #IMPORTANCE_SERVICE},
         * {@link #IMPORTANCE_BACKGROUND}, or {@link #IMPORTANCE_EMPTY}.  These
         * constants are numbered so that "more important" values are always
         * smaller than "less important" values.
         */
        public int importance;

其意思概括来说就是,进行重要性是相对来说的,重要性等级分为5种,前台进程,可见进程,服务进程,后台进程和空进程。并且这个值越小,它的重要程度越大,所以在需要内存时,importance值越小的进程优先被杀死。

下面来简单介绍一些这5种进程:

1.前台进程:

        /**
         * Constant for {@link #importance}: this process is running the
         * foreground UI.
         * 处在UI界面最前面的process的importance值为100
         */
        public static final int IMPORTANCE_FOREGROUND = 100;

屏幕上显示的进程。我们最不希望结束的进行就是前台进行,所以它的importance最小。 下面让我们来看一下官方给出的前台进程的例子:

    It hosts an Activity that the user is interacting with (the Activity's onResume() method has been called).

    It hosts a Service that's bound to the activity that the user is interacting with.

    It hosts a Service that's running "in the foreground"—the service has called startForeground().

    It hosts a Service that's executing one of its lifecycle callbacks (onCreate(), onStart(), or onDestroy()).

    It hosts a BroadcastReceiver that's executing its onReceive() method.

2.可见进程:

        /**
         * Constant for {@link #importance}: this process is running something
         * that is actively visible to the user, though not in the immediate
         * foreground.
         * 正在运行的App,处于用户可见的importance的值为200,
         */
        public static final int IMPORTANCE_VISIBLE = 200;

可见进程是一些不在前台,但用户依然可见的进程,举个例来说:widget、输入法等,都属于visible。这部分进程虽然不在前台,但与我们的使用也密切相关,我们也不希望它们被终止(你肯定不希望时钟、天气,新闻等widget被终止,那它们将无法同步,你也不希望输入法被终止,否则你每次输入时都需要重新启动输入法) 官方文档例子:

    It hosts an Activity that is not in the foreground, but is still visible to the user (its onPause() method has been          called). This might occur, for example, if the foreground activity started a dialog, which allows the previous               activity to be seen behind it.

    It hosts a Service that's bound to a visible (or foreground) activity.

3.服务进程:分为主要服务、次要服务

        /**
         * Constant for {@link #importance}: this process is contains services
         * that should remain running.
         */
        public static final int IMPORTANCE_SERVICE = 300;

目前正在运行的一些服务(主要服务,如拨号等,是不可能被进程管理终止的,故这里只谈次要服务),举例来说:谷歌企业套件,Gmail内部存储,联系人内部存储等。这部分服务虽然属于次要服务,但很一些系统功能依然息息相关,我们时常需要用到它们,所以也太希望他们被终止。

4.后台服务:

        /**
         * Constant for {@link #importance}: this process process contains
         * background code that is expendable.
         */
        public static final int IMPORTANCE_BACKGROUND = 400;

就是我们通常意义上理解的启动后被切换到后台的进程,如浏览器,阅读器等。当程序显示在屏幕上时,他所运行的进程即为前台进程(foreground),一旦我们按home返回主界面(注意是按home,不是按back),程序就驻留在后台,成为后台进程(background)。

后台进程的管理策略有多种:有较为积极的方式,一旦程序到达后台立即终止,这种方式会提高程序的运行速度,但无法加速程序的再次启动;也有较消极的方式,尽可能多的保留后台程序,虽然可能会影响到单个程序的运行速度,但在再次启动已启动的程序时,速度会有所提升。这里就需要用户根据自己的使用习惯找到一个平衡点

5.空进程:

        /**
         * Constant for {@link #importance}: this process is empty of any
         * actively running code.
         */
        public static final int IMPORTANCE_EMPTY = 500;

没有任何东西在内运行的进程,有些程序,比如BTE,在程序退出后,依然会在进程中驻留一个空进程,这个进程里没有任何数据在运行,作用往往是提高该程序下次的启动速度或者记录程序的一些历史信息。 这部分进程无疑是应该最先终止的。

6.在官方文档中还给出了三种进行的importance值,分别为:可触摸到的、可保存状态和不存在的进程(搞不懂这个是用来干什么的)

        /**
         * Constant for {@link #importance}: this process is running something
         * that is considered to be actively perceptible to the user.  An
         * example would be an application performing background music playback.
         */
        public static final int IMPORTANCE_PERCEPTIBLE = 130;
        /**
         * Constant for {@link #importance}: this process is running an
         * application that can not save its state, and thus can't be killed
         * while in the background.
         *
         * @hide
         */
        public static final int IMPORTANCE_CANT_SAVE_STATE = 170;
        /**
         * Constant for {@link #importance}: this process does not exist.
         */
        public static final int IMPORTANCE_GONE = 1000;

资料来自于Google谷歌官方开发文档

在W3School网站上看到,可以把SQL语句分为两部分:数据操作语言 (DML) 和 数据定义语言 (DDL)。

查询和更新指令构成了 SQL 的 DML 部分:

  • SELECT - 从数据库表中获取数据
  • UPDATE - 更新数据库表中的数据
  • DELETE - 从数据库表中删除数据
  • INSERT INTO - 向数据库表中插入数据

SQL 中最重要的 DDL 语句:

  • CREATE DATABASE - 创建新数据库
  • ALTER DATABASE - 修改数据库
  • CREATE TABLE - 创建新表
  • ALTER TABLE - 变更(改变)数据库表
  • DROP TABLE - 删除表
  • CREATE INDEX - 创建索引(搜索键)
  • DROP INDEX - 删除索引

1.创建数据库

CREATE DATABASE dbname

2.删除数据库

DROP DATABASE dbname

3.SELECT 语句

用于从列表中选取数据,结果被存储在一个结果表中。语法如下:

SELECE 列名 FROM 表名  or SELECT * FROM 表名

4.DISTINCT 语句

关键词 DISTINCT 用于返回唯一不同的值。

在表中,可能会包含重复值。这并不成问题,不过,有时您也许希望仅仅列出不同(distinct)的值。也就是俗话说的去重。

SELECT DISTINCT 列名 FROM 表名

5.WHERE 语句

有条件地从表中选取数据,可把WHERE语句添加到SELECT中。语法:

SELECT 列名 FROM 表名 WHERE  运算符 

在用在WHERE语句中的运算符:

sql-like

5.AND和OR

用于基于一个以上的条件对记录进行过滤。

AND 和 OR 可在 WHERE 子语句中把两个或多个条件结合起来。

如果第一个条件和第二个条件都成立,则 AND 运算符显示一条记录。

如果第一个条件和第二个条件中只要有一个成立,则 OR 运算符显示一条记录。

6.ORDER BY 语句

用于对结果进行排序。

ORDER BY 语句用于根据指定的列对结果集进行排序。

ORDER BY 语句默认按照升序(ASC)排序。如果希望降序排序的话,可以使用 DESC 关键字。

7.INSERT INTO 语句

用于向表中插入新行。

语法:

INSERT INTO 表名称 VALUES (1, 2,....)

我们也可以指定所要插入数据的列:

INSERT INTO table_name (1, 2,...) VALUES (1, 2,....)

8.UPDATE 语句

用于修改表中的数据。

语法:

UPDATE 表名 SET 列名 = 新值 WHERE 列名 = 某值

9.DELETE 语句

用于删除表中的行。

语法:

DELETE FROM 表名 WHERE 列名 = 

删除所有行:

DELETE * FROM table_name or  DELETE FROM table_name

10.LIKE 操作符

用于在 WHERE 子句中搜索列中的指定模式。

语法:

SELECT column_name(s)
FROM table_name
WHERE column_name LIKE pattern

LIKE的几种模式:

  • 'A_Z': 所有以 'A' 起头,另一个任何值的字,且以 'Z' 为结尾的字串。 'ABZ' 和 'A2Z' 都符合这一个模式,而 'AKKZ' 并不符合 (因为在 A 和 Z 之间有两个字,而不是一个字)。

  • 'ABC%': 所有以 'ABC' 起头的字串。举例来说,'ABCD' 和 'ABCABC' 都符合这个套式。

  • '%XYZ': 所有以 'XYZ' 结尾的字串。举例来说,'WXYZ' 和 'ZZXYZ' 都符合这个套式。

  • '%AN%': 所有含有 'AN' 这个套式的字串。举例来说, 'LOS ANGELES' 和 'SAN FRANCISCO' 都符合这个套式。

11.IN 操作符

允许我们再WHERE子句中规定多个值。

语法:

SELECT column_name(s)
FROM table_name
WHERE column_name IN(value1,value2,...)

12.JOIN

用于根据两个或多个表中的列之间的关系,从这些表中查询数据。