Android 개인 재 테 크 도구 3:계산서 페이지 추가
앞의 로그 인 페이지 에서 계산서 추가 페이지 로 넘 어 갑 니 다.이 페이지 는 주로 수지 기록 을 등록 하 는 데 쓰 인 다.솔직히 데이터베이스 에 내 역 을 입력 하 는 거 야.
표 구 조 는 다음 과 같다.
db.execSQL("CREATE TABLE bills ("
+ "_ID INTEGER PRIMARY KEY," //id
+ "fee integer," //비용.
+"acctitemid integer," //장부 유형
+ "userid integer," //사용자
+ "sdate TEXT," //날짜.
+ "stime TEXT," //시간.
+ "desc TEXT" //비고
+ ");");
주로 이 데 이 터 를 입력 하 는 것 을 볼 수 있다.우선 인 터 페 이 스 를 배치 하 는 것 입 니 다.제 가 지금 생각 하고 있 는 것 은 tablelayot 로 배치 하 는 것 입 니 다.
마지막 레이아웃 은 다음 그림(그림 1)과 같 습 니 다.
여기 서 나 는 먼저 장 부 를 설정 해 야 한다.앞에서 우 리 는 이미 장부 의 데 이 터 를 초기 화 했다.
장 부 는 ExpandableListActivity 2 층 의 구조 여야 합 니 다.데이터베이스 에서 읽 어야 합 니 다.나 는 장부 뒤에 editview 를 놓 고 커서 가 없 는 것 만 읽 었 다.즉,여기 서 입력 할 수 없다.이 editview 의 onclick 이벤트 에서 우 리 는 장부 선택 화면 을 열 었 다.다음 그림:
그림 2 장부 선택:
이 인터페이스 에서 서브 노드 를 누 르 면 앞 화면 으로 돌아 가 선택 한 장 부 를 전달 합 니 다.여기에 문제 가 있 습 니 다.만약 사용자 가 입력 해 야 할 장부 가 없다 면 어떻게 합 니까?
그래서 저 는 dialog 방식 이 아니 라 ExpandableListActivity 를 사 용 했 습 니 다.이 인터페이스 에서 키 노드 가 길 면 관리 장부 메뉴 를 꺼 내 장 부 를 유지 합 니 다.다음 그림 과 같 습 니 다.
그림 3 장부 선택 메뉴:
그림 4 장부 편집:
위의 절 차 는 말 하기 가 매우 간단 하지만,내 가 앤 드 리 오 드 로 작 성 했 을 때 많은 문제 에 부 딪 혔 지만,하나하나 가 나 에 의 해 해결 되 었 다.이것 이 바로 프로 그래 밍 의 즐거움 이다.
ExpandableList Activity 에 대해 서 는 android 에 있 는 apidemos 에 있 는 ExpandableList 1,ExpandableList 2,ExpandableList 3 를 참고 하 실 수 있 습 니 다.
이 안 은 이 ui 를 익히 는 데 도움 이 된다.ExpandableList 2 에 서 는 데이터베이스 에서 읽 는 예 입 니 다.물론 안 드 로 이 드 에 있 는 그 건 잘 모 르 겠 어 요.import android.provider.Contacts.People 을 인 용 했 기 때 문 이에 요.연락처 부분의 프레임 워 크 입 니 다.저 는 현재 데이터 베 이 스 를 조작 하 는 것 이 그 와 다 릅 니 다.저 는 모두 sql 로 직접 방문 합 니 다.
하지만 당신 은 cursor 2 개 만 해결 하면 됩 니 다.Cursor group Cursor child Cursor,다른 것 은 모두 Simple Cursor TreeAdapter 가 도와 주 었 습 니 다.
Simple Cursor TreeAdapter 를 어떻게 사용 하 는 지 살 펴 보 자.
자바 코드
// groupcursor , acctitem
//select * from accitem where pid is null
Cursor groupCursor = billdb.getParentNode();
// Cache the ID column index
mGroupIdColumnIndex = groupCursor.getColumnIndexOrThrow("_ID");
// Set up our adapter
mAdapter = new MyExpandableListAdapter(groupCursor, this, android.R.layout.simple_expandable_list_item_1,
android.R.layout.simple_expandable_list_item_1,
new String[] { "NAME" }, // Name for group layouts
new int[] { android.R.id.text1 },
new String[] { "NAME" }, //
new int[] { android.R.id.text1 });
setListAdapter(mAdapter);
// childCursor
// select * from acctitem where id=pid
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 를 사용 해 야 합 니 다.계 정 을 새로 만 드 는 것 은 계 정의 이름 을 입력 해 야 하기 때 문 입 니 다.바로 위의 그림 4 가 표현 한 것 이다.alertDialog 는 많은 방법 을 제공 하지만 list,treelist,radio 를 선택 할 수 있 습 니 다.안 타 깝 게 도 text 를 입력 할 수 없습니다.
여기 api demos 에 있 는 DateWidgets 1.java 와 소스 코드 에 있 는 DatePickerDialog.java 를 참 고 했 습 니 다.
우 리 는 alertdialog 에서 계승 한 후에 Editview 를 추가 하여 마지막 으로 데 이 터 를 되 돌려 줄 수 있 습 니 다.위 에서 내 가 말 한 자바 두 개 만 똑똑히 보고 처리 하면 간단 하 다.
주로 반전 함수 의 용법 이다.다음 코드 보기:
자바 코드
//
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");
// setView(label);
edit = new EditText(context);
edit.setText(value);
layout = new LinearLayout(context);
layout.setOrientation(LinearLayout.VERTICAL);
// LinearLayout.LayoutParams param =
// new LinearLayout.LayoutParams(100, 40);
// layout.addView(label, param);
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) {
// Log.v("cola","U click which="+which);
text = edit.getText().toString();
Log.v("cola", "U click text=" + text);
if (mCallback != null)
mCallback.onDateSet(text); //
}
}
이렇게 하면 사용자 정의 dialog 를 완성 할 수 있 습 니 다.장 부 를 새로 만 들 고 편집 할 수 있 습 니 다.장부 의 첨삭 과 수정 은 sql 의 일이 다.여기 서 나 는 또 하나의 문 제 를 만 났 다.바로 내 가 장 부 를 새로 만 든 후에 어떻게 인 터 페 이 스 를 갱신 하여 장부 수정 후의 변 화 를 반영 하 느 냐 하 는 것 이다.
여기 서 getExpandableListView().invalidate()만 사용 하면됐 습 니 다.
왜냐하면 나 는 이전에 ExpandableList 1.java 예 에서 그것 을 사용 하면 인 터 페 이 스 를 새로 고 칠 수 있 었 기 때문이다.
그 예 에서 제 가 배열 을 수정 한 후에 이 방법 을 호출 하면 화면 이 새로 고침 되 고 이 Simple Cursor TreeAdapter 에 서 는 안 될 것 같 습 니 다.
커서 만 새로 고치 면 될 것 같 아 요.나중에 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;
/**
* Demonstrates expandable lists backed by Cursors
*/
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);
// Query for people
Cursor groupCursor = billdb.getParentNode();
// Cache the ID column index
mGroupIdColumnIndex = groupCursor.getColumnIndexOrThrow("_ID");
// Set up our adapter
mAdapter = new MyExpandableListAdapter(groupCursor, this,
android.R.layout.simple_expandable_list_item_1,
android.R.layout.simple_expandable_list_item_1,
new String[] { "NAME" }, // Name for group layouts
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());// bundle
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) {
// Log.v("cola","id"+info.id);
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) + "";
// Log.v("cola","pid="+pid);
return billdb.getChildenNode(pid);
}
@Override
public long getGroupId(int groupPosition) {
// Log.v("cola", "getGroupId " + groupPosition);
Cursor groupCursor = (Cursor) getGroup(groupPosition);
return groupCursor.getLong(mGroupIdColumnIndex);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
// Log.v("cola", "getChildId " + groupPosition + "," +
// 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");
// setView(label);
edit = new EditText(context);
edit.setText(value);
layout = new LinearLayout(context);
layout.setOrientation(LinearLayout.VERTICAL);
// LinearLayout.LayoutParams param =
// new LinearLayout.LayoutParams(100, 40);
// layout.addView(label, param);
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) {
// Log.v("cola","U click which="+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;
/**
* Provides access to a database of notes. Each note has a title, the note
* itself, a creation date and a modified data.
*/
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{
//s.getBytes(encoding);
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,' ')");
//db.execSQL("insert into bills values(100,135,10000,'','',' ')");
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();
}
//getTree();
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");
}
}
시리즈 글:Android 개인 재 테 크 도구 6:계산서 내 역 표시
Android 개인 재 테 크 도구 5:계산서 내 역 표시
Android 개인 재 테 크 도구 4:계산서 페이지 추가
Android 개인 재 테 크 도구 3:계산서 페이지 추가
Android 개인 재 테 크 도구 2:SQLite 를 사용 하여 시작 할 때 데이터 초기 화
Android 개인 재 태 크 도구 1:프로젝트 개요 와 시작 인터페이스의 실현
이상 은 안 드 로 이 드 개발 개인 재 태 크 도구 에 대해 계산서 페이지 의 설명 을 추가 하고 해당 하 는 글 을 계속 업데이트 합 니 다.본 사이트 에 대한 지원 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.