现在的位置: 首页 > 综合 > 正文

Android入门(7)第一个应用-GTD

2013年10月08日 ⁄ 综合 ⁄ 共 12320字 ⁄ 字号 评论关闭

一、提要

       这个实例整合了前面学过的一些组件(intent,handler,ListView...),也加入了一些新的东西(dialog,LayoutInflater),最主要的是在应用中整合了Sqlite。

      应用的名字是Getting Things Done的缩写,类似于一个记事本,有拖延症的同学可以试用一下。listview用于显示条目,单击Item可以查看详细,menu中可以添加条目。





二、遇到的问题及解决方法

1.如何修改应用名称及应用图标

修改程序的图标,修改drawable文件夹的i→→c_launcher.png图标,把新的图标改名覆盖就可以了。

如果你要自己的名称,可以修改AndroidManifest.xml的这个节点,application android:icon="@drawable/ic_launcher",不需要加文件扩展名。

即使这么做了,真机调试的时候可能还是会有一些问题,比如图标没办法改变,这个时候就需要在Eclipse中新建一个不同名的项目,然后转移代码(有点小麻烦~_~!)。

2.关于调试方法

调试的时候程序如果出错,一般是查看logcat,看error发生的地方,会提示在程序的第几行,然后去找就可以了。

但有些错误没办法定位,那就把日志输出成txt,然后去google,baidu吧。


3.Couldn't read row 0, col -1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
错误1:请求的字段在数据库的表中不存在,一般是大小写没写对;
错误2:编程的中途改变表的字段,实际字段并没有改变,解决方法是卸载当前版本,再安装调试。

4.android.content.res.Resources.loadXmlResourceParser
在传递string类做参数的地方传了int形变量。

5.android.content.res.Resources$NotFoundException
出现此类异常时,可以根据 Resource ID到资源类R中找相关的资源。比如0x7f030000,对应的是city_item布局文件,就可以将问题缩小到更小的范围。对于这类运行时找不到资源,但资源又确实存在的问题,可能的编译打包时出现问题,没有将该资源加入。可修改一下该资源,让编译器重新编译。 
还有试一下Project ->Clean一下这个项目 也可以的。

三、代码清单

GDT.java 

主Activity,显示列表,响应事件。

package com.example.gtd;

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

import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;

public class GTD extends Activity {

	private DBManager mgr; 
	private ListView myListView;
	private SimpleAdapter myAdapter=null; 
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_gtd);
		myListView=(ListView)findViewById(R.id.listView);
		//初始化DBManager  
		mgr = new DBManager(this);

		myListView.setOnItemClickListener(new OnItemClickListenerImpl());
		//this.add(myListView);
		this.query(myListView);
	}
	@Override  
	protected void onDestroy() {  
		super.onDestroy();  
		//应用的最后一个Activity关闭时应释放DB  
		mgr.closeDB();  
	}  
	public void add(View view) {  
		ArrayList<Thing> things = new ArrayList<Thing>();          
		Thing thing1 = new Thing("Eat","get some food");  
		Thing thing2 = new Thing("Play","play a game");                
		things.add(thing1);  
		things.add(thing2);      
		mgr.add(things);  
		System.out.print("Add done!");
	}  

	public void query(View view) {  
		List<Thing> things = mgr.query();  
		ArrayList<Map<String, String>> mylist = new ArrayList<Map<String, String>>();  
		for (Thing thing : things) {  
			HashMap<String, String> map = new HashMap<String, String>();  
			map.put("title", thing.title);  
			map.put("content", thing.content);  
			System.out.println(thing.title+thing.content);
			mylist.add(map);  
		}  

		myAdapter= new SimpleAdapter(this, //没什么解释    
				mylist,//数据来源     
				R.layout.my_listitem,//ListItem的XML实现    

				//动态数组与ListItem对应的子项            
				new String[] {"title", "content"},     

				//ListItem的XML文件里面的两个TextView ID    
				new int[] {R.id.ItemTitle,R.id.ItemText});   
		//添加并且显示   

		myListView.setAdapter(myAdapter); 
		System.out.println("queryHere");
	}  
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		menu.add(0,1,1,R.string.add);
		menu.add(0,2,2,R.string.about);
		menu.add(0,3,3,R.string.exit);
		//getMenuInflater().inflate(R.menu.activity_gtd, menu);
		return true;
	}
	@Override  
	public boolean onMenuItemSelected(int featureId, MenuItem item) {  
		// TODO Auto-generated method stub  
		if(item.getItemId()==1)showAddDialog();
		if(item.getItemId()==2) new AlertDialog.Builder(this) .setTitle("About") .setMessage("Powerd By Empty.") .show();    
		if(item.getItemId()==3) finish();  
		return super.onMenuItemSelected(featureId, item);  
	}  
	public void updateList()
	{
		query(myListView);
	}

	protected void showAddDialog() {  

		LayoutInflater factory = LayoutInflater.from(this);  
		final View textEntryView = factory.inflate(R.layout.add_dialog, null);  
		final EditText editTextName = (EditText) textEntryView.findViewById(R.id.editTextName);  
		final EditText editTextNumEditText = (EditText)textEntryView.findViewById(R.id.editTextNum);  
		AlertDialog.Builder ad1 = new AlertDialog.Builder(GTD.this);  
		ad1.setTitle("Add a thing:");  
		ad1.setIcon(android.R.drawable.ic_dialog_alert);  
		ad1.setView(textEntryView);  
		ad1.setPositiveButton("No", new DialogInterface.OnClickListener() {  
			public void onClick(DialogInterface dialog, int i) {  
			}  
		});  
		ad1.setNegativeButton("Yes", new DialogInterface.OnClickListener() {  
			public void onClick(DialogInterface dialog, int i) {   
				Thing thing = new Thing(editTextName.getText().toString(),editTextNumEditText.getText().toString());  
				mgr.addOneThing(thing); 
				updateList();
			}  
		});  

		ad1.show();// 显示对话框
	}  
	private class OnItemClickListenerImpl implements OnItemClickListener {  


		@SuppressWarnings("unchecked")  
		@Override  
		public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {   

			//获得选中项的HashMap对象   
			HashMap<String,String> map=(HashMap<String,String>)myListView.getItemAtPosition(arg2);   
			String title=map.get("title");   
			String content=map.get("content"); 
			System.out.println("ItemClick"+title+content);
			final Thing tmpThing=new Thing(title,content);
			//Toast.makeText(getApplicationContext(),    
			//		"你选择了第"+arg2+"个Item,itemTitle的值是:"+title+"itemContent的值是:"+content,   
				//	Toast.LENGTH_SHORT).show();   

			
			new AlertDialog.Builder(GTD.this)
			.setTitle(tmpThing.title+"")//设置标题
			.setMessage(tmpThing.content)//设置提示消息
			/*
			.setPositiveButton("Finished",new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					//do something
					mgr.finishThing(tmpThing);
				}
			})*/
			.setNegativeButton("Delete",new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					//do something
					mgr.deleteThing(tmpThing);
					updateList();
				}
			})
			.setNeutralButton("Cancel",new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					//do something
				}
			})
			.setCancelable(false)//设置按返回键是否响应返回,这是是不响应
			.show();//显示
		} 
	}
}

SplashScreen.java

最简单的闪屏类,这个就不多解释了,注意handler的用法。

package com.example.gtd;


import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ImageView;
import android.widget.TextView;


public class SplashScreen extends Activity {
	private ImageView logoView;
	private TextView rightView;
	private final int SPLASH_DISPLAY_LENGHT = 3000; //延迟三秒 


	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.splash_screen);
		logoView=(ImageView)findViewById(R.id.imageView1);
		rightView=(TextView)findViewById(R.id.textView1);
		//logoView.setAlpha(alpha);
		new Handler().postDelayed(new Runnable(){ 


	         @Override 
	         public void run() { 
	             Intent mainIntent = new Intent(SplashScreen.this, GTD.class); 
	             SplashScreen.this.startActivity(mainIntent); 
	             SplashScreen.this.finish(); 
	         } 
	            
	        }, SPLASH_DISPLAY_LENGHT); 
		//updateThread.run();
	}
}

DBHelper.java

继承SQLiteOpenHelper,负责创建数据库,打开数据库。

package com.example.gtd;

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

public class DBHelper extends SQLiteOpenHelper {

	private static final String DATABASE_NAME = "test.db";  
    private static final int DATABASE_VERSION = 1;  
      
    public DBHelper(Context context) {  
        //CursorFactory设置为null,使用默认值  
        super(context, DATABASE_NAME, null, DATABASE_VERSION);  
        System.out.println("New DBHelper!");
    }  
  
	@Override
	public void onCreate(SQLiteDatabase db) {
		// TODO Auto-generated method stub
		Log.d("DB", "New DB!");
		System.out.println("New DB!");
		db.execSQL("CREATE TABLE IF NOT EXISTS thing" +  
                "(_id INTEGER PRIMARY KEY AUTOINCREMENT, title VARCHAR, detail VARCHAR,isdone INTEGER)");  

	}


	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// TODO Auto-generated method stub
		db.execSQL("ALTER TABLE thing ADD COLUMN other STRING");  
	}

}

DBManager.java

对数据库的操作进行了封装。

package com.example.gtd;

import java.util.ArrayList;  
import java.util.List;  
  
import android.content.ContentValues;  
import android.content.Context;  
import android.database.Cursor;  
import android.database.sqlite.SQLiteDatabase;  
  
public class DBManager {  
    private DBHelper helper;  
    private SQLiteDatabase db;  
      
    public DBManager(Context context) {  
        helper = new DBHelper(context); 
        System.out.println("New DBManager!");
        //因为getWritableDatabase内部调用了mContext.openOrCreateDatabase(mName, 0, mFactory);  
        //所以要确保context已初始化,我们可以把实例化DBManager的步骤放在Activity的onCreate里  
        db = helper.getWritableDatabase();  
    }  
      

    public void add(List<Thing> things) {  
        db.beginTransaction();  //开始事务  
        try {  
            for (Thing thing: things) {  
                db.execSQL("INSERT INTO thing VALUES(null, ?, ?, ?)", new Object[]{thing.title, thing.content, 0});  
            }  
            db.setTransactionSuccessful();  //设置事务成功完成  
        } finally {  
            db.endTransaction();    //结束事务  
        }  
    }  
    public void addOneThing(Thing thing)
    {
    	db.execSQL("INSERT INTO thing VALUES(null, ?, ?, ?)", new Object[]{thing.title, thing.content, 0});   	
    }
      
  
    public void updateAge(Thing thing) {  
        ContentValues cv = new ContentValues();  
        cv.put("isdone", thing.isdone);  
        db.update("thing", cv, "title = ?", new String[]{thing.title});  
    }  
      
    public void finishThing(Thing thing)
    {
    	ContentValues cv = new ContentValues();  
        cv.put("isdone", 1);  
        db.update("thing", cv, "title = ?", new String[]{thing.title});

    }

    public void deleteThing(Thing thing) {  
        db.delete("thing", "title= ?", new String[]{thing.title});  
        System.out.print("delete thing");
    }  
      

    public List<Thing> query() {  
        ArrayList<Thing> things = new ArrayList<Thing>();  
        Cursor c = queryTheCursor(); 
        if(c.moveToLast())
        while (!c.isBeforeFirst()) {  
        	Thing thing = new Thing();  
        	thing._id = c.getInt(c.getColumnIndex("_id"));  
        	thing.title = c.getString(c.getColumnIndex("title"));  
        	//System.out.println("c.getColumnIndex(detail)"+c.getColumnIndex("detail"));
        	thing.content = c.getString(c.getColumnIndex("detail")); 
            thing.isdone = c.getInt(c.getColumnIndex("isdone"));  
            things.add(thing);  
            c.moveToPrevious();
        }  
        c.close();  
        return things;  
    }  

    public Cursor queryTheCursor() {  
        Cursor c = db.rawQuery("SELECT * FROM thing", null);  
        return c;  
    }  
      
    /** 
     * close database 
     */  
    public void closeDB() {  
        db.close();  
    }  
}  

 Thing.java

待办事类,定义了成员和构造函数。

package com.example.gtd;

public class Thing {
	public int _id;  
    public String title;  
     
    public String content;  
    public int isdone; 
      
    public Thing() {  
    }  
      
    public Thing(String title,String content) {  
        this.title = title;  
        this.content = content;   
    }  

}

下面是布局文件

splash_screen.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:weightSum="1"
    android:background="#FFFFFF">
        <ImageView 
            android:layout_height="wrap_content" 
            android:layout_width="match_parent" 
            android:src="@drawable/logo" 
            android:id="@+id/imageView1" 
            android:layout_alignParentTop="true" 
            android:layout_alignParentLeft="true" 
            android:layout_marginTop="150dp">
        </ImageView>
        
        <TextView android:text="@string/copyright" 
            android:layout_height="wrap_content" 
            android:textAppearance="?android:attr/textAppearanceSmall" 
            android:layout_width="wrap_content" 
            android:id="@+id/textView1" 
            android:layout_alignParentBottom="true" 
            android:layout_centerHorizontal="true" 
            android:layout_marginBottom="14dp">
        </TextView>
</RelativeLayout>

activity_gtd.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ListView  
        android:id="@+id/listView"  
        android:layout_width="fill_parent"  
        android:layout_height="wrap_content"/>  

</RelativeLayout>

add_dialog.xml

<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent"  
    android:orientation="vertical" >  
  
    <TextView  
        android:id="@+id/textView1"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:text="Title" />  
  
    <EditText  
        android:id="@+id/editTextName"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content" >  
  
        <requestFocus />  
    </EditText>  
  
    <TextView  
        android:id="@+id/textView2"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:text="Content" />  
  
    <EditText  
        android:id="@+id/editTextNum"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content" />  
  
</LinearLayout>  

my_listitem.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/myListItem"
    android:layout_width="fill_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="3dip"
    android:paddingLeft="10dip" >

    <TextView
        android:id="@+id/ItemTitle"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="30dip" >
    </TextView>

    <TextView
        android:id="@+id/ItemText"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >
    </TextView>

</LinearLayout>

参考资料:

常用的dialog:http://blog.csdn.net/chenlei1889/article/details/6267406

Android中SQLite应用详解:http://blog.csdn.net/liuhe688/article/details/6715983

Android 实例-个人理财工具:http://blog.csdn.net/untosil/article/details/3267086

抱歉!评论已关闭.