ColaBox 登記收支記錄終于進入了復雜階段了.這個界面我也是查找了很多資料以及打開android的源代碼看了后才完成了,現在想來Google的開源真是明智的啊.
gn7pIoN f'*HP%+Y 從前面的登錄頁面跳轉進入添加賬單頁面.這個頁面主要是用來登記收支記錄的.
R0{+Xd 說白了就是往數據庫錄入明細.
n0nkv[ w Xfy,W 表結構就是db.execSQL("CREATE TABLE bills ("
Onby=Y o6 "_ID INTEGER PRIMARY KEY," //id
t4 h5R "fee integer," //費用
,NKDEcw] "acctitemid integer," //賬目類型
h?fv :^vSi "userid integer," //使用者
r's4 -\ "sdate TEXT," //日期
Bglh}_X "stime TEXT," //時間
M {_`X "desc TEXT" //備注
#W'jNX,h ");");
$UgM7V$ Q_qc_IcM y 可以看到主要是錄入這些數據.首先是布置界面,我目前想到的用個tablelayout來布局
!2$O^ }6" 最后布局就是如下圖這樣
Z Oyq{w!2 #*1\h=bzmW 圖1
gfFP-J3cN
rW&8#& gNo.&G [ /t(dhz&xN b-;+&Rb 在這兒我首先需要設置賬目,前面我們已經初始化過賬目的數據.
8 U B?X 賬目應該是一個ExpandableListActivity 2層的結構.需要從數據庫里面讀取.我在賬目后面放了一個editview 只讀沒有光標的.也就是在這兒不可錄入,在該editview的onclick事件里面我們打開賬目選擇界面.如下圖
tHJ#2X#Y. =k 2In_ 圖2 賬目選擇
0' @^PzX (B}+uI{
k"LbB#Q ZYos.ay I;S[Ft8d 在這個界面中點擊子節點就返回前面界面,把選擇的賬目傳遞過去.在這有個問題,如果用戶需要錄入的賬目沒有怎么辦?
ik=~`3Zp0 所以我這沒有用dialog方式而是用了ExpandableListActivity在這個界面中如果長點某個子節點就彈出管理賬目菜單,
\`-/\N 來維護賬目,如下圖所示:
OQ;DqV 圖3賬目選擇菜單示意 圖4 編輯賬目
^z-e" `7zz&f9dDX
,a9<\bd) HF" v \
C\Qor3]; -9Wx;u4]o kz\ D-b 上面這些流程說起來很簡單,可是當我用andriod編寫時,遇到了很多問題,不過一個個都被我解決了,這正是編程的快樂所在.
`VCU`Y 關于ExpandableListActivity 大家可以參考android 里面apidemos 里面ExpandableList1,ExpandableList2,ExpandableList3
=/&ob%J)9] 這里面對熟悉這個ui還是很有幫助的. 在ExpandableList2 里面就是從數據庫進行讀取的例子. 當然android里面那個我是沒太
ER~m &JI 看明白因為他引用了import android.provider.Contacts.People; 聯系人部分的框架,而我目前對數據庫的操作和他不一樣,我都是直接
R ,-y sql訪問.
Y O;N9wu3f 但是你只要搞定2個cursor就ok了. Cursor groupCursor childCursor 其他都由SimpleCursorTreeAdapter幫你實現了.
.<} (J#vC 下面我們來看看如何使用SimpleCursorTreeAdapter
t33/QW r //首先要實現groupcursor就是父節點游標,這個其實就是我的acctitem表的
?W-J2tgss{ //select * from accitem where pid is null 的結果
0 {#c Cursor groupCursor = billdb.getParentNode();
>MZWm6M8 // Cache the ID column index
":E fR`A# mGroupIdColumnIndex = groupCursor.getColumnIndexOrThrow("_ID");
m,NUNd#)\ // Set up our adapter
0j\?zt? mAdapter = new MyExpandableListAdapter(groupCursor, this, android.R.layout.simple_expandable_list_item_1,
(~}IoQp> android.R.layout.simple_expandable_list_item_1,
]4wyuP,up new String[] { "NAME" }, // Name for group layouts
zBD ?O! new int[] { android.R.id.text1 },
8wz%e( new String[] { "NAME" }, //
Lsa&A+fru new int[] { android.R.id.text1 });
Nr)v!z~y setListAdapter(mAdapter);
spter35b[ rUvjc4O} //然后我要實現childCursor
1M+o7HO.mG //其實就是select * from acctitem where id=pid 的結果
Wm>[5h%> public class MyExpandableListAdapter extends SimpleCursorTreeAdapter {
<y#-I%ed public MyExpandableListAdapter(Cursor cursor, Context context,
1xN6V-qk int groupLayout, int childLayout, String[] groupFrom,
Pf&\2_H3s9 int[] groupTo, String[] childrenFrom, int[] childrenTo)
j9"uxw@ {
A;~lG3j4 super(context, cursor, groupLayout, groupFrom, groupTo,
c\"t+/Z childLayout, childrenFrom, childrenTo);
+vOlA#t%Z }
b[&A,ZPh$@ protected Cursor getChildrenCursor(Cursor groupCursor) {
m(MPVY<X String pid = groupCursor.getLong(mGroupIdColumnIndex) "";
$="t7C9S // Log.v("cola","pid=" pid);
~aKM+KmtPH return billdb.getChildenNode(pid);
/5cFa }
9G njJ }
R@*mMWW, //我們看看Billdbhelper里面的cursor
_dQVundH public Cursor getParentNode(){
QwF\s13 return db.query("acctitem", new String[]{"_id", "name" }, "pid is null", null, null, null, "pid,_id");
;. jnRPo"; Md!L@gX6< }
,3 !D(& xd[GJ;xvs public Cursor getChildenNode(String pid){
61qs`N=k Log.v("cola","run getchildenNode");
KDx~^OO return db.query("acctitem", new String[]{"_id", "name" }, "pid=" pid, null, null, null, "_id");
+{b!,D3sa* }
SVr3OyzI 只要這幾步一個2級的tree list就可以出現了.
>j5,Z] 上面其實才是剛開始,后面我們需要使用一個自定義的Dialog 類似于一個inputBox 因為我們新增賬目是需要輸入賬目的名稱.
\BIa:}9O 就是上面圖4表現的.
e_eNtVq 雖然alertDialog提供了很多方法,可以選擇list,treelist,radio, 可惜就是不能錄入text.
aT9+] Ig 這里我參考了api demos 里面的 DateWidgets1.java 和源代碼里面DatePickerDialog.java .
KyQO>g{R 我們可以從alertdialog 繼承.然后添加一個Editview 最后把數據返回出來.只要把上面我說的2個java看清楚了后處理起來就簡單了.
[73 \jT 主要是一個回調函數的用法.下面看代碼
B=0U^wL //
<F>^ffwGH- public class Dialog_edit extends AlertDialog implements OnClickListener {
nRP|Qt7> private String text = "";
*=sMJY9#jE private EditText edit;
6Kl%|VrJs private OnDateSetListener mCallback; //定義回調函數
cst}/8e private LinearLayout layout;
-<g&U*/E public interface OnDateSetListener {//回調接口
9.:]eL void onDateSet(String text);
3/aK#TjK }
>,Z[IAU.x5 protected Dialog_edit(Context context, String title, String value,
Ipp#{'Do OnDateSetListener Callback) {
Qkvg 85 super(context);
xJ$/#UdP mCallback = Callback;
<:n !qQS6 TextView label = new TextView(context);
{ R`"Nk label.setText("hint");
FI(iqSJ6 // setView(label);
wHR# -g' edit = new EditText(context);
> u!# 4 edit.setText(value);
0| }]=XN^ layout = new LinearLayout(context);
Gp9:#L! layout.setOrientation(LinearLayout.VERTICAL);
\C}_l+nY // LinearLayout.LayoutParams param =
[S_qi, // new LinearLayout.LayoutParams(100, 40);
k d9<&.y{ // layout.addView(label, param);
'* eeup LinearLayout.LayoutParams param2 = new LinearLayout.LayoutParams(200,
y,xJ5BI$ 50);
]ft}fU5C1 layout.addView(edit, param2);
.Y5o&at6s //添加edit
!dV2:`|+ setView(layout);
".7\>8A#a setTitle(title);
6qd?&.=r setButton("確定", this);
P47 x-; setButton2("取消", (OnClickListener) null);
/^sk y! }
a7}O.NDf public void onClick(DialogInterface dialog, int which) {
uqvS // Log.v("cola","U click which=" which);
2&zklXuo: text = edit.getText().toString();
-sxu7I Log.v("cola", "U click text=" text);
hr W2#v if (mCallback != null)
abw5Gz@Ag mCallback.onDateSet(text);//使用回調返回錄入的數據
@~bP|a }
SQJ +C% }
^/I.? :+ 這樣我們就完成了自定義的dialog 我們可以使用它來新增和編輯賬目. 對于賬目的增刪改就是sql的事情了
LKBh{X0%( 在這我又遇到一個問題就是我新增一個賬目后如何來刷新界面,從而反映賬目修改后的變化
S1#5oy2 在這我開始以為只要使用getExpandableListView().invalidate(); 就可以了,
=E62N7_`= 因為我之前在ExpandableList1.java例子里面,使用它可以刷新界面.
tgj 5l#P 在那個例子里面我修改了數組后調用該方法,界面就刷新了,而在這SimpleCursorTreeAdapter就行不通了,我想
*D67&/g.