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:
~~~
~~~
- 步骤3:(本人的需求是点击listView中的一个联系人,选择发短信,再跳转到自定义的编辑短信的界面)activity跳转,传递电话号码,在Activity中增加以下代码:
~~~
Intent messageIntent = new Intent(ShowAddressActivity.this,SendMessageActivity.class);
messageIntent.putExtra("phone",phone);
startActivity(messageIntent);
~~~
- 步骤4:在发送短信的activity中获取电话号码,显示在editText中,在发送时重新获取EditText中电话号码,因为电话号码可以手动编辑
~~~
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import java.util.List;
public class SendMessageActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.edit_message);
//将选择的电话号码显示
String phone = this.getIntent().getStringExtra("phone");
final EditText phoneText = (EditText)findViewById(R.id.phoneText);
phoneText.setText(phone);
//获取短信内容
final EditText contentText = (EditText)findViewById(R.id.contentText);
Button sendButton = (Button)findViewById(R.id.sendButton);
sendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//获取电话号码
String phone = phoneText.getText().toString();
String content =contentText.getText().toString();
if("".equals(content)){
new AlertDialog.Builder(SendMessageActivity.this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle("警告")
.setMessage("请输入短信内容")
.setPositiveButton("确定",null)
.show();
return;
}
if("".equals(phone)){
new AlertDialog.Builder(SendMessageActivity.this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle("警告")
.setMessage("请输入联系人号码")
.setPositiveButton("确定",null)
.show();
return;
}
SmsManager smsManager = SmsManager.getDefault();
if(content.length()>70)
{
List contents = smsManager.divideMessage(content);
for(String sms:contents)
{
smsManager.sendTextMessage(phone,null,sms,null,null);
}
}
else
{
smsManager.sendTextMessage(phone,null,content,null,null);
}
Toast.makeText(SendMessageActivity.this, R.string.str_remind_sms_send_finish, Toast.LENGTH_SHORT).show();
}
});
}
}
~~~
备注:R.string.str_remind_sms_send_finish ="发送完成"。
综上就实现了拨打电话和发送短信的功能,安装在手机上测试了一下,还是挺满意,除了界面~需要进一步完善的地方:1)短信功能暂时不支持多人同时发送,其实想想这个功能也是比较容易实现的~2)通话记录和短信记录暂时没有设计数据库进行保存。3)支持发送图片等。
';
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
';
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表字段如下
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类的说明将在另一个章节中讨论。
~~~
';
字段 | 类型 | 主键 |
id | TEXT | KEY |
name | TEXT | |
workplace | TEXT | |
phone | TEXT | |
gender | INTEGER |
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
~~~
~~~
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-03-18_56eb6a33d72e0.jpg)
### 三、Activity
页面跳转是伴随着不同的activity之间切换而跳转的,不知道这说法有没问题,先看看大概的代码吧:
首先:写AddAddressActivity.java
~~~
public class AddAddressActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add_address);
}
}
~~~
关键句子:就是setContentView();那么该activity启动后就会打开一个新的界面,也就是我们设计的add_address.xml。接下来就是启动这个activity了,很easy了,再另一个activity里启动就可以了。
(1)一个activity启动另一个activity
这个时候就需要activity之间通信的桥梁Intent:例如从MainActivity启动AddAddressActivity,在MainActivity.java中写
~~~
Intent intent = new Intent(MainActivity.this, AddAddressActivity.class);
startActivity(intent);
~~~
如果有数据需要传输,那么就需要Bundle运载数据,Bundle在Java里相当于Map~
~~~
Bundle bundle = new Bundle();
bundle.putString("name","嘿嘿");
bundle.putInt("age",22);
~~~
在接受方,AddAddressActivity.java中:
~~~
Bundle bundle = this.getIntent().getExtras();
String name = bundle.getString("name");
int age = bundle.getInt("age");
~~~
暂时会这么一些了,接下来再看看SQLite存储~
';
前言
最后更新于:2022-04-01 19:57:54
> 原文出处:[移动开发](http://blog.csdn.net/column/details/mobile-tec.html)
作者:[chentravelling](http://blog.csdn.net/chentravelling)
**本系列文章经作者授权在看云整理发布,未经作者允许,请勿转载!**
# 移动开发
> 移动开发技术文档,适合初学者参考。
';