EditText监听,根据输入内容查询数据并动态更新ListView

最后更新于:2022-04-01 19:58:10

EditText监听,根据输入内容查询数据并动态更新ListView Email:chentravelling@163.com 电话簿里有一个很实用的功能,就是根据姓名或者电话号码搜索联系人;很多网站或者软件有回复、评论、注册等功能,会限制输入字数,每当用户输入一个字数字后,会动态显示已经输入的字数或者剩余还能输入多少数字。在android系统里,我们可以通过对EditText进行监听,如果内容发生了改变就执行某项操作就行。 - 环境 > IDE:Android Studio > JDK:1.8 > 系统:win7 64位 - 声明: > 1)我查询数据和适配器是Cursor和SimpleCursorAdapter > 2)关于ListView显示数据和动态更新可戳这里《[Cursor记录集游标、ListView和SimpleCursorAdapter、ListView数据动态更新](http://blog.csdn.net/chentravelling/article/details/50364162)》 - 步骤1:在Activity(继承ListActivity)中增加全局变量 ~~~ private AddressDAO addressDAO;//操作数据库的类 private SimpleCursorAdapter adapter;//适配器 private Cursor cursor;//记录集游标 private EditText searchText;//搜索栏 private String condition;//查询条件 ~~~ - 步骤2:在onCreate中为搜索栏添加监听事件 ~~~ //需要先导入 import android.text.TextWatcher; //然后添加监听事件 searchText = (EditText)findViewById(R.id.search); searchText.addTextChangedListener(textWatcher); ~~~ - 步骤3:监听事件 ~~~ TextWatcher textWatcher = new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { //Toast.makeText(ShowAddressActivity.this,"beforeTextChanged ",Toast.LENGTH_SHORT).show(); } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { //Toast.makeText(ShowAddressActivity.this,"onTextChanged ",Toast.LENGTH_SHORT).show(); } @Override public void afterTextChanged(Editable s) { //Toast.makeText(ShowAddressActivity.this,"afterTextChanged ",Toast.LENGTH_SHORT).show(); condition = searchText.getText().toString(); try{ cursor = addressDAO.conditionQuery(condition); adapter.changeCursor(cursor); }catch(Exception e){} // new RefresListR().execute(); } }; ~~~ - 声明:adapter.changeCursor(Cursor)相当于通知适配器当前的数据集cursor已经改变了,需要刷新ListView了 - 步骤4:查询数据,才数据库操作类中增加查询函数 ~~~ //查询数据:返回的是一个Cursor对象 public Cursor conditionQuery(String condition) { String sql; if(condition.length()>0||!"".equals(condition)) { sql = "select * from people where name like '%"+condition+"%' or phone like '%"+condition+"%'"; }else { sql = "select * from people"; } //获取SQLiteDatabase对象实例 db = this.getReadableDatabase(); Cursor cursor = db.rawQuery(sql, null); return cursor; } ~~~ 通过上面4个步骤,基本可以完成在搜索栏根据输入的文字进行条件查询,亲测了一下。当然可能数据过多的时候,采用这个方法可能会造成读取时间长的问题,那么最好可以使用后台线程读取数据库,可参考《[Cursor记录集游标、ListView和SimpleCursorAdapter、ListView数据动态更新](http://blog.csdn.net/chentravelling/article/details/50364162)》。 初学者个人理解,难免有误,欢迎指正。
';

发送短息和拨打电话功能

最后更新于:2022-04-01 19:58:08

发送短息和拨打电话功能 Email:chentravelling@163.com 捣腾了一小会,实现了拨打电话和发送短信的功能,作为手机的基本功能,还是值得一尝试,在此小结一下。 环境: IDE:Android Studio JDK:1.8 系统:win7 64位 1.拨打电话 - 步骤1:在AndroidMainfest.xml文件中获取拨打电话的权限,增加以下内容: ~~~ ~~~ - 步骤2:通过Intent作为通信桥梁,实现打电话。在Activity中增加以下代码: ~~~ Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:"+phone)); try{ startActivity(callIntent); }catch(Exception e) { return; } ~~~ 备注: (1)这段代码可以有其他形式,无非都是设置intent对象的一些参数,主要是拨打的电话号码。 (2)如果没有try{}..catch{}块,会提示错误的,但是看到网上很多版本都没有try..catch,至少我遇到错误了。 (3)其次可以通过checkPermission()来判断是否获取了权限。 (4)Intent.ACTION_CALL是可以直接拨打电话的,如果使用Intent.ACTION_DIAL,只是进入拨号界面。 2.发送短息 - 步骤1:在AndroidMainfest.xml文件中获取发送短信的权限,增加以下内容: ~~~ ~~~ - 步骤2:自定义编辑短信的edit_message.xml: ~~~
';

Cursor记录集游标、ListView和SimpleCursorAdapter、ListView数据动态更新

最后更新于:2022-04-01 19:58:06

Cursor记录集游标、ListView和SimpleCursorAdapter、ListView数据动态更新 Email:chentravelling@163.com 为什么要把**Cursor、ListView、SimpleCursorAdapter**这三个放在一起来讲呢?实在是因为在使用的时候,这三个太紧密相关了。 环境: IDE:Android Studio JDK:1.8 系统:win7 64位 ### 一、Cursor 在android系统中使用SQLite数据库,那么Cursor就会经常使用,使用方式大概如下: ~~~ SQLiteDatabase db; //... String sql = "select * from 表"; Cursor cursor = db.rawQuery(sql,null); ~~~ 即我们查询数据返回得到的是一个封装成Cursor的对象,这就是一个记录集,包含了所有查询得到的记录。那么关于Cursor类简单介绍一下几种关键方法: 首先,我们要使用Cursor记录集游标,就必须知道查询语句中表的字段名、数据类型。 - moveToFirst()游标移动到第一行,一般用这个方法判断查询结果是否为空 > 使用方法: ~~~ if(cursor.moveToFirst()==false) return; ~~~ - moveToLast()游标移动到最后一行 - moveToPosition(int position)游标移动到指定行 - moveToPrevious()游标移动到前一行 - moveToNext()游标移动到下一行,主要用于遍历获取数据 > 使用方法: ~~~ List> list = new ArrayList>(); Map map; while (cursor.moveToNext()) { map = new HashMap(); map.put("name",cursor.getString(cursor.getColumnIndex("name"))); map.put("phone",cursor.getString(cursor.getColumnIndex("phone"))); map.put("_id",cursor.getString(cursor.getColumnIndex("_id"))); list.add(map); } ~~~ - getColumnIndex(String columnName)获取指定列在cursor记录集中的位置 - getString(int position)获取指定位置的数据 - getColumnName(int columnIndex)获取指定列的字段名 - getColumnCount()获得列的总数 - getCount()获取cursor记录集的行数 - close()关闭游标,释放资源 - isBeforeFirst()游标是否指向第一行 - isAfterLast()游标是否指向最后一行 使用方法: 结合isBeforeFirst()、isAfterLast()、moveToNext()三个方法,我们将可以通过for循环来遍历整个记录集 ~~~ for(cursor.moveToFirst();!cursor.isAfterLast();cursor.moveToNext()) { //获取数据,和while()循环一样; } ~~~ - isClosed()是否关闭游标 > 还有一些其他方法吧,暂时没有用过,所以就不罗列了,上面已经把非常常用的方法列举了。 ### 二、ListView和SimpleCursorAdapter 当我们从数据库中查到了数据以后,一般就会用作界面显示,那么ListView就会经常用到。那么我分三部分讲:1)用于显示数据适配器;2)数据库中数据更新后,ListView也更新。首先我们需要三个元素:ListView、adapter即适配器,用于将数据映射到ListView中、数据。 1)常用方法,根据适配器不一样,或者数据不一样,我们要选择的方法也不一样。一般分为三种:**ArrayAdapter、SimpleAdapter和SimpleCursorAdapter**。第一种最简单 ,只能用于显示一行文字,第二种扩展性更好,支持自定义,第三种主要适用于Cursor记录集游标。对于第一种适配器,本人没有上代码测试过,所以就不讲了。 - SimpleAdapter 很好的扩展性,可以显示图片、各种控件等等。 ~~~ public class ShowAddressActivity extends ListActivity { private AddressDAO addressDAO; private SimpleAdapter adapter; private Cursor cursor; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //查数据库返回所有联系人 addressDAO = new AddressDAO(this); cursor = addressDAO.query(); List> list = new ArrayList>(); Map map; //遍历数据 while (cursor.moveToNext()) { map = new HashMap(); map.put("name",cursor.getString(cursor.getColumnIndex("name"))); map.put("phone",cursor.getString(cursor.getColumnIndex("phone"))); map.put("_id",cursor.getString(cursor.getColumnIndex("_id"))); list.add(map); } adapter = new SimpleAdapter(this,list,R.layout.address_list,new String[]{"_id","name","phone"},new int[]{R.id.id,R.id.name,R.id.phone}); setAdapter(adapter); ~~~ 首先我们需要把查询的数据从cursor游标再次封装到有HashMap构成的list中,然后再使用new SimpleAdapter();将数据映射到xml文件中,完成适配:映射规则如下图: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-18_56eb6a34c8e4a.jpg) - SimpleCursorAdapter ~~~ public class ShowAddressActivity extends ListActivity { private AddressDAO addressDAO; private SimpleCursorAdapter adapter; private Cursor cursor; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.show_address); //查数据库返回所有联系人 addressDAO = new AddressDAO(this); cursor = addressDAO.query(); adapter = new SimpleCursorAdapter(this,R.layout.address_list,cursor,new String[]{"_id","name","phone"},new int[]{R.id.id,R.id.name,R.id.phone}); ListView listView = (ListView)findViewById(android.R.id.list); listView.setAdapter(adapter); //.. } ~~~ 其中涉及到了两个xml文件:show_address.xml和address_list.xml,布局代码如下: (1)show_address.xml:包含一个搜索框、一个增加按钮和一个ListView ~~~
';

SQLite数据库之SQLiteOpenHelper与SQLiteDatabase

最后更新于:2022-04-01 19:58:03

SQLite数据库之SQLiteOpenHelper与SQLiteDatabase Email:chentravelling@163.com 在前面一章节:《[SQLite数据库的创建和操作、SQLite数据库可视化](http://blog.csdn.net/chentravelling/article/details/50339433)》中,我已经使用过SQLiteOpenHelper类和SQLiteDatabase类,也正是因为这两个类,使得android系统的数据库服务非常方便。本文重在记录这两个类的区别以及个人理解。 SQLiteOpenHelper类是SQLiteDatabase类的一个帮助类,什么叫帮助类?就是通过SQLiteOpenHelper实现对数据库的创建、更新功能,而由SQLiteDatabase实现对数据的直接操作:增删改查。 环境: IDE:Android Studio JDK:1.8 系统:win7 64位 1、SQLiteOpenHelper类的使用: (1)数据库创建:新建AddressDAO类,继承SQLiteOpenHelper,重写构造函数即可: 创建address_db数据库 ~~~ public class AddressDAO extends SQLiteOpenHelper{ public AddressDAO(Context context) { super(context,"address_db",null,1); } } (2)创建表:重写onCreate()方法即可:创建people表 ~~~ ~~~
@Override
    public void onCreate(SQLiteDatabase db)
    {
        Log.e("onCreate", "create");
        String sql = "CREATE TABLE IF NOT EXISTS people(id integer primary key autoincrement,name text,phone text,workplace text,gender integer);";
        db.execSQL(sql);
    }
~~~
String sql = 。。。这个完全按照标准的SQL语句写即可。当然如果使用SQLiteDatabase封装的方法也可以,只是本人不是很喜欢用。

~~~

(3)数据库升级:重写onUpgrade()即可:
~~~

~~~
 //当数据库升级的时候,Android系统会自动调用onUpgrade方法
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
    {
        String sql = "DROP TABLE IF EXISTS address_db";
        db.execSQL(sql);
        onCreate(db);
    }
~~~

所以这段完整代码使用SQLiteOpenHelper完成了数据库的创建、表的创建、数据库升级,当然都需要有一个关闭数据库的功能。

~~~
public class AddressDAO extends SQLiteOpenHelper{
    private SQLiteDatabase db;
    public AddressDAO(Context context)
    {
        super(context,"address_db",null,1);
    }
    //创建数据库
    @Override
    public void onCreate(SQLiteDatabase db)
    {
        Log.e("onCreate", "create");
        String sql = "CREATE TABLE IF NOT EXISTS people(id integer primary key autoincrement,name text,phone text,workplace text,gender integer);";
        db.execSQL(sql);
    }
    //当数据库升级的时候,Android系统会自动调用onUpgrade方法
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
    {
        String sql = "DROP TABLE IF EXISTS address_db";
        db.execSQL(sql);
        onCreate(db);
    }
    //关闭数据库服务
    public void closeDB(SQLiteDatabase db)
    {
        if(db!=null)
        {
            db.close();
        }
    }
//...
}
~~~

2、在前面我们就已经使用过SQLiteDatabase对象了:db,这个类主要完成对数据的基本操作、执行SQL语句等等首先我们要使用**SQLiteDatabase**对象需要通过SQLiteOpenHelper.getWritableDatabase()或者getReadeableDatabase()方法获取,前者获取写入后者获取读出的SQLiteDatabase对象

比如插入数据

~~~
//插入数据
    public void add()
    {
        String sql = "insert into people values(null,'张亚茹','13716762131','北京','0');";
        //获取SQLiteDatabase对象
        db = this.getWritableDatabase();
        db.execSQL(sql);
    }
~~~

~~~


~~~

~~~
OK,最近几天学习android写BLOG发现好难写,自己理解清楚了或者没理解清楚,要写出来都是一件很痛苦的事情,要写清楚明白,更是痛苦。
~~~

                    
';

SQLite数据库的创建和操作、SQLite数据库可视化

最后更新于:2022-04-01 19:58:01

SQLite数据库的创建和操作 Email:chentravelling@163.com 前天学习了一下界面布局和activity,昨天抽了一会时间捣腾了一下SQLite,总体感觉Android的数据库服务还算方便,这都是两个类的功劳:SQLiteOpenHelper和SQLiteDatabase。关于这两个类,后续再讲。 ### 一、环境 IDE:Android Studio JDK:1.8 系统:win 7 64位 ### 二、设计 我拿了一个简单的例子:people表字段如下
字段类型主键
idTEXTKEY
nameTEXT
workplaceTEXT
phoneTEXT
genderINTEGER
2.1)首先我写了一个people类:peopleBean。为什么要新建一个类呢?首先是对需要传递和保存的信息进行封装,这样个人觉得更加符合面向对象的思想,也使得代码更规范,可读性更高,安全性更高。 ~~~ /** * Created by chen on 2015/12/16. */ public class peopleBean { private String id;//主键 private String name; private String workplace; private String phone; private int gender; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getWorkplace() { return workplace; } public void setWorkplace(String workplace) { this.workplace = workplace; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public int getGender() { return gender; } public void setGender(int gender) { this.gender = gender; } } ~~~ 2.2)新建一个对数据库进行操作的类:AddressDAO,该类继承自SQLiteOpenHelper类,关于SQLiteOpenHelper类的说明将在另一个章节中讨论。 ~~~

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Created by chen on 2015/12/16.
 */
public class AddressDAO extends SQLiteOpenHelper{

    private SQLiteDatabase db;
    public AddressDAO(Context context)
    {
        super(context,"address_db",null,1);
    }
    //创建数据库
    @Override
    public void onCreate(SQLiteDatabase db)
    {
        Log.e("onCreate", "create");
        String sql = "CREATE TABLE IF NOT EXISTS people(id integer primary key autoincrement,name text,phone text,workplace text,gender integer);";
        db.execSQL(sql);
    }
    //当数据库升级的时候,Android系统会自动调用onUpgrade方法
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
    {
        String sql = "DROP TABLE IF EXISTS address_db";
        db.execSQL(sql);
        onCreate(db);
    }
    //关闭数据库服务
    public void closeDB(SQLiteDatabase db)
    {
        if(db!=null)
        {
            db.close();
        }
    }
    //插入数据
    public void add(peopleBean people)
    {
      /*  String name = people.getName();
        String phone = people.getPhone();
        String workplace = people.getWorkplace();
        String gender = people.getGender()==0?"男":"女";*/
        String sql = "insert into people values(null,'"+people.getName()+"','"+people.getPhone()+"','"+people.getWorkplace()+"','"+people.getGender()+"')";
        //String sql = "insert into people values(null,'张亚茹','13716762131','北京','0');";
        //获取SQLiteDatabase对象实例
        db = this.getWritableDatabase();
        db.execSQL(sql);

    }
    //查询数据:返回的是一个Cursor对象
    public Cursor query()
    {
        String sql = "select * from people";
        //获取SQLiteDatabase对象实例
        db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(sql, null);
        return cursor;
    }
}

~~~
 
其中关键的几个地方:

(1)重写**onCreate()**函数,功能:新建数据库,库名:address_db

(2)重写**onUpdate()**函数,数据库升级时,Android系统会自动调用该方法

(3)查询的时候,调用的是**rawQuery()**方法,返回的是**Cursor对象**,该对象是一个数据集合,关于Cursor的操作,后续再讲。

其他的删除和查询暂时还没写。

当然还可以通过调用SQLiteDatabase类中的insert()、delete()、update()、rawQuery()进行数据的增删改查,但是个人喜欢通过执行sql语句来做,比较方便。

### 三、关于SQLite可视化

系统中的数据库在哪里呢?见下图:

打开android device monitor

![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-18_56eb6a3476878.jpg)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-18_56eb6a349c204.jpg)

将数据库表导入和导出:

![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-18_56eb6a34ae300.jpg)

然后就可以利用SQLite可视化工具查看了:SQLite Expert
                    
';

Android Studio项目打包,发布APK

最后更新于:2022-04-01 19:57:59

第一步:Build->Generate Signed APK ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-18_56eb6a3406e4d.jpg) 第二步:Create New Key Store 如果已新建了,直接跳到第四步,选择choose existing key store ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-18_56eb6a341deab.jpg) 第三步:输入必要信息 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-18_56eb6a34343d2.jpg) 第四步:Next ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-18_56eb6a344a090.jpg) 第五步:选择合适路径,Finish ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-18_56eb6a345f685.jpg) ok了,在第五步设置的APK Destiniation Folder路径下去找APK吧。
';

初学安卓,简单布局和activity切换

最后更新于:2022-04-01 19:57:57

【android】初学安卓,简单布局和activity切换 Email:chentravelling@163.com 为什么这个时候学安卓呢?当然是因为选修课啊......说好的机器学习暂时就搁浅了,所以就借了本安卓的书开始学习了。 ### 一、环境 Android Studio+JDK 1.8+win 7  64位 为什么选Android Studio呢?感觉很高大上,配置起来也很easy,只是配置模拟器的时候劳心费神了,而且耗内存太刁。言归正传吧! ### 二、布局 如果学过xml,有过写网页的经验,那么写安卓的界面布局就很easy了。只是,据说android有五大布局: (1)AbsoluteLayout:直接写控件的x坐标和y坐标,很明显这种方式不被推荐,因为Android系统的硬件分辨率不尽相同,使用这种布局方式无法实现自适应。 (2)RelativeLayout:这个方式就是设置控件相对于参照物的相对位置了,一般灵活吧。 (3)LinerLayout:很方便的布局,使用较多,就是将控件横向或者纵向排列,嵌套起来用就更好了。 (4)FrameLayout:每个控件的左上方都与父容器左上方重叠 (5)GridLayout/TableLayout:经典案例就是用户注册。 TableLayout的特点:  Shrinkable : 该列的宽度可以进行收缩,以使表格能够适应父容器的大小 Stretchable : 该列可以进行拉伸,以填满表格中空闲的空间  Collapsed : 该列将会被隐藏  GridLayout的特点:  android:layout_row :  固定显示在第几行。  android:layout_column : 固定显示在第几列,前面几列没控件的话就空着。  android:layout_rowSpan : 跨几行  android:layout_columnSpan:  跨几列   本来想自己用LinerLayout和TableLayout两种布局方式结合起来写一个注册界面的,唉,只可惜对布局这玩意不是特别来电,怎么弄都有点不好看,为了更快地去学习功能上的知识,于是就先把布局这块放下了,用一个比较简单的界面吧。取名:add_address.xml ~~~
';

前言

最后更新于:2022-04-01 19:57:54

> 原文出处:[移动开发](http://blog.csdn.net/column/details/mobile-tec.html) 作者:[chentravelling](http://blog.csdn.net/chentravelling) **本系列文章经作者授权在看云整理发布,未经作者允许,请勿转载!** # 移动开发 > 移动开发技术文档,适合初学者参考。
';