键字:android sdk1.0 sqlite intent ExpandableListActivity SimpleCursorTreeAdapter cursor custom dialog
ColaBox 登记收支记录终于进入了复杂阶段了.这个界面我也是查找了很多资料以及打开android的源代码看了后才完成了,现在想来Google的开源真是明智的啊.
从前面的登录页面跳转进入添加账单页面.这个页面主要是用来登记收支记录的.
说白了就是往数据库录入明细.
表结构就是db.execSQL("CREATE TABLE bills ("
+ "_ID INTEGER PRIMARY KEY," //id
+ "fee integer," //费用
+"acctitemid integer," //账目类型
+ "userid integer," //使用者
+ "sdate TEXT," //日期
+ "stime TEXT," //时间
+ "desc TEXT" //备注
+ ");");
可以看到主要是录入这些数据.首先是布置界面,我目前想到的用个tablelayout来布局
最后布局就是如下图这样
图1
在这儿我首先需要设置账目,前面我们已经初始化过账目的数据.
账目应该是一个ExpandableListActivity 2层的结构.需要从数据库里面读取.我在账目后面放了一个editview 只读没有光标的.也就是在这儿不可录入,在该editview的onclick事件里面我们打开账目选择界面.如下图
图2 账目选择
在这个界面中点击子节点就返回前面界面,把选择的账目传递过去.在这有个问题,如果用户需要录入的账目没有怎么办?
所以我这没有用dialog方式而是用了ExpandableListActivity 在这个界面中如果长点某个子节点就弹出管理账目菜单,
来维护账目,如下图所示:
图3账目选择菜单示意 图4 编辑账目
上面这些流程说起来很简单,可是当我用andriod编写时,遇到了很多问题,不过一个个都被我解决了,这正是编程的快乐所在.
关于ExpandableListActivity 大家可以参考android 里面apidemos 里面ExpandableList1,ExpandableList2,ExpandableList3
这里面对熟悉这个ui还是很有帮助的. 在ExpandableList2 里面就是从数据库进行读取的例子. 当然android里面那个我是没太
看明白因为他引用了import android.provider.Contacts.People; 联系人部分的框架,而我目前对数据库的操作和他不一样,我都是直接
sql访问.
但是你只要搞定2个cursor就ok了. Cursor groupCursor childCursor 其他都由SimpleCursorTreeAdapter帮你实现了.
下面我们来看看如何使用SimpleCursorTreeAdapter
-
-
-
Cursor groupCursor = billdb.getParentNode();
-
-
-
mGroupIdColumnIndex = groupCursor.getColumnIndexOrThrow(
"_ID"
);
-
-
mAdapter =
new
MyExpandableListAdapter(groupCursor,
this
, android.R.layout.simple_expandable_list_item_1,
-
android.R.layout.simple_expandable_list_item_1,
-
new
String[] {
"NAME"
},
-
new
int
[] { android.R.id.text1 },
-
new
String[] {
"NAME"
},
-
new
int
[] { android.R.id.text1 });
-
setListAdapter(mAdapter);
-
-
-
-
-
-
public
class
MyExpandableListAdapter extends SimpleCursorTreeAdapter {
-
-
public
MyExpandableListAdapter(Cursor cursor, Context context,
-
int
groupLayout,
int
childLayout, String[] groupFrom,
-
int
[] groupTo, String[] childrenFrom,
int
[] childrenTo)
-
{
-
super(context, cursor, groupLayout, groupFrom, groupTo,
-
childLayout, childrenFrom, childrenTo);
-
}
-
-
protected Cursor getChildrenCursor(Cursor groupCursor) {
-
String pid = groupCursor.getLong(mGroupIdColumnIndex) + "";
// Log.v("cola","pid="+pid);
return billdb.getChildenNode(pid);
-
}
-
}
-
//我们看看Billdbhelper里面的cursor
-
public Cursor getParentNode(){
return db.query("acctitem", new String[]{"_id", "name" }, "pid is null", null, null, null, "pid,_id");
}
public Cursor getChildenNode(String pid){
Log.v("cola","run getchildenNode");
return db.query("acctitem", new String[]{"_id", "name" }, "pid="+pid, null, null, null, "_id");
-
}
-
只要这几步一个2级的tree list就可以出现了.
-
上面其实才是刚开始,后面我们需要使用一个自定义的Dialog 类似于一个inputBox 因为我们新增账目是需要输入账目的名称.
就是上面图4表现的.
虽然alertDialog提供了很多方法,可以选择list,treelist,radio, 可惜就是不能录入text.
这里我参考了api demos 里面的 DateWidgets1.java 和源代码里面DatePickerDialog.java .
我们可以从alertdialog 继承.然后添加一个Editview 最后把数据返回出来.只要把上面我说的2个java看清楚了后处理起来就简单了.
主要是一个回调函数的用法.下面看代码
-
//
-
public
class
Dialog_edit extends AlertDialog implements OnClickListener {
-
private
String text =
""
;
-
private
EditText edit;
-
private
OnDateSetListener mCallback; //定义回调函数
-
-
private
LinearLayout layout;
-
-
public
interface
OnDateSetListener { //回调接口
-
-
void
onDateSet(String text);
-
}
-
-
protected
Dialog_edit(Context context, String title, String value,
-
OnDateSetListener Callback) {
-
super(context);
-
mCallback = Callback;
-
TextView label =
new
TextView(context);
-
label.setText(
"hint"
);
-
-
edit =
new
EditText(context);
-
edit.setText(value);
-
layout =
new
LinearLayout(context);
-
layout.setOrientation(LinearLayout.VERTICAL);
-
-
-
-
LinearLayout.LayoutParams param2 =
new
LinearLayout.LayoutParams(200,
-
50);
-
layout.addView(edit, param2);
-
//添加edit
-
setView(layout);
-
setTitle(title);
-
setButton(
"确定"
,
this
);
-
setButton2(
"取消"
, (OnClickListener)
null
);
-
-
}
-
-
public
void
onClick(DialogInterface dialog,
int
which) {
-
-
text = edit.getText().toString();
-
Log.v(
"cola"
,
"U click text="
+ text);
-
if
(mCallback !=
null
)
-
mCallback.onDateSet(text); //使用回调返回录入的数据
-
-
}
-
-
}
-
这样我们就完成了自定义的dialog 我们可以使用它来新增和编辑账目. 对于账目的增删改就是sql的事情了
在这我又遇到一个问题就是我新增一个账目后如何来刷新界面,从而反映账目修改后的变化
在这我开始以为只要使用
getExpandableListView().invalidate(); 就可以了,
因为我之前在ExpandableList1.java例子里面,使用它可以刷新界面.
在那个例子里面我修改了数组后调用该方法,界面就刷新了,而在这SimpleCursorTreeAdapter就行不通了,我想
应该只要刷新cursor应该就可以了,后来找到了notifyDataSetChanged 呵呵,果然可以了. 这样账目的录入和管理就搞定了.
下面给出目前最新的代码.
首先是账目管理
-
-
-
package com.cola.ui;
-
-
import android.app.AlertDialog;
-
import android.app.ExpandableListActivity;
-
import android.content.Context;
-
import android.content.DialogInterface;
-
import android.content.Intent;
-
import android.database.Cursor;
-
import android.os.Bundle;
-
import android.provider.Contacts.People;
-
import android.util.Log;
-
import android.view.ContextMenu;
-
import android.view.MenuItem;
-
import android.view.View;
-
import android.view.ContextMenu.ContextMenuInfo;
-
import android.widget.ExpandableListAdapter;
-
import android.widget.ExpandableListView;
-
import android.widget.SimpleCursorTreeAdapter;
-
import android.widget.TextView;
-
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
-
-
-
-
-
public
class
Frm_Editacctitem extends ExpandableListActivity {
-
private
int
mGroupIdColumnIndex;
-
-
private
String mPhoneNumberProjection[] =
new
String[] { People.Phones._ID,
-
People.Phones.NUMBER };
-
-
private
ExpandableListAdapter mAdapter;
-
-
BilldbHelper billdb;
-
-
Dialog_edit newdialog;
-
-
-
-
-
private
ExpandableListContextMenuInfo info;
-
-
-
-
@Override
-
public
void
onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
-
setTitle(
"ColaBox-选择账目"
);
-
billdb =
new
BilldbHelper(
this
);
-
-
-
Cursor groupCursor = billdb.getParentNode();
-
-
-
mGroupIdColumnIndex = groupCursor.getColumnIndexOrThrow(
"_ID"
);
-
-
mAdapter =
new
MyExpandableListAdapter(groupCursor,
this
,
-
android.R.layout.simple_expandable_list_item_1,
-
android.R.layout.simple_expandable_list_item_1,
-
new
String[] {
"NAME"
},
-
new
int
[] { android.R.id.text1 },
new
String[] {
"NAME"
},
-
new
int
[] { android.R.id.text1 });
-
setListAdapter(mAdapter);
-
registerForContextMenu(getExpandableListView());
-
-
}
-
-
@Override
-
public
boolean onChildClick(ExpandableListView parent, View v,
int
groupPosition,
int
childPosition,
long
id)
-
{
-
Bundle bundle =
new
Bundle();
-
bundle.putString(
"DataKey"
, ((TextView)v).getText().toString());
-
Intent mIntent =
new
Intent();
-
mIntent.putExtras(bundle);
-
setResult(RESULT_OK, mIntent);
-
billdb.close();
-
finish();
-
-
return
true
;
-
}
-
@Override
-
public
void
onCreateContextMenu(ContextMenu menu, View v,
-
ContextMenuInfo menuInfo) {
-
super.onCreateOptionsMenu(menu);
-
if
(ExpandableListView
-
.getPackedPositionType(((ExpandableListContextMenuInfo) menuInfo).packedPosition) == 1) {
-
Log.v(
"cola"
,
"run menu"
);
-
menu.setHeaderTitle(
"菜单"
);
-
menu.add(0, 1, 0,
"新 增"
);
-
menu.add(0, 2, 0,
"删 除"
);
-
menu.add(0, 3, 0,
"编 辑"
);
-
}
-
-
}
-
-
@Override
-
public
boolean onContextItemSelected(MenuItem item) {
-
info = (ExpandableListContextMenuInfo) item.getMenuInfo();
-
-
if
(item.getItemId() == 1) {
-
-
newdialog =
new
Dialog_edit(
this
,
"请输入新增账目的名称"
,
""
,
-
mDialogClick_new);
-
newdialog.show();
-
}
else
if
(item.getItemId() == 2) {
-
new
AlertDialog.Builder(
this
).setTitle(
"提示"
).setMessage(
"确定要删除'"
+((TextView)info.targetView).getText().toString()+
"'这个账目吗?"
)
-
.setIcon(R.drawable.quit).setPositiveButton(
"确定"
,
-
new
DialogInterface.OnClickListener() {
-
public
void
onClick(DialogInterface dialog,
-
int
whichButton) {
-
billdb.Acctitem_delitem((
int
)info.id);
-
updatedisplay();
-
}
-
}).setNegativeButton(
"取消"
,
-
new
DialogInterface.OnClickListener() {
-
public
void
onClick(DialogInterface dialog,
-
int
whichButton) {
-
-
}
-
}).show();
-
-
}
else
if
(item.getItemId() == 3) {
-
newdialog =
new
Dialog_edit(
this
,
"请修改账目名称"
,
-
((TextView) info.targetView).getText().toString(),
-
mDialogClick_edit);
-
newdialog.show();
-
}
-
-
return
false
;
-
}
-
-
private
Dialog_edit.OnDateSetListener mDialogClick_new =
new
Dialog_edit.OnDateSetListener() {
-
public
void
onDateSet(String text) {
-
Log.v(
"cola"
,
"new acctitem"
);
-
billdb.Acctitem_newitem(text,ExpandableListView.getPackedPositionGroup(info.packedPosition));
-
updatedisplay();
-
}
-
-
};
-
-
private
Dialog_edit.OnDateSetListener mDialogClick_edit =
new
Dialog_edit.OnDateSetListener() {
-
public
void
onDateSet(String text) {
-
billdb.Acctitem_edititem(text,(
int
)info.id);
-
updatedisplay();
-
}
-
-
};
-
-
private
void
updatedisplay(){
-
Log.v(
"cola"
,
"update display"
);
-
((MyExpandableListAdapter)mAdapter).notifyDataSetChanged();
-
-
}
-
-
public
class
MyExpandableListAdapter extends SimpleCursorTreeAdapter {
-
-
public
MyExpandableListAdapter(Cursor cursor, Context context,
-
int
groupLayout,
int
childLayout, String[] groupFrom,
-
int
[] groupTo, String[] childrenFrom,
int
[] childrenTo) {
-
super(context, cursor, groupLayout, groupFrom, groupTo,
-
childLayout, childrenFrom, childrenTo);
-
}
-
-
@Override
-
protected
Cursor getChildrenCursor(Cursor groupCursor) {
-
-
String pid = groupCursor.getLong(mGroupIdColumnIndex) +
""
;
-
-
return
billdb.getChildenNode(pid);
-
-
}
-
-
@Override
-
public
long
getGroupId(
int
groupPosition) {
-
-
Cursor groupCursor = (Cursor) getGroup(groupPosition);
-
return
groupCursor.getLong(mGroupIdColumnIndex);
-
}
-
-
@Override
-
public
long
getChildId(
int
groupPosition,
int
childPosition) {
-
-
-
Cursor childCursor = (Cursor) getChild(groupPosition, childPosition);
-
return
childCursor.getLong(0);
-
}
-
-
}
-
}
-
自定义对话框
-
-
package com.cola.ui;
-
-
import android.app.AlertDialog;
-
import android.content.Context;
-
import android.content.DialogInterface;
-
import android.content.DialogInterface.OnClickListener;
-
import android.util.Log;
-
import android.widget.EditText;
-
import android.widget.LinearLayout;
-
import android.widget.TextView;
-
-
-
public
class
Dialog_edit extends AlertDialog implements OnClickListener {
-
private
String text =
""
;
-
private
EditText edit;
-
private
OnDateSetListener mCallback;
-
-
private
LinearLayout layout;
-
-
public
interface
OnDateSetListener {
-
-
void
onDateSet(String text);
-
}
-
-
protected
Dialog_edit(Context context, String title, String value,
-
OnDateSetListener Callback) {
-
super(context);
-
mCallback = Callback;
-
TextView label =
new
TextView(context);
-
label.setText(
"hint"
);
-
-
edit =
new
EditText(context);
-
edit.setText(value);
-
layout =
new
LinearLayout(context);
-
layout.setOrientation(LinearLayout.VERTICAL);
-
-
-
-
LinearLayout.LayoutParams param2 =
new
LinearLayout.LayoutParams(200,
-
50);
-
layout.addView(edit, param2);
-
setView(layout);
-
setTitle(title);
-
setButton(
"确定"
,
this
);
-
setButton2(
"取消"
, (OnClickListener)
null
);
-
-
}
-
-
public
void
onClick(DialogInterface dialog,
int
which) {
-
-
text = edit.getText().toString();
-
Log.v(
"cola"
,
"U click text="
+ text);
-
if
(mCallback !=
null
)
-
mCallback.onDateSet(text);
-
-
}
-
-
}
-
数据库管理代码
-
package com.cola.ui;
-
-
import android.content.Context;
-
import android.database.Cursor;
-
import android.database.sqlite.SQLiteDatabase;
-
import android.util.Log;
-
-
-
-
-
-
public
class
BilldbHelper {
-
-
private
static
final String TAG =
"Cola_BilldbHelper"
;
-
-
private
static
final String DATABASE_NAME =
"cola.db"
;
-
-
SQLiteDatabase db;
-
Context context;
-
-
BilldbHelper(Context _context) {
-
context=_context;
-
db=context.openOrCreateDatabase(DATABASE_NAME, 0,
null
);
-
Log.v(TAG,
"db path="
+db.getPath());
-
}
-
-
public
void
CreateTable_acctitem() {
-
try
{
-
db.execSQL(
"CREATE TABLE acctitem ("
-
+
"_ID INTEGER PRIMARY KEY,"
-
+
"PID integer,"
-
+
"NAME TEXT"
-
+
");"
);
-
Log.v(
"cola"
,
"Create Table acctitem ok"
);
-
}
catch
(Exception e){
-
Log.v(
"cola"
,
"Create Table acctitem err,table exists."
);
-
}
-
}
-
-
public
void
CreateTable_bills() {
-
try
{
-
db.execSQL(
"CREATE TABLE bills ("
-
+
"_ID INTEGER PRIMARY KEY,"
-
+
" acctitemid integer,"
-
+
"fee integer,"
-
+
"userid integer,"
-
+
"sdate TEXT,"
-
+
"stime TEXT,"
-
+
"desc TEXT"
-
+
");"
);
-
-
Log.v(
"cola"
,
"Create Table acctitem ok"
);
-
}
catch
(Exception e){
-
Log.v(
"cola"
,
"Create Table acctitem err,table exists."
);
-
}
-
}
-
-
public
void
CreateTable_colaconfig() {
-
try
{
-
db.execSQL(
"CREATE TABLE colaconfig ("
-
+
"_ID INTEGER PRIMARY KEY,"
-
+
"NAME TEXT"
-
+
");"
);
-
Log.v(
"cola"
,
"Create Table colaconfig ok"
);
-
}
catch
(Exception e){
-
Log.v(
"cola"
,
"Create Table acctitem err,table exists."
);
-
}
-
}
-
-
public
void
InitAcctitem() {
-
try
{
-
-
db.execSQL(
"insert into acctitem values (1,null,'收入')"
);
-
db.execSQL(
"insert into acctitem values (2,1,'工资')"
);
-
db.execSQL(
"insert into acctitem values (9998,1,'其他')"
);
-
db.execSQL(
"insert into acctitem values (0,null,'支出')"
);
-
db.execSQL(
"insert into acctitem values (3,0,'生活用品')"
);
-
db.execSQL(
"insert into acctitem values (4,0,'水电煤气费')"
);
-
db.execSQL(
"insert into acctitem values (5,0,'汽油费')"
);
-
db.execSQL(
"insert into acctitem values (9999,0,'其他')"
);
-
-
-
Log.v(
"cola"
,
"insert into ok"
);
-
}
catch
(Exception e)
-
{
-
Log.v(
"cola"
,
"init acctitem e="
+e.getMessage());
-
}
-
-
}
-
public
void
Acctitem_newitem(String text,
int
type){
-
-
Cursor c =db.query(
"acctitem"
,
new
String[]{
"max(_id)+1"
},
"_id is not null and _id<9998"
,
null
,
null
,
null
,
null
);
-
c.moveToFirst();
-
int
maxid=c.getInt(0);
-
String sql=
"insert into acctitem values ("
+maxid+
","
+type+
",'"
+text+
"')"
;
-
db.execSQL(sql);
-
Log.v(
"cola"
,
"newitem ok text="
+text+
" id="
+type+
" sql="
+sql);
-
-
}
-
-
public
void
Acctitem_edititem(String text,
int
id){
-
db.execSQL(
"update acctitem set name='"
+text+
"' where _id="
+id);
-
Log.v(
"cola"
,
"edititem ok text="
+text+
" id="
+id);
-
}
-
-
public
void
Acctitem_delitem(
int
id){
-
-
db.execSQL(
"delete from acctitem where _id="
+id);
-
Log.v(
"cola"
,
"delitem ok id="
+id);
-
}
-
-
public
void
QueryTable_acctitem(){
-
-
}
-
-
public
void
FirstStart(){
-
try
{
-
String col[] = {
"type"
,
"name"
};
-
Cursor c =db.query(
"sqlite_master"
, col,
"name='colaconfig'"
,
null
,
null
,
null
,
null
);
-
int
n=c.getCount();
-
if
(c.getCount()==0){
-
CreateTable_acctitem();
-
CreateTable_colaconfig();
-
CreateTable_bills();
-
InitAcctitem();
-
}
-
-
Log.v(
"cola"
,
"c.getCount="
+n+
""
);
-
-
-
}
catch
(Exception e){
-
Log.v(
"cola"
,
"e="
+e.getMessage());
-
}
-
-
-
}
-
-
-
public
void
close(){
-
db.close();
-
}
-
-
public
Cursor getParentNode(){
-
return
db.query(
"acctitem"
,
new
String[]{
"_id"
,
"name"
},
"pid is null"
,
null
,
null
,
null
,
"pid,_id"
);
-
-
}
-
-
public
Cursor getChildenNode(String pid){
-
Log.v(
"cola"
,
"run getchildenNode"
);
-
return
db.query(
"acctitem"
,
new
String[]{
"_id"
,
"name"
},
"pid="
+pid,
null
,
null
,
null
,
"_id"
);
-
-
}
-
-
}
这段代码搞了2个通宵.昨天晚上又被ubuntu 8.04和vmware 5.5 折腾死.我的周末就这样泡汤了.
##############################################
2008-11-23 01:43 湖北武汉
##############################################
备注:
今天看了下android的dialog例子,发现android 带了可输入文字的dialog例子,呵呵,实际上和我自定义的方法就是类似的.
我之前还是demo看的太少了,也就不会走弯路了.
具体可以看AlertDialogSamples.java
分享到:
相关推荐
总之,实现Android个人理财工具的账单页面涉及数据库设计、界面布局和数据适配器的使用。通过精心设计和代码实现,用户可以方便地添加和管理他们的财务记录,从而提高个人财务管理的效率。在后续的部分,开发者可能...
在这个“Android应用小实例--炫酷计时器”中,我们将深入探讨如何在Android应用中创建并定制一个功能丰富的计时器。 计时器组件在Android SDK中是`android.widget.Chronometer`类,它类似于一个倒计时定时器,但...
### Android实例开发完全手册知识点概览 #### 第1章 正式开发前的准备 - **1.1 Windows下安装Java环境JDK** - **实例说明:** 本节介绍如何在Windows操作系统上安装Java Development Kit (JDK),这是进行Android...
总结,个人理财通(Android)是Android平台上的一款实用理财工具,它结合了Android系统的特性和财务管理的需求,提供了全面的个人财务解决方案。虽然缺乏官方文档,但对于用户来说,它的直观界面和实用功能足以满足...
在这个"Fragment实例-Android Studio项目"中,我们可以深入理解Fragment的使用方法以及如何在不同设备上适配。 1. **Fragment基本概念** Fragment是Activity的一部分,可以包含UI组件和业务逻辑。它们可以在一个...
Android串口开发(android-serialport-api开发)工程实例。SerialPortUtil里面有我常用的转换工具(16进制字符串转二进制字符串并补位、二进制字符串转16进制字符串并补位)
在Android开发领域,掌握实例源码是提升技能和理解系统工作原理的重要途径。"android 实例源码 集合" 提供了多种Android应用程序的源代码,这为我们提供了宝贵的参考资源,帮助开发者深入理解Android应用开发的各种...
4. 配置AVD(Android Virtual Device):通过AVD Manager创建模拟器实例,选择设备配置、系统镜像和硬件选项,以便在Windows上运行Android应用。 三、使用Android SDK进行开发 1. 创建项目:使用Android Studio,...
在Android应用开发中,创建一个个人理财工具的关键部分之一是展示用户的收支明细。在这个场景下,开发者需要从SQLite数据库中提取数据并将其呈现给用户。本文将深入探讨如何实现这一功能,特别是如何利用ListView和...
在Android开发中,构建一个类似京东商品的三级分类系统是一项常见的任务,这涉及到用户界面设计、数据结构管理和触摸事件处理等多个方面。在这个简单的实例中,我们将探讨如何在Android平台上实现这样的功能,不涉及...
《Android-Universal-Image-Loader:高效加载与缓存图片的解决方案》 在移动开发领域,尤其是Android平台,图片加载和缓存是一个重要的课题。Android-Universal-Image-Loader(简称UIL)是一款强大的开源库,专门...
Android ADT SDK(Android Developer Tools Software Development Kit)是Android开发者用于构建、调试和发布Android应用程序的重要工具集。这个压缩包包含了版本18和19的SDK,分别对应Android 4.3 (API Level 18) ...
在Android应用开发中,Fragment是Android SDK中的一个重要组件,它被设计用来支持多屏幕适配和增强用户界面的模块化。Fragment允许开发者将应用程序的功能或UI部分分解为独立的、可重用的组件,这些组件可以在不同的...
为了使用这个库,开发者需要将其添加到项目的依赖库中,如果是使用Gradle构建系统,可以在`build.gradle`文件中添加依赖。然后,就可以在代码中创建`AsyncHttpClient`实例,配置请求参数,并注册回调来处理请求结果...
本文将深入探讨如何在Android项目中实现友盟(Umeng)的第三方登录与分享功能,结合提供的完整实例源码,帮助开发者更好地理解和运用这一技术。 首先,让我们了解什么是友盟。友盟是阿里巴巴移动事业群旗下的开放...
《Android实例开发完全手册》是一本深度探讨Android应用开发的实战型书籍,旨在通过丰富的实例帮助读者掌握Android开发的核心技术和实践技巧。这本书涵盖了从基础到高级的各个方面,为开发者提供了全面的学习路径。 ...
这个是Android NDK上调用第三方的动态库的实例,而且代码简单容易理解,非常适合新手学习参考,因为网上很多资源是C2C(Copy to Copy)的,有些还不能运行,容易误导新手,并且还要设置积分,我免积分提供给网友下载...
在Android平台上,实现简单的定位功能是一项常见的任务,它涉及到Android系统的地理位置服务,主要依赖于GPS(全球定位系统)以及网络定位技术。本实例将详细解析如何在Android应用中集成定位功能,让应用能够获取到...
《Android创意实例详解》这本书籍源码的分享,旨在为Android开发者提供丰富的实践案例和学习资源。这份源码集合涵盖了Android应用开发中的多种创新技术与设计思路,是深入理解和掌握Android开发技能的理想辅助资料。...
Android作为全球最受欢迎的移动操作系统之一,提供了对OpenGL ES 2的广泛支持。这意味着开发者可以利用这一强大工具来创建引人入胜的游戏和视觉效果丰富的应用程序。为了有效地使用OpenGL ES 2进行开发,本书涵盖了...