Android实例解析——通讯录

Android实例解析——通讯录


包括 listView的用法,活动间数据的传递,已经数据库的操作

   要做一个类似于通讯录这样的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;
		}
	}
	
}


解析都在代码里面,此代码封装性不够到位,而且也很简陋,但基本的核心的东西都有。

制作通讯录的难点在于列表控件的用法已经适配器的连接。

记得在注册文件里面注册另外的两个活动呀!

你可能感兴趣的:(Android)