国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android 個人理財工具三:添加賬單頁面 上

2019-12-12 05:29:50
字體:
來源:轉載
供稿:網友

       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。

Java代碼      

//首先要實現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 類似于一個inputBox,因為我們新增賬目是需要輸入賬目的名稱。就是上面圖4表現的。

       雖然alertDialog提供了很多方法,可以選擇list、treelist、radio,可惜就是不能錄入text。

       這里我參考了api demos 里面的 DateWidgets1.java 和源代碼里面DatePickerDialog.java 。

       我們可以從alertdialog 繼承,然后添加一個Editview 最后把數據返回出來。只要把上面我說的2個java看清楚了后處理起來就簡單了。

       主要是一個回調函數的用法。下面看代碼:

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");   // 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(); 就可以了。

       因為我之前在ExpandableList1.java例子里面,使用它可以刷新界面。

       在那個例子里面我修改了數組后調用該方法,界面就刷新了,而在這SimpleCursorTreeAdapter就行不通了,我想

       應該只要刷新cursor應該就可以了,后來找到了notifyDataSetChanged,呵呵,果然可以了。 這樣賬目的錄入和管理就搞定了。

       下面給出目前最新的代碼。

       首先是賬目管理:

Java代碼

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);   }  } } 

       自定義對話框:

Java代碼

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);  } } 

       數據庫管理代碼:

Java代碼

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 個人理財工具六:顯示賬單明細 下

                       Android 個人理財工具五:顯示賬單明細 上

                       Android 個人理財工具四:添加賬單頁面 下

                       Android 個人理財工具三:添加賬單頁面 上

                       Android 個人理財工具二:使用SQLite實現啟動時初始化數據

                       Android 個人理財工具一:項目概述與啟動界面的實現

       以上就Android 開發個人理財工具 添加賬單頁面的講解,后續繼續更新相應文章,謝謝大家對本站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 巴林右旗| 滁州市| 崇信县| 菏泽市| 台湾省| 吴旗县| 延川县| 丰宁| 左贡县| 开封市| 宽甸| 长子县| 浦江县| 宜兰市| 唐海县| 法库县| 镇赉县| 德钦县| 宝清县| 澎湖县| 成武县| 巴楚县| 江孜县| 汝阳县| 甘孜| 陆良县| 佳木斯市| 黄骅市| 澜沧| 乌恰县| 合水县| 繁峙县| 英山县| 左贡县| 平江县| 宜州市| 桐庐县| 石河子市| 岗巴县| 清丰县| 镇雄县|