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
- Android入门(7)第一个应用-GTD
- android入门--第一个小应用
- springboot2入门(1-第一个应用)
- 第一个Android应用
- 第一个android应用
- 第一个Android应用
- 第一个Android应用
- android开发入门(一)android studio上的第一个应用GeoQuiz
- Android入门——第一个小应用
- AngularJs轻松入门(一)创建第一个应用
- AngularJs轻松入门(一)创建第一个应用
- Docker入门系列(二):构建第一个docker应用
- Android的第一个应用
- android第一个应用-helloWorld
- 创建第一个android应用
- ExtJS入门-第一个ExtJS应用
- Django入门:第一个Django应用
- Struts2入门的第一个应用
- linux与windows双系统如何修改默认启动方式
- 简单的内存池实现(非线程安全)
- 推荐系统:Slope One 算法
- 如何设置Eclipse中的每一行容纳的代码数
- c语言中realloc()函数解析
- Android入门(7)第一个应用-GTD
- va_start用法
- vs 中大括号之间垂直虚线显示
- IE和FF兼容性问题汇总(JS)
- algebraicSumOfPrime
- UML中对象间的几种关系
- linux开发vim必须掌握的命令总结
- SlidingDrawer的使用与介绍
- ffmpeg