主頁 > 移動端開發 > 10分鐘手把手教你用Android手擼一個簡易的個人記賬App

10分鐘手把手教你用Android手擼一個簡易的個人記賬App

2021-07-21 14:06:29 移動端開發

封面

用Android手擼一個簡易的個人記賬系統

  • ??序言
  • 📋一、系統結構設計Design
    • 1. 需求分析
    • 2. 資料庫設計
    • 3. 界面設計
    • 4. 程序設計
  • 📘二、編碼階段Coding
    • 1. 專案結構🗂?
      • (1)檔案目錄
      • (2)AndroidManifest.xml
      • (3)Activity類解讀
      • (4)XML解讀
    • 2. 靜態頁面?
      • (1)用戶登錄頁面activity_main.xml
      • (2)用戶注冊頁面activity_register.xml
      • (3)用戶個人中心頁面activity_user_center.xml
      • (4)用戶搜索記錄頁面activity_search_record.xml
      • (5)收支管理頁面activity_manage.xml
      • (6)串列資料記錄record_item_layout.xml
    • 3. 邏輯結構💡
      • (1)DBHelper類
      • (2)MainActivity類
      • (3)RegisterActivity類
      • (4)UserCenterActivity類
      • (5)SearchRecordActivity類
      • (6)ManageActivity類
      • (7)User類
  • 🎵三、運行結果Result
  • 📈四、結束語
  • 🐣彩蛋 One More Thing
    • (:不合理設計
    • (:番外篇

??序言

前段時間期末周,這學期有一門課叫移動應用開發,這門課的期末作業是用 Android 寫一個個人記賬管理系統, Android 的前臺是用 xml 實作,后臺是用 java 實作,于是,對這兩門語言不太熟悉的周一,開始了漫漫長路的摸索之旅,

接下來就來講解,如何從0到1實作一個簡易的個人記賬系統

一起來學習⑧~🙃

溫馨小提示: 第二部分的編碼階段代碼較多,可直接滑到第三部分看運行效果,并到第四部分克隆github倉庫代碼,閱讀體驗更加~

📋一、系統結構設計Design

1. 需求分析

首先我們先來看下老師的需求👇

設計和實作一個類似個人財務管理的 Android APP ,資料庫采用 SQLite (也可以直接訪問 WebMySQL 資料庫、或提供 Web 介面訪問 MySQL 資料庫),

APP應具備以下功能:

  • 用戶注冊和登錄(這類 APP 一般面對個人,用戶不需要分類別);
  • 收入和支出管理(單條收支記錄的添加、洗掉和修改,收入和支出每一條記錄至少包括日期、型別、金額和說明,)
  • 收入和支出查詢(根據時間段、類別等進行查詢)
  • 收入和支出統計(例如某個月、某個星期或指定時間段的總收支)
  • 其他要求:界面設計應盡量美觀,可以添加一些圖片或背景,

基于以上需求,周一對所要實作的功能進行了整理,請看下方思維導圖:

需求分析

2. 資料庫設計

分析完成之后,接下來開始設計資料庫詳情見下方思維導圖:

資料庫設計

因為功能較為簡單,所以資料庫只設計了兩張表,

3. 界面設計

設計完資料庫之后,開始楷模潤色該 APP 的界面,基于本次課題需求,周一設計了5個界面,接下來先來看 App具體界面設計:

界面設計


看完五個界面所需要的內容之后,接下來,我們來對它進行原型繪制,請看下圖:

原型圖


現在,原型圖設計完畢,我們接著設計高保真 App 界面,請看下圖:

高保真界面1

高保真界面2

4. 程序設計

好了,看完原型圖之后,我們是不是該來想想頁面與頁面之間,是怎么進行互動的呢?

因此,現在我們來對整個程序進行設計,詳情見下方思維導圖:

程序設計

📘二、編碼階段Coding

1. 專案結構🗂?

(1)檔案目錄

先來看專案的檔案目錄詳情看下圖👇

專案檔案結構

(2)AndroidManifest.xml

接下來附上 AndroidManifest.xml 的代碼,具體代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.financial.management">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="個人財務管理App"
        android:roundIcon="@mipmap/ic_launcher"
        android:supportsRtl="true"
        android:theme="@style/Theme.Final">
       <activity android:name="com.financial.management.ManageActivity"></activity>
        <activity android:name="com.financial.management.SearchRecordActivity" />
        <activity android:name="com.financial.management.RegisterActivity"/>
        <activity android:name="com.financial.management.UserCenterActivity" />
        <activity android:name="com.financial.management.MainActivity">

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        </activity>
    </application>

</manifest>

(3)Activity類解讀

看完上面兩個內容之后,接下來是Activity類的解讀時間,詳情見下表👇

檔案名作用
MainActivity用戶登錄頁面Activity,用戶可以進行登錄,
RegisterActivity用戶注冊頁面Activity,用戶可以進行注冊,
UserCenterActivity個人中心Activity,對應用戶個人中心的4個按鈕進行功能撰寫,實作用戶收支管理、查看收支、收支統計、退出登錄四大功能,
ManageActivity收支管理Activity,對用戶的收入和支出進行管理,
SearchRecordActivity查詢收支Activity,通過條件對資料庫中的資料進行查詢,得出用戶想要查詢的收支結果,
DBHelper創建資料庫表和資料庫資料,同時實作與資料庫操作相關的登錄和注冊方法,
User用戶類Activity,用于獲取用戶ID以及密碼,

(4)XML解讀

解讀完 Activity 類之后,現在來對 XML 的各個檔案進行介紹,詳情見下表👇

檔案名作用
activity_main.xml用戶登錄頁面,用戶通過輸入賬號和密碼,進行登錄操作,
activity_register.xml用戶注冊頁面,用戶通過輸入賬號和密碼,進行注冊操作,
activity_user_center.xml個人中心頁面,當用戶登錄成功以后,進行個人中心頁面,個人中心實作收支管理、查看收支、收支統計、退出登錄四大功能,
activity_search_record.xml通過選擇年份月份來進行查詢該年該月份的各個收入支出詳情,并且計算總金額以及根據類別來計算該類別的總金額,
activity_manage.xml用戶對自己的日常開銷進行收支管理,可以進行添加、洗掉和修改等操作,
record_item_layout.xml用來存盤串列的傳輸資料

到這里,大家先對待會要撰寫的 Activity 類和 XML 檔案所要展示的功能先進行一番了解,

2. 靜態頁面?

現在,我們到了真正的編碼階段啦!如果是按照我的編碼習慣的話,我一般會先把靜態頁面進行構建,并把一些需要預留的id等等資訊給先處理好,方便后面寫業務邏輯時可以直接進行系結,

針對以上6個靜態頁面,下面將進行代碼撰寫,

(1)用戶登錄頁面activity_main.xml

activity_main.xml 是用戶登錄頁面,當用戶通過輸入賬號和密碼時,可以進行登錄操作,具體代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:gravity="center_horizontal"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/textView1"
            android:layout_width="360dp"
            android:layout_height="360dp"
            android:gravity="center"
            android:background="@drawable/login_logo"
            android:textColor="#fff"
            android:textSize="24dp"
            android:layout_marginTop="-30dp"
            android:layout_marginHorizontal="45dp"/>

        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:gravity="center|center_horizontal"
            android:text="用戶登錄"
            android:textColor="#5768C5"
            android:textSize="20dp"
            android:layout_marginTop="-60dp"
            />


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:paddingHorizontal="20dp"
            android:paddingVertical="10dp">

            <ImageView
                android:id="@+id/imageView3"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_weight="0"
                app:srcCompat="@drawable/account" />

            <EditText
                android:id="@+id/edt_uid"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:ems="10"
                android:hint="請輸入您的用戶名"
                android:inputType="textPersonName" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0"
            android:orientation="horizontal"
            android:paddingHorizontal="20dp"
            android:paddingVertical="10dp">

            <ImageView
                android:id="@+id/imageView4"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_weight="0"
                app:srcCompat="@drawable/password" />

            <EditText
                android:id="@+id/edt_upwd"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:ems="10"
                android:hint="請輸入您的密碼"
                android:inputType="textPassword" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="80dp"
            android:gravity="center"
            android:orientation="horizontal"
            android:paddingHorizontal="60dp">

            <Button
                android:id="@+id/btn_login"
                android:layout_width="100dp"
                android:layout_height="60dp"
                android:layout_weight="1"
                android:text="登錄"
                android:textSize="18dp"
                app:backgroundTint="#4757AE"
                app:cornerRadius="50dp" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <Button
                android:id="@+id/btn_register"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:gravity="center"
                android:text="還沒有賬號?現在注冊"
                android:textColor="#888282"
                android:textColorHint="#FFFFFFFF"
                android:backgroundTint="#FFFFFFFF"
                android:color="#FFFFFF"
                />
        </LinearLayout>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="20dp"
            android:background="#FFFFFF"
            android:layout_marginTop="-10dp"/>

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

(2)用戶注冊頁面activity_register.xml

activity_register.xml 是用戶注冊頁面,用戶通過輸入賬號和密碼,可以進行注冊操作,具體代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".RegisterActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:gravity="center"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/textView10"
            android:layout_width="220dp"
            android:layout_height="220dp"
            android:background="@drawable/register_logo"
            android:gravity="center"
            android:textColor="#FFEB3B"
            android:layout_marginBottom="20dp"/>

        <TextView
            android:id="@+id/textView5"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:gravity="center"
            android:text="用戶注冊"
            android:textColor="#0C6BC2"
            android:textSize="22sp" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:paddingHorizontal="20dp"
            android:layout_marginTop="10dp">

            <TextView
                android:id="@+id/textView7"
                android:layout_width="wrap_content"
                android:layout_height="45dp"
                android:layout_weight="0"
                android:text="賬  號:  "
                android:textColor="#0C6BC2"
                android:textSize="22sp" />

            <EditText
                android:id="@+id/edt_rid"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:ems="10"
                android:hint="請輸入需要注冊的賬號"
                android:inputType="textPersonName" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:paddingHorizontal="20dp"
            android:layout_marginVertical="15dp">

            <TextView
                android:id="@+id/textView8"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="0"
                android:text="密  碼:  "
                android:textColor="#0C6BC2"
                android:textSize="22sp" />

            <EditText
                android:id="@+id/edt_rpwd"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:ems="10"
                android:hint="請輸入密碼"
                android:inputType="textPassword" />
        </LinearLayout>

        <Button
            android:id="@+id/btn_registeruser"
            android:layout_width="260dp"
            android:layout_height="60dp"
            android:layout_gravity="center"
            android:layout_marginVertical="20dp"
            android:background="#2D6C2F"
            android:gravity="center"
            android:text="注冊"
            android:textSize="22sp"
            app:backgroundTint="#1C8DE6" />

    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

(3)用戶個人中心頁面activity_user_center.xml

現在,來到了個人中心頁面,在個人中心頁面當中,將會顯示具體的用戶名,同時, 有四個按鈕入口,分別是:收支管理,查看收支,退出登錄和收支統計,來看下具體代碼實作:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".UserCenterActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="120dp"
            android:orientation="horizontal"
            android:gravity="center">

            <ImageView
                android:id="@+id/imageView"
                android:layout_width="60dp"
                android:layout_height="60dp"
                app:srcCompat="@drawable/girl"
                android:layout_marginHorizontal="30dp"/>

            <TextView
                android:id="@+id/tv_welcome"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center|left"
                android:textColor="#4F92CF"
                android:textSize="24sp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:gravity="center_horizontal"
            android:layout_marginTop="40dp">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginHorizontal="20dp"
                android:background="#FFFFFF"
                android:gravity="center_horizontal"
                android:orientation="vertical"
                android:padding="24dp"
                android:elevation="10dp"
                app:cornerRadius="30dp">

                <ImageView
                    android:id="@+id/btn_recordmanage"
                    android:layout_width="60dp"
                    android:layout_height="60dp"
                    app:srcCompat="@drawable/revenue" />

                <TextView
                    android:id="@+id/textView17"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="20dp"
                    android:text="收支管理"
                    android:textColor="#252020"
                    android:textSize="18sp" />
            </LinearLayout>

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:gravity="center_horizontal"
                android:layout_marginHorizontal="20dp"
                android:background="#FFFFFF"
                android:padding="24dp"
                android:elevation="10dp"
                app:cornerRadius="30dp">

                <ImageView
                    android:id="@+id/btn_searchrecord"
                    android:layout_width="60dp"
                    android:layout_height="60dp"
                    app:srcCompat="@drawable/look" />

                <TextView
                    android:id="@+id/textView22"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="查看收支"
                    android:textColor="#FF252020"
                    android:textSize="18sp"
                    android:layout_marginTop="20dp"/>
            </LinearLayout>
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:gravity="center_horizontal"
            android:layout_marginVertical="30dp">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:gravity="center_horizontal"
                android:layout_marginHorizontal="20dp"
                android:background="#FFFFFF"
                android:padding="24dp"
                android:elevation="10dp"
                app:cornerRadius="30dp">

                <ImageView
                    android:id="@+id/btn_exit"
                    android:layout_width="60dp"
                    android:layout_height="60dp"
                    app:srcCompat="@drawable/exit" />

                <TextView
                    android:id="@+id/textView4"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:text="退出登錄"
                    android:textColor="#FF252020"
                    android:textSize="18sp"
                    android:layout_marginTop="20dp"/>
            </LinearLayout>

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:gravity="center_horizontal"
                android:layout_marginHorizontal="20dp"
                android:background="#FFFFFF"
                android:padding="24dp"
                android:elevation="10dp"
                app:cornerRadius="30dp">

                <ImageView
                    android:id="@+id/btn_calcmoney"
                    android:layout_width="60dp"
                    android:layout_height="60dp"
                    app:srcCompat="@drawable/statics" />

                <TextView
                    android:id="@+id/textView23"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="收支統計"
                    android:textColor="#FF252020"
                    android:textSize="18sp"
                    android:layout_marginTop="20dp"/>
            </LinearLayout>
            
        </LinearLayout>
        
    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

(4)用戶搜索記錄頁面activity_search_record.xml

用戶可以通過選擇年份月份和篩選型別,點擊搜索,來查詢該年該月份的各個收入和支出的詳情,同時在該時間點和該篩選型別下,點擊計算可以對總金額進行計算,下面附上具體代碼實作:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context=".SearchRecordActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:gravity="center"
            android:layout_marginTop="50dp"
            android:layout_marginBottom="10dp">

            <ImageView
                android:id="@+id/imageView2"
                android:layout_width="120dp"
                android:layout_height="120dp"
                app:srcCompat="@drawable/income_2" />

            <TextView
                android:id="@+id/textView20"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="我的收支"
                android:textColor="#3F51B5"
                android:textSize="20sp"
                android:layout_marginTop="10dp"/>
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:orientation="horizontal"
            android:gravity="center_vertical"
            android:layout_marginHorizontal="24dp"
            android:layout_marginTop="30dp">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="100dp"
                android:orientation="vertical">

                <TextView
                    android:id="@+id/textView33"
                    android:layout_width="wrap_content"
                    android:layout_height="50dp"
                    android:text="日期  "
                    android:gravity="center_vertical"
                    android:textColor="#111113"
                    android:textSize="18sp" />

                <TextView
                    android:id="@+id/textView34"
                    android:layout_width="wrap_content"
                    android:layout_height="50dp"
                    android:text="型別  "
                    android:gravity="center_vertical"
                    android:textColor="#FF111113"
                    android:textSize="18sp" />
            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="100dp"
                android:layout_weight="1"
                android:orientation="vertical">

                <Spinner
                    android:id="@+id/spin_date"
                    android:layout_width="match_parent"
                    android:layout_height="50dp" />

                <Spinner
                    android:id="@+id/spin_type"
                    android:layout_width="match_parent"
                    android:layout_height="50dp"
                    android:layout_weight="1" />
            </LinearLayout>

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="100dp"
                android:orientation="vertical"
                android:gravity="center_vertical">

                <Button
                    android:id="@+id/btn_search"
                    android:layout_width="60dp"
                    android:layout_height="40dp"
                    android:background="#39DC54"
                    android:text="搜索"
                    android:textColor="#FAF9F9"
                    android:textSize="12sp"
                    app:backgroundTint="#5E97DA" />
            </LinearLayout>
        </LinearLayout>

        <ImageView
            android:layout_width="360dp"
            android:layout_height="0.5dp"
            android:background="#D1CDCD"
            android:layout_gravity="center"
            android:paddingHorizontal="24dp"/>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            android:layout_marginHorizontal="24dp">

            <TextView
                android:id="@+id/textView32"
                android:layout_width="wrap_content"
                android:layout_height="50dp"
                android:text="總金額  "
                android:gravity="center_vertical"
                android:textColor="#FF111113"
                android:textSize="18sp" />

            <TextView
                android:id="@+id/tv_show"
                android:layout_width="wrap_content"
                android:layout_height="50dp"
                android:layout_weight="1"
                android:textColor="#4CAF65"
                android:textSize="24sp"
                android:gravity="center_vertical"/>

            <Button
                android:id="@+id/btn_calc"
                android:layout_width="60dp"
                android:layout_height="40dp"
                android:gravity="center_vertical"
                android:text="計算"
                android:textColor="#FAF9F9"
                android:textSize="12sp"
                app:backgroundTint="#5E97DA" />
        </LinearLayout>

        <ImageView
            android:layout_width="360dp"
            android:layout_height="0.5dp"
            android:background="#D1CDCD"
            android:layout_gravity="center"
            android:paddingHorizontal="20dp"/>

        <TextView
            android:id="@+id/textView31"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:gravity="center_vertical"
            android:text="查詢結果  "
            android:layout_marginTop="20dp"
            android:textColor="#111113"
            android:layout_marginHorizontal="24dp"
            android:textSize="18sp"/>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_marginVertical="20dp"
            android:layout_marginHorizontal="20dp">

            <TextView
                android:id="@+id/textView29"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="序號"
                android:textColor="#6290c8"
                android:textStyle="bold"
                android:textSize="18sp"
                android:gravity="center_horizontal"/>

            <TextView
                android:id="@+id/textView26"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="日期"
                android:textColor="#6290c8"
                android:textStyle="bold"
                android:textSize="18sp"
                android:gravity="center_horizontal"/>

            <TextView
                android:id="@+id/textView25"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="型別"
                android:textColor="#6290c8"
                android:textStyle="bold"
                android:textSize="18sp"
                android:gravity="center_horizontal"/>

            <TextView
                android:id="@+id/textView27"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="金額"
                android:textColor="#6290c8"
                android:textStyle="bold"
                android:textSize="18sp"
                android:gravity="center_horizontal"/>

            <TextView
                android:id="@+id/textView28"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="說明"
                android:textColor="#6290c8"
                android:textStyle="bold"
                android:textSize="18sp"
                android:gravity="center_horizontal"/>
        </LinearLayout>

        <ListView
            android:id="@+id/searchlistview"
            android:layout_width="match_parent"
            android:layout_height="500dp"
            android:layout_weight="0"
            android:layout_marginHorizontal="20dp"/>
    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

(5)收支管理頁面activity_manage.xml

對于收支管理頁面來說,用戶可以對自己的日常開銷進行收支管理,同時也可以進行添加、洗掉和修改等操作,具體代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ManageActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_horizontal"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:gravity="center"
            android:orientation="vertical">

            <ImageView
                android:id="@+id/imageView2"
                android:layout_width="150dp"
                android:layout_height="150dp"
                android:layout_marginTop="20dp"
                app:srcCompat="@drawable/income_1" />

            <TextView
                android:id="@+id/textView20"
                android:layout_width="wrap_content"
                android:layout_height="30dp"
                android:text="收支管理"
                android:textColor="#3F51B5"
                android:textSize="20dp" />
        </LinearLayout>


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:gravity="center_vertical"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/textView36"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginHorizontal="20dp"
                android:text="您選擇的序號是:"
                android:textColor="#152029"
                android:textSize="18sp"
                android:textStyle="bold" />

            <TextView
                android:id="@+id/tv_test"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="暫未選擇"
                android:textColor="#4CAF50"
                android:textSize="18sp" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginHorizontal="20dp"
            android:layout_marginVertical="10dp"
            android:gravity="center"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/textView29"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_weight="1"
                android:text="序號"
                android:textColor="#111819"
                android:textSize="18sp" />

            <TextView
                android:id="@+id/textView26"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="日期"
                android:textColor="#111819"
                android:textSize="18sp" />

            <TextView
                android:id="@+id/textView25"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="型別"
                android:textColor="#111819"
                android:textSize="18sp" />

            <TextView
                android:id="@+id/textView27"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="金額"
                android:textColor="#111819"
                android:textSize="18sp" />

            <TextView
                android:id="@+id/textView28"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="說明"
                android:textColor="#111819"
                android:textSize="18sp" />

        </LinearLayout>

        <ImageView
            android:layout_width="380dp"
            android:layout_height="0.5dp"
            android:background="#D8D3D3"
            android:paddingHorizontal="20dp" />

        <ListView
            android:id="@+id/recordlistview"
            android:layout_width="wrap_content"
            android:layout_height="120dp"
            android:layout_weight="1"></ListView>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginHorizontal="14dp"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/textView18"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="日期: "
                android:textColor="#101112"
                android:textSize="18sp" />

            <EditText
                android:id="@+id/edt_date"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:ems="10"
                android:hint="填寫日期,如:202107表示2021年7月"
                android:inputType="textPersonName" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginHorizontal="14dp"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/textView21"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="型別: "
                android:textColor="#101112"
                android:textSize="18sp" />

            <EditText
                android:id="@+id/edt_type"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:ems="10"
                android:hint="型別為收入或支出"
                android:inputType="textPersonName" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginHorizontal="14dp"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/textView30"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="金額: "
                android:textColor="#101112"
                android:textSize="18sp" />

            <EditText
                android:id="@+id/edt_money"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:ems="10"
                android:hint="請輸入金額"
                android:inputType="textPersonName" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginHorizontal="14dp"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/tv_state"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="說明: "
                android:textColor="#101112"
                android:textSize="18sp" />

            <EditText
                android:id="@+id/edt_state"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:ems="10"
                android:hint="闡述說明"
                android:inputType="textPersonName" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginVertical="30dp">

            <Button
                android:id="@+id/btn_add"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginHorizontal="10dp"
                android:layout_weight="1"
                android:text="添加"
                app:backgroundTint="#78C6A3" />

            <Button
                android:id="@+id/btn_update"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginHorizontal="10dp"
                android:layout_weight="1"
                android:text="修改"
                app:backgroundTint="#56AB91" />

            <Button
                android:id="@+id/btn_delete"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginHorizontal="10dp"
                android:layout_weight="1"
                android:text="洗掉"
                app:backgroundTint="#358F80" />
        </LinearLayout>
    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

(6)串列資料記錄record_item_layout.xml

record_item_layout.xml 主要用途是存盤串列的傳輸資料,具體代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:layout_marginHorizontal="20dp"
        android:gravity="center_horizontal"
        android:paddingVertical="2dp">

        <TextView
            android:id="@+id/list_id"
            android:layout_width="40dp"
            android:layout_height="24dp"
            android:layout_weight="1"
            android:textSize="18sp"
            android:gravity="center_horizontal" />

        <TextView
            android:id="@+id/list_date"
            android:layout_width="90dp"
            android:layout_height="24dp"
            android:layout_weight="1"
            android:textSize="18sp"
            android:gravity="center_horizontal" />

        <TextView
            android:id="@+id/list_type"
            android:layout_width="70dp"
            android:layout_height="24dp"
            android:layout_weight="1"
            android:textSize="18sp"
            android:gravity="center_horizontal" />

        <TextView
            android:id="@+id/list_money"
            android:layout_width="70dp"
            android:layout_height="24dp"
            android:layout_weight="1"
            android:textSize="18sp"
            android:gravity="center_horizontal" />

        <TextView
            android:id="@+id/list_state"
            android:layout_width="90dp"
            android:layout_height="24dp"
            android:layout_weight="1"
            android:textSize="18sp"
            android:gravity="center_horizontal" />

    </LinearLayout>
</LinearLayout>

3. 邏輯結構💡

寫完靜態頁面之后,接下來我們要對每個頁面的邏輯進行撰寫,現在我們來看一下各個 Activity 類所實作的內容都有些什么呢?

(1)DBHelper類

DBHelper 類用于創建資料庫表資料庫資料,同時實作與資料庫操作相關的登錄和注冊方法,具體代碼實作如下:

package com.financial.management;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DBHelper extends SQLiteOpenHelper {
    public static final String DB_NAME = "Test.db";
    public static final String TABLE_NAME = "userinfo";
    public static final String COLUMN_USERID = "uid";
    public static final String COLUMN_USERPWD = "upwd";


    //創建資料庫陳述句
    private static final String CREATE_TABLE = "create table if not exists "
            + TABLE_NAME + "(" + COLUMN_USERID + " text not null primary key,"
            + COLUMN_USERPWD + " text not null)";

    public DBHelper(Context context) {
        super(context, DB_NAME, null, 1);
    }

    //創建資料庫方法
    @Override
    public void onCreate(SQLiteDatabase db) {
        try {
            db.execSQL(CREATE_TABLE);
            db.execSQL("insert into " + TABLE_NAME + " values('11','11')");
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }

    //重置資料庫方法(先刪表,再建表)
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("drop table  if exists " + TABLE_NAME);
        db.execSQL(CREATE_TABLE);
    }

    //登錄方法
    public User userlogin(String userId, String userPwd) {
        User user = null;
        SQLiteDatabase db = getReadableDatabase();
        Cursor cursor = db.query(TABLE_NAME,
                new String[]{COLUMN_USERID, COLUMN_USERPWD},
                COLUMN_USERID + "=? and " + COLUMN_USERPWD + "=?",
                new String[]{userId, userPwd},
                null,
                null,
                null);
        if (cursor.getCount() > 0) {
            cursor.moveToFirst();
            user = new User();
            user.setUserId(cursor.getString(cursor.getColumnIndex(COLUMN_USERID)));
            user.setUserPwd(cursor.getString(cursor.getColumnIndex(COLUMN_USERPWD)));

        }
        return user;
    }

    //注冊方法
    public long registerUser(User user) {
        SQLiteDatabase db = getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put(COLUMN_USERID, user.getUserId());
        contentValues.put(COLUMN_USERPWD, user.getUserPwd());
        return db.insert(TABLE_NAME, null, contentValues);

    }
}

(2)MainActivity類

MainActivity 類是用戶登錄頁面的Activity,主要撰寫用戶登錄頁面的代碼邏輯,具體代碼實作如下:

package com.financial.management;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import java.util.ArrayList;


//登錄頁面邏輯
public class MainActivity extends AppCompatActivity {
    EditText edt_id,edt_pwd;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        edt_id = findViewById(R.id.edt_uid);
        edt_pwd =findViewById(R.id.edt_upwd);
        Button btn_login = findViewById(R.id.btn_login);
        //登錄按鍵
        btn_login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    String userId=edt_id.getText().toString();
                    String userPwd=edt_pwd.getText().toString();
                    DBHelper dbuserHelper=new DBHelper(getApplicationContext());
                    User user = dbuserHelper.userlogin(userId,userPwd);

                    //登錄成功跳轉對應型別界面
                    if(user!=null) {
                        Toast.makeText(getApplicationContext(), user.getUserId() + "登錄成功", Toast.LENGTH_SHORT).show();
                        Intent intent;
                        ArrayList<User> list = new ArrayList<>();
                        list.add(user);

                        intent = new Intent(getApplicationContext(), UserCenterActivity.class);
                        intent.putParcelableArrayListExtra("LoginUser", list);
                        startActivity(intent);
                    }else{
                        Toast.makeText(getApplicationContext(),"登錄失敗,密碼錯誤或賬號不存在!",Toast.LENGTH_SHORT).show();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(),"資料庫例外",Toast.LENGTH_SHORT).show();
                }
            }
        });
        //注冊按鍵
        Button btn_register=findViewById(R.id.btn_register);
        btn_register.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(getApplicationContext(),RegisterActivity.class);

                startActivity(intent);
            }
        });
    }
}

(3)RegisterActivity類

RegisterActivity 類是用戶注冊頁面的Activity,主要撰寫用戶注冊頁面的業務邏輯,具體代碼實作如下:

package com.financial.management;


import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import java.util.ArrayList;

//注冊頁面邏輯
public class RegisterActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);
        final EditText edt_rid =findViewById(R.id.edt_rid);
        final EditText edt_rpwd =findViewById(R.id.edt_rpwd);
        //注冊按鍵
        Button btn_registerf=findViewById(R.id.btn_registeruser);
        btn_registerf.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                User user = new User();
                user.setUserId(edt_rid.getText().toString());
                user.setUserPwd(edt_rpwd.getText().toString());

                DBHelper dbUserHelper = new DBHelper(getApplicationContext());
                if (dbUserHelper.registerUser(user) > 0) {
                    Toast.makeText(getApplicationContext(), "注冊成功", Toast.LENGTH_SHORT).show();
                    Intent intent;
                    ArrayList<User> list = new ArrayList<>();
                    list.add(user);

                    intent = new Intent(getApplicationContext(), MainActivity.class);
                    startActivity(intent);

                }else{
                    Toast.makeText(getApplicationContext(), "您已經注冊過此賬戶,請回傳登錄", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

(4)UserCenterActivity類

UserCenterActivity 類是個人中心頁面的Activity,主要撰寫個人中心各種按鈕跳轉的業務邏輯,具體代碼實作如下:

package com.financial.management;


import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;

//用戶個人中心頁面邏輯
public class UserCenterActivity extends AppCompatActivity {
    ArrayList<User> list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_user_center);

        Intent intent=getIntent();
        list =intent.getParcelableArrayListExtra("LoginUser");
        User user=list.get(0);
        final String username=user.getUserId();
        TextView tv_welcome=findViewById(R.id.tv_welcome);
        tv_welcome.setText("歡迎您 ,用戶"+username);

        //收支管理
        ImageView btn_recordmanage =findViewById(R.id.btn_recordmanage);
        btn_recordmanage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent1=new Intent(getApplicationContext(), ManageActivity.class);
                startActivity(intent1);
            }
        });
        //收支查詢
        ImageView btn_searchrecord=findViewById(R.id.btn_searchrecord);
        btn_searchrecord.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent2=new Intent(getApplicationContext(),SearchRecordActivity.class);
                startActivity(intent2);
            }
        });
        //收支統計
        ImageView btn_calcmoney=findViewById(R.id.btn_calcmoney);
        btn_calcmoney.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent3=new Intent(getApplicationContext(),SearchRecordActivity.class);
                startActivity(intent3);
            }
        });
        //退出按鍵
        ImageView btn_exit=findViewById(R.id.btn_exit);
        btn_exit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AlertDialog dialog = new AlertDialog.Builder(UserCenterActivity.this).setTitle("退出操作")
                        .setMessage("確定退出,不繼續玩玩?")
                        .setPositiveButton("確定", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                Intent intent=new Intent(getApplicationContext(), MainActivity.class);
                                startActivity(intent);
                            }
                        }).setNegativeButton("繼續留下!", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {

                            }
                        }).create();
                dialog.show();

            }
        });
    }
}

(5)SearchRecordActivity類

SearchRecordActivity 類是搜索記錄頁面的Activity,主要撰寫我的收支頁面的業務邏輯,具體代碼實作如下:

package com.financial.management;

import androidx.appcompat.app.AppCompatActivity;

import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

//收支記錄頁面業務邏輯
public class SearchRecordActivity extends AppCompatActivity {
    //定義spinner中的資料
    private String[] date_data= {"", "202101", "202102", "202103", "202104", "202105","202106","202107","202108","202109","202110","202111","202112"};
    private String[] type_data = {"", "收入", "支出"};
    Spinner spin_date, spin_type;
    ListView listView;
    TextView tv_show;
    float sum=0;
    //資料庫
    private String selectDate, selectType;
    private static final String DATABASE_NAME = "Test.db";
    private static final String TABLE_NAME = "record";
    private static final String COLUMN_ID = "id";
    private static final String COLUMN_DATE = "date";
    private static final String COLUMN_TYPE = "type";
    private static final String COLUMN_MONEY = "money";
    private static final String COLUMN_STATE = "state";
    private SQLiteDatabase sqLiteDatabase = null;

    private void selectSumMoney() {
        //自定義查詢的sql陳述句
        String sql;
        //如果查詢時間和查詢型別都為空,則查詢整個表
        if (TextUtils.isEmpty(selectDate) && TextUtils.isEmpty(selectType)) {
            sql = "select * from " + TABLE_NAME;
            //如果有查詢時間,沒有查詢型別,查詢指定內容
        } else if (!TextUtils.isEmpty(selectDate) && TextUtils.isEmpty(selectType)) {
            sql = "select * from " + TABLE_NAME + " where date='" + selectDate + "'";
            //如果沒有查詢時間,有查詢型別,查詢指定內容
        } else if (TextUtils.isEmpty(selectDate) && !TextUtils.isEmpty(selectType)) {//如果沒有查詢時間,有查詢型別
            sql = "select * from " + TABLE_NAME + " where type='" + selectType+"'";
        } else {//否則,查詢條件都不為空,查詢指定內容
            sql ="select * from " + TABLE_NAME + " where date='" + selectDate + "' and type='" + selectType+"'";
        }
        Cursor cursor = sqLiteDatabase.rawQuery(sql, null);

        while (cursor.moveToNext()) {

            float money = cursor.getFloat(cursor.getColumnIndex(COLUMN_MONEY));
            sum=sum+money;

            //list.add(map);
        }
        String money2=String.valueOf(sum);
        tv_show.setText(money2);
        sum=0;
    }
    //選擇資料
    private void selectData() {
        //自定義查詢的sql陳述句
        String sql;
        //如果查詢時間和查詢型別都為空,則查詢整個表
        if (TextUtils.isEmpty(selectDate) && TextUtils.isEmpty(selectType)) {
            sql = "select * from " + TABLE_NAME;
            //如果有查詢時間,沒有查詢型別,查詢指定內容
        } else if (!TextUtils.isEmpty(selectDate) && TextUtils.isEmpty(selectType)) {
            sql = "select * from " + TABLE_NAME + " where date='" + selectDate + "'";
            //如果沒有查詢時間,有查詢型別,查詢指定內容
        } else if (TextUtils.isEmpty(selectDate) && !TextUtils.isEmpty(selectType)) {//如果沒有查詢時間,有查詢型別
            sql = "select * from " + TABLE_NAME + " where type='" + selectType+"'";
        } else {//否則,查詢條件都不為空,查詢指定內容
            sql = "select * from " + TABLE_NAME + " where date='" + selectDate + "' and type='" + selectType+"'";
        }
        //將查詢到的資料封裝到Cursor
        Cursor cursor = sqLiteDatabase.rawQuery(sql, null);
        ArrayList<Map<String, String>> list = new ArrayList<Map<String, String>>();
        if (cursor.getCount() == 0) {
            //查無資料則怒不顯示串列
            // listView.setVisibility(View.GONE);
            Toast.makeText(getApplicationContext(), "無資料", Toast.LENGTH_SHORT).show();
        } else {
            //查有資料則顯示串列
            listView.setVisibility(View.VISIBLE);
            while (cursor.moveToNext()) {

                int id = cursor.getInt(cursor.getColumnIndex(COLUMN_ID));
                String date = cursor.getString(cursor.getColumnIndex(COLUMN_DATE));
                String type = cursor.getString(cursor.getColumnIndex(COLUMN_TYPE));
                float money = cursor.getFloat(cursor.getColumnIndex(COLUMN_MONEY));
                String state = cursor.getString(cursor.getColumnIndex(COLUMN_STATE));
                Map<String, String> map = new HashMap<String, String>();
                map.put("id", String.valueOf(id));
                map.put("date", date);
                map.put("type", type);
                map.put("money", String.valueOf(money));
                map.put("state", state);
                list.add(map);
            }
            //創建SimpleAdapter
            SimpleAdapter simpleAdapter = new SimpleAdapter(getApplicationContext(),
                    list,
                    R.layout.record_item_layout,
                    new String[]{"id", "date", "type", "money", "state"},
                    new int[]{R.id.list_id, R.id.list_date, R.id.list_type, R.id.list_money, R.id.list_state});
            listView.setAdapter(simpleAdapter);

        }
    }

    //時間和類別spinner點擊事件
    private void initClick() {
        //時間事件
        spin_date.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                selectDate = date_data[position];
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });
        //類別事件
        spin_type.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                selectType = type_data[position];
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });

        findViewById(R.id.btn_search).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                selectData();
            }
        });
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search_record);
        tv_show=findViewById(R.id.tv_show);
        try {
            //打開資料庫,如果是第一次會創建該資料庫,模式為MODE_PRIVATE
            sqLiteDatabase = openOrCreateDatabase(DATABASE_NAME, MODE_PRIVATE, null);
            //執行創建表的sql陳述句,雖然每次都呼叫,但只有首次才創建表

            //執行查詢
            listView = findViewById(R.id.searchlistview);//系結串列
            selectData();
        } catch (SQLException e) {
            Toast.makeText(this, "資料庫例外!", Toast.LENGTH_LONG).show();
            e.printStackTrace();
        }

        ArrayAdapter<String> adapter = new
                ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, date_data);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spin_date = findViewById(R.id.spin_date);
        spin_date.setAdapter(adapter);

        ArrayAdapter<String> adapter1 = new
                ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, type_data);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spin_type = findViewById(R.id.spin_type);
        spin_type.setAdapter(adapter1);
        initClick();
        Button btn_calc=findViewById(R.id.btn_calc);
        btn_calc.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                selectSumMoney();

            }
        });
    }
}

(6)ManageActivity類

ManageActivity 類是收支管理頁面的Activity,主要撰寫用戶的收入和支出的業務邏輯,實作收支的增刪改查具體代碼實作如下:

package com.financial.management;

import androidx.appcompat.app.AppCompatActivity;
import android.content.DialogInterface;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AlertDialog;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class ManageActivity extends AppCompatActivity {
    private SQLiteDatabase sqLiteDatabase = null;
    private int selectId = -1;
    EditText edt_date, edt_type, edt_money, edt_state;
    TextView tv_test;

    private static final String DATABASE_NAME = "Test.db";
    private static final String TABLE_NAME = "record";
    private static final String COLUMN_ID = "id";
    private static final String COLUMN_DATE = "date";
    private static final String COLUMN_TYPE = "type";
    private static final String COLUMN_MONEY = "money";
    private static final String COLUMN_STATE = "state";

    //創建表
    private static final String CREATE_TABLE = "create table if not exists " + TABLE_NAME
            + "(" + COLUMN_ID + " integer primary key autoincrement," + COLUMN_DATE + " text," + COLUMN_TYPE
            + " text," + COLUMN_MONEY + " float," + COLUMN_STATE + " text)";

    //自定義的查詢方法
    private void selectData() {
        //遍歷整個表
        String sql = "select * from " + TABLE_NAME ;
        //把查詢資料封裝到Cursor
        Cursor cursor = sqLiteDatabase.rawQuery(sql, null);
        ArrayList<Map<String, String>> list = new ArrayList<Map<String, String>>();
        //用while回圈遍歷Cursor,再把它分別放到map中,最后統一存入list中,便于呼叫
        while (cursor.moveToNext()) {

            int id = cursor.getInt(cursor.getColumnIndex(COLUMN_ID));
            String date = cursor.getString(cursor.getColumnIndex(COLUMN_DATE));
            String type = cursor.getString(cursor.getColumnIndex(COLUMN_TYPE));
            float money = cursor.getFloat(cursor.getColumnIndex(COLUMN_MONEY));
            String state = cursor.getString(cursor.getColumnIndex(COLUMN_STATE));

            Map<String, String> map = new HashMap<String, String>();
            map.put("id", String.valueOf(id));
            map.put("date", date);
            map.put("type", type);
            map.put("money", String.valueOf(money));
            map.put("state", state);
            list.add(map);
        }

        //創建SimpleAdapter
        SimpleAdapter simpleAdapter = new SimpleAdapter(getApplicationContext(),
                list,
                R.layout.record_item_layout,
                new String[]{"id", "date", "type", "money", "state"},
                new int[]{R.id.list_id, R.id.list_date, R.id.list_type, R.id.list_money, R.id.list_state});
        final ListView listView = findViewById(R.id.recordlistview);
        //系結配接器
        listView.setAdapter(simpleAdapter);
        //設定ListView單擊事件
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                ListView tempList = (ListView) parent;


                View mView = tempList.getChildAt(position);
                TextView list_id = mView.findViewById(R.id.list_id);
                TextView list_date = mView.findViewById(R.id.list_date);
                TextView list_type = mView.findViewById(R.id.list_type);
                TextView list_money = mView.findViewById(R.id.list_money);
                TextView list_state = mView.findViewById(R.id.list_state);

                String rid = list_id.getText().toString();
                String date = list_date.getText().toString();
                String type = list_type.getText().toString();
                String money = list_money.getText().toString();
                String state = list_state.getText().toString();

                tv_test.setText(rid);
                edt_date.setText(date);
                edt_type.setText(type);
                edt_money.setText(money);
                edt_state.setText(state);
                selectId = Integer.parseInt(rid);
            }
        });
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_manage);
        try {
            sqLiteDatabase = openOrCreateDatabase(DATABASE_NAME, MODE_PRIVATE, null);
            sqLiteDatabase.execSQL(CREATE_TABLE);
            //執行查詢
            selectData();
        } catch (SQLException e) {
            Toast.makeText(this, "資料庫例外!", Toast.LENGTH_LONG).show();
            e.printStackTrace();
        }
        tv_test = findViewById(R.id.tv_test);
        edt_date = findViewById(R.id.edt_date);
        edt_type = findViewById(R.id.edt_type);
        edt_money = findViewById(R.id.edt_money);
        edt_state = findViewById(R.id.edt_state);

        //新增按鍵
        Button btn_add = findViewById(R.id.btn_add);
        btn_add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (edt_date.getText().toString().equals("") | edt_type.getText().toString().equals("") | edt_money.getText().toString().equals("") | edt_state.getText().toString().equals("")) {
                    Toast.makeText(ManageActivity.this, "資料不能為空!", Toast.LENGTH_LONG).show();
                    return;
                }

                String date = edt_date.getText().toString();
                String type = edt_type.getText().toString();
                String money = edt_money.getText().toString();
                String state = edt_state.getText().toString();
                //定義添加資料的sql陳述句
                String sql = "insert into " + TABLE_NAME + "(" + COLUMN_DATE + "," + COLUMN_TYPE + "," + COLUMN_MONEY + "," + COLUMN_STATE + ") " +
                        "values('" + date + "','" + type + "','" + money + "','" + state + "')";
                //執行sql陳述句
                sqLiteDatabase.execSQL(sql);
                Toast.makeText(getApplicationContext(), "新增資料成功!", Toast.LENGTH_LONG).show();
                //重繪顯示串列
                selectData();

                //消除資料
                tv_test.setText("");
                edt_date.setText("");
                edt_type.setText("");
                edt_money.setText("");
                edt_state.setText("");
            }
        });

        //修改按鍵
        Button btn_update = findViewById(R.id.btn_update);
        btn_update.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //無選擇提示
                if (selectId == -1) {
                    Toast.makeText(getApplicationContext(), "請選擇要修改的行!", Toast.LENGTH_LONG).show();
                    return;
                }
                //判斷是否有空資料
                if (edt_date.getText().toString().equals("") | edt_type.getText().toString().equals("") | edt_money.getText().toString().equals("") | edt_state.getText().toString().equals("")) {
                    Toast.makeText(getApplicationContext(), "資料不能為空!", Toast.LENGTH_LONG).show();
                    return;
                }

                String date = edt_date.getText().toString();
                String type = edt_type.getText().toString();
                String money = edt_money.getText().toString();
                String state = edt_state.getText().toString();
                //定義修改資料的sql陳述句
                String sql = "update " + TABLE_NAME + " set " + COLUMN_DATE + "='" + date + "',type='" + type + "',money='" + money + "',state='" + state + "' where id=" + selectId;
                //執行sql陳述句
                sqLiteDatabase.execSQL(sql);
                Toast.makeText(getApplicationContext(), "修改資料成功!", Toast.LENGTH_LONG).show();
                //重繪顯示串列
                selectData();
                selectId = -1;
                //消除資料
                tv_test.setText("");
                edt_date.setText("");
                edt_type.setText("");
                edt_money.setText("");
                edt_state.setText("");
            }
        });
        //洗掉按鍵
        Button btn_delete = findViewById(R.id.btn_delete);
        btn_delete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //無選擇提示
                if (selectId == -1) {
                    Toast.makeText(ManageActivity.this, "請選擇要洗掉的行!", Toast.LENGTH_LONG).show();
                    return;
                }

                //定義洗掉對話框
                AlertDialog dialog = new AlertDialog.Builder(ManageActivity.this).setTitle("洗掉操作")
                        .setMessage("確定洗掉?此操作不可逆,請慎重選擇!")
                        .setPositiveButton("確定", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                //定義洗掉的sql陳述句
                                String sql = "delete from " + TABLE_NAME + " where id=" + selectId;
                                //執行sql陳述句
                                sqLiteDatabase.execSQL(sql);
                                //重繪顯示串列
                                Toast.makeText(getApplicationContext(), "洗掉資料成功!", Toast.LENGTH_LONG).show();
                                selectData();
                                selectId = -1;
                                //清除資料
                                tv_test.setText("");
                                edt_date.setText("");
                                edt_type.setText("");
                                edt_money.setText("");
                                edt_state.setText("");
                            }
                        }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {

                            }
                        }).create();
                dialog.show();
            }
        });
    }
}

(7)User類

User 類是用戶類Activity,用于獲取用戶ID以及密碼,具體代碼實作如下:

package com.financial.management;
import android.os.Parcel;
import android.os.Parcelable;

public class User implements Parcelable {
    private String userId="";
    private String userPwd="";
    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getUserPwd() {
        return userPwd;
    }

    public void setUserPwd(String userPwd) {
        this.userPwd = userPwd;
    }



    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.userId);
        dest.writeString(this.userPwd);
    }

    public User() {
    }

    protected User(Parcel in) {
        this.userId = in.readString();
        this.userPwd = in.readString();
    }

    public static final Creator<User> CREATOR = new Creator<User>() {
        @Override
        public User createFromParcel(Parcel source) {
            return new User(source);
        }

        @Override
        public User[] newArray(int size) {
            return new User[size];
        }
    };
}

🎵三、運行結果Result

到這里,整個系統的設計就差不多要結束啦!現在我們用一段視頻來演示整個系統的運行效果🌈

<iframe id="G1g5pVZJ-1626512791305" src="https://live.csdn.net/v/embed/170699" allowfullscreen="true" data-mediaembed="csdn"></iframe>

📈四、結束語

在拿到這個課題呢,周一首先對課題進行了系統結構設計,結構設計完成之后就到了編碼階段,編碼階段分為兩部分進行,先是進行靜態頁面的楷模,而后到了業務邏輯的撰寫,

講到這里,整個系統從設計階段到編碼階段的整個程序講解就結束啦!這也算是我學習Android的第一個小作品,作品不完美之處較多,后續還將會繼續改進~

本文代碼已上傳至github,戳此鏈接可下載代碼~

🐣彩蛋 One More Thing

(:不合理設計

  • 年月份資料寫的太固定了,沒有可擴展性
  • 日期應該用日期選擇器來做,而不應該是以文本的形式
  • 收入和支出應該以單選框來進行選擇,而不應該是文本的形式
  • ……

(:番外篇

  • 關注公眾號星期一研究室,第一時間關注學習干貨,更多精選專欄待你解鎖~
  • 如果這篇文章對你有用,記得留個腳印jio再走哦~
  • 以上就是本文的全部內容!我們下期見!👋👋👋

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/289331.html

標籤:其他

上一篇:Flutter Android 工程結構及應用層編譯原始碼深入分析

下一篇:今天干了兩件大事!

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more