要做一个类似于通讯录这样的APP,应该掌握 listView的用法,活动间数据的传递,已经数据库的操作。有如下几个步骤:
1.设置一个listView,将它与适配器连接,适配器有多种,我这里用的是最基本也是最常用的BaseAdapter,当然也可以选择其他的。
2.然后就是做添加界面与修改界面,这两个界面对应两个活动,其中要有活动间数据的来回传递,
3.最后就是连接数据库了,如果你前面两步写到代码都封装的很好,这一步就是最容易做的。
具体的解析在代码里面,这里直接上代码。
先给出几个布局,依次是 :主界面,listView的内容,已经添加与修改界面(两个界面完全一样,就ID和名字不一样,所以就给出一个界面了)
然后是Java源代码。依次是列表内容类,适配器类,数据库类,修改的类,添加的类,主活动类
package com.example.tonxunlu_13;
public class Data {
public int imagId;
public String content;
public String number;
public Data(){}
public Data(int imagId,String content,String number){
this.imagId=imagId;
this.content=content;
this.number=number;
}
}
package com.example.tonxunlu_13;
import java.util.LinkedList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class MyAdapter extends BaseAdapter{
public Context mcontext;
public LinkedList mData;
public MyAdapter(){}
public MyAdapter(LinkedList mData,Context mcontext){
this.mcontext=mcontext;
this.mData=mData;
}
public void add(Data data){
//向mData中添加一行
if(mData==null){
mData=new LinkedList();
}
mData.add(data);
notifyDataSetChanged();
}
public void remove(int position){
//移除mData的指定行
if(mData!=null){
mData.remove(position);
}
notifyDataSetChanged();
}
public void modify(int position,Data data){
//修改mData的指定行
if(mData!=null){
mData.set(position, data);
}
notifyDataSetChanged();
}
@Override
public int getCount() {
// 获取数据域大小方法
return mData.size();
}
@Override
public Object getItem(int arg0) {
// 返回每个Item的数据
return mData.get(arg0);
}
@Override
public long getItemId(int position) {
// 返回每个Item的ID
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//重绘视图,调用次数是由第一个方法确定的。最后将视图返回。
//position就是位置从0开始,convertView是Spinner,ListView中每一项要显示的view
//通常return 的view也就是convertView
// parent就是父窗体了,也就是Spinner,ListView,GridView了.
ViewHoder viewhoder=null;
if(convertView==null){
convertView=LayoutInflater.from(mcontext).inflate(R.layout.item_list, parent, false);
//inflate(int resource, ViewGroup root, boolean attachToRoot)
//第二个参数指的是加载布局的root
//大概就是说如果后面attachToRoot为true的情况下,这个布局会被解析并加载在root下面,
//如果为false,则会依照root去解析该xml并返回view,但是这个view不会被加载到root里
viewhoder=new ViewHoder();
viewhoder.image=(ImageView)convertView.findViewById(R.id.imag);
viewhoder.text=(TextView)convertView.findViewById(R.id.text_content);
viewhoder.number=(TextView)convertView.findViewById(R.id.number);
convertView.setTag(viewhoder);
//setTag设置一个标签 可以用它来给空间附加一些信息
}else{
viewhoder=(ViewHoder)convertView.getTag();
}
viewhoder.image.setImageResource(mData.get(position).imagId);
viewhoder.text.setText(mData.get(position).content);
viewhoder.number.setText(mData.get(position).number);
return convertView;
}
private class ViewHoder{
ImageView image;
TextView text;
TextView number;
}
}
package com.example.tonxunlu_13;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
public class Dosql extends SQLiteOpenHelper {//数据库建表和更新的抽象类
public Dosql(Context context, String name, CursorFactory factory, int version) {
super(context, name, factory, version);
// TODO Auto-generated constructor stub
}
public void add(SQLiteDatabase db ,String s1,String s2){
//添加操作
db.execSQL("INSERT INTO person(name,number) values(?,?)",new String[]{s1,s2});
}
public void delete(SQLiteDatabase db,String s){
//删除操作
db.execSQL("DELETE FROM person WHERE number = ?", new String[]{s});
}
public void updata(SQLiteDatabase db,String s1,String s2,String s3){
//修改操作
db.execSQL("UPDATE person SET name = ?,number = ? WHERE number = ?",
new String[]{s1,s2,s3});
}
public MyAdapter find(MyAdapter myadapter,SQLiteDatabase db){
//查找操作
Cursor cursor = db.rawQuery("SELECT * FROM person", null);
//cursor 指向数据库中的某项记录的指针
for(;cursor.moveToNext()==true;){
String name = cursor.getString(cursor.getColumnIndex("name"));
String number=cursor.getString(cursor.getColumnIndex("number"));
myadapter.add(new Data(R.drawable.ic,name,number));
}
cursor.close();
return myadapter;
}
@Override
public void onCreate(SQLiteDatabase db) {
//实例化时调用
db.execSQL("CREATE TABLE person(name VARCHAR(20),number VARCHAR(20))");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// 数据库版本号改变是调用
}
}
package com.example.tonxunlu_13;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class SecondActivity extends Activity{
EditText ed1,ed2;
Button button1;
int po;
String str2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.xiugai);
button1=(Button)findViewById(R.id.button1);
ed1=(EditText)findViewById(R.id.name2);
ed2=(EditText)findViewById(R.id.number2);
//接收intent传过来的数据
Intent intent2=getIntent();
Bundle bundle=intent2.getExtras();
String str1=bundle.getString("b1");
str2=bundle.getString("b2");
po=bundle.getInt("b3");
ed1.setText(str1);
ed2.setText(str2);
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String s1=ed1.getText().toString();
String s2=ed2.getText().toString();
//用于活动结束时返回数据
Intent intent3=new Intent();
Bundle bu=new Bundle();
bu.putString("bu1", s1);
bu.putString("bu2", s2);
bu.putInt("bu3", po);
bu.putString("bu0", str2);
intent3.putExtras(bu);
setResult(RESULT_OK, intent3);
//设置返回时的参数,第一个是返回处理结果
finish();
}
});
}
}
package com.example.tonxunlu_13;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class ThirdActivity extends Activity{
EditText ed3,ed4;
Button button2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tianjia);
button2=(Button)findViewById(R.id.button2);
ed3=(EditText)findViewById(R.id.name4);
ed4=(EditText)findViewById(R.id.number4);
button2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String s1=ed3.getText().toString();
String s2=ed4.getText().toString();
//用于活动结束时返回数据
Intent intent=new Intent();
Bundle bu=new Bundle();
bu.putString("bu3", s1);
bu.putString("bu4", s2);
intent.putExtras(bu);
setResult(RESULT_OK, intent);
//设置返回时的参数,第一个是返回处理结果
finish();
}
});
}
}
package com.example.tonxunlu_13;
import java.util.LinkedList;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.view.View.OnClickListener;
import android.view.View.OnCreateContextMenuListener;
public class MainActivity extends Activity {
private ListView list = null;
private Button but=null;
private MyAdapter myadapter = null;
private LinkedList mData = null;
private Context mcontext = null;
private Data data=null;
private Dosql dosql;
private SQLiteDatabase db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);//不在活动中显示标题栏
setContentView(R.layout.activity_main);
mcontext = MainActivity.this;
dosql=new Dosql(mcontext, "my1.db", null, 1);
db=dosql.getWritableDatabase();
//SQLiteDatabase 数据访问或者说操作的类
list = (ListView) findViewById(R.id.list_one);
but=(Button)findViewById(R.id.add);
mData = new LinkedList();
myadapter = new MyAdapter(mData, mcontext);
list.setAdapter(dosql.find(myadapter, db));//向list中添加数据
but.setOnClickListener(new OnClickListener() {
//添加内容的点击事件
@Override
public void onClick(View arg0) {
Intent intent=new Intent(MainActivity.this,ThirdActivity.class);
startActivityForResult(intent, 2);
}
});
list.setOnItemClickListener(new OnItemClickListener() {//单击事件
@Override
public void onItemClick(AdapterView> arg0, View arg1, int arg2, long arg3) {
//第二个参数相当于position
Data data=(Data) myadapter.getItem(arg2);
//调用手机拨号功能
Uri uri=Uri.parse("tel:"+data.number);
Intent intent=new Intent(Intent.ACTION_DIAL,uri);
startActivity(intent);
}
});
list.setOnCreateContextMenuListener(new OnCreateContextMenuListener(){
//长按事件 显示菜单
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
menu.setHeaderTitle("请选择操作");
menu.add(0, 1, 0, "修改");//第二个参数是id第三个是order
menu.add(0, 2, 1, "删除");
}
});
}
public boolean onContextItemSelected ( MenuItem item ) {
switch(item.getItemId()){
case 1:
//修改 事件
ContextMenuInfo info = item.getMenuInfo();
AdapterView.AdapterContextMenuInfo contextMenuInfo = (AdapterContextMenuInfo) info;
int position = contextMenuInfo.position;
//获取长按事件的position
data=(Data)myadapter.getItem(position);
//参数放进bundle中,bundle放入intent中,传递到下一个活动
Intent intent1=new Intent(MainActivity.this,SecondActivity.class);
Bundle bundle=new Bundle();
bundle.putString("b1", data.content);//第一个参数类似于一个标记
bundle.putString("b2", data.number);
bundle.putInt("b3", position);
intent1.putExtras(bundle);
startActivityForResult(intent1, 1);//1是一个请求码用于获取下一个活动返回的数据
break;
case 2:
//删除事件
ContextMenuInfo info1 = item.getMenuInfo();
AdapterView.AdapterContextMenuInfo contextMenuInfo1 = (AdapterContextMenuInfo) info1;
int position1 = contextMenuInfo1.position;
//获取长按事件的position
Data data=(Data) myadapter.getItem(position1);//获取特定行的item
myadapter.remove(position1);
dosql.delete(db, data.number);
Toast.makeText(this, "删除成功", Toast.LENGTH_SHORT).show();
break;
}
return false;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//下一个活动结束时调用,可以获取返回的数据。
switch(requestCode){
case 1:
//从活动2中返回的结果
if(resultCode==RESULT_OK){
Bundle bundle=data.getExtras();
String str1=bundle.getString("bu1");
String str2=bundle.getString("bu2");
int po=bundle.getInt("bu3");
String s=bundle.getString("bu0");
myadapter.modify(po, new Data(R.drawable.ic, str1,str2));
dosql.updata(db, str1, str2, s);
Toast.makeText(this, "修改成功", Toast.LENGTH_SHORT).show();
}
break;
case 2://从活动3中返回的结果
if(resultCode==RESULT_OK){
Bundle bundle=data.getExtras();
String str3=bundle.getString("bu3");
String str4=bundle.getString("bu4");
myadapter.add(new Data(R.drawable.ic,str3,str4));
dosql.add(db, str3, str4);
Toast.makeText(this, "添加成功", Toast.LENGTH_SHORT).show();
}
break;
}
}
}
解析都在代码里面,此代码封装性不够到位,而且也很简陋,但基本的核心的东西都有。
制作通讯录的难点在于列表控件的用法已经适配器的连接。
记得在注册文件里面注册另外的两个活动呀!