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

来源:互联网 发布:mac ping ip 端口命令 编辑:程序博客网 时间:2024/06/05 12:44

一、提要

       这个实例整合了前面学过的一些组件(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; @Overridepublic 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");}  @Overridepublic 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() {@Overridepublic void onClick(DialogInterface dialog, int which) {//do somethingmgr.finishThing(tmpThing);}})*/.setNegativeButton("Delete",new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {//do somethingmgr.deleteThing(tmpThing);updateList();}}).setNeutralButton("Cancel",new DialogInterface.OnClickListener() {@Overridepublic 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; //延迟三秒 @Overridepublic 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!");    }    @Overridepublic void onCreate(SQLiteDatabase db) {// TODO Auto-generated method stubLog.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)");  }@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// TODO Auto-generated method stubdb.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

原创粉丝点击