(Android Step by Step) 한투 OpenAPI 나스닥 실시간 시세 (2)
제가 올리는 글을 누가 읽을까 했는데, 그래도 많은 분들이 찾아주시고, 관심 가져 주셔서 감사합니다. 제가 좀 게을러서 후속 글을 너무 늦게 올려서 미안합니다. 많은 공감과 댓글이 글쓰는이에게 큰 힘이 됩니다. ㅎㅎ
이제 지난 포스트에 이어서 SQLite DatabaseHelper Class를 작성할 거예요. SQLite는 Android에 기본적을 내장된 경량 Database입니다. SQLite를 호출하기 위해서는 SQLiteOpenHelper를 상속받아서 DataBaseHelper를 작성해주면 됩니다.
DataBaseHelper Class 기본 틀만 예를 들어 보면, 먼저 설계한 DB, Table, Table 컬럼을 companion object에 정의해줍니다. 그 다음 OnCreate를 통해 Table을 만들어 주고, Table 속성의 추가, 변경 시 OnUpgrade에서 처리해 주도록 구현합니다. 그 이후 Insert, Update, Delete Function을 필요에 따라 추가해 주면 됩니다.
package com.example.peppermint.Database
import android.content.ContentValues
import android.content.Context
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.util.Log
class DatabaseHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
companion object {
private const val DATABASE_NAME = "OverseaStockDB"
private const val DATABASE_VERSION = 1
private const val TABLE_NAME = "stockitems"
private const val COLUMN_ID = "id"
private const val COLUMN_NAME = "name"
private const val COLUMN_SYMBOL = "symbol"
private const val COLUMN_CODE = "code"
private const val COLUMN_PRICE = "price"
private const val COLUMN_CHANGEPRICE = "changeprice"
private const val COLUMN_CHANGEPERCENT = "changepercent"
private const val COLUMN_VOLUME = "volume"
private const val COLUMN_IS_CHECKED = "isChecked"
}
override fun onCreate(db: SQLiteDatabase) {
val createTableQuery = "CREATE TABLE $TABLE_NAME ($COLUMN_ID INTEGER PRIMARY KEY AUTOINCREMENT, $COLUMN_NAME TEXT, $COLUMN_SYMBOL TEXT, $COLUMN_CODE TEXT, $COLUMN_PRICE REAL, $COLUMN_CHANGEPRICE REAL, $COLUMN_CHANGEPERCENT REAL, $COLUMN_VOLUME INTEGER, $COLUMN_IS_CHECKED INTEGER DEFAULT 0)"
db.execSQL(createTableQuery)
}
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
db.execSQL("DROP TABLE IF EXISTS $TABLE_NAME")
onCreate(db)
}
}
이렇게 해서 나스닥 종목을 DB Table에 저장할 준비를 마쳤습니다.
III. Layout 작성
1. activity_main layout
main activity에서는 실시간 시세를 받아올 나스닥 종목 리스트를 보여주기 위한 RecyclerView를 만들어 줍니다. 또 추가할 나스닥 종목 입력창 (activity_add_stock)을 호출하기 위해 아래 floating action button을 만들어 줍니다.
Top Menu 및 icon 만드는 방법은 이전 포스트를 참고하시면 됩니다. 작성된 activity_main Layout은 아래와 같습니다.
<?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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="20dp"
tools:context=".MainActivity">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="@menu/top_menu"
app:navigationIcon="@drawable/ic_app"
app:title="MegaBomb" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="4dp"
android:layout_marginTop="65dp"
app:layout_constraintStart_toStartOf="@id/toolbar"
app:layout_constraintTop_toTopOf="@id/toolbar" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/addButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="24dp"
android:layout_marginBottom="44dp"
android:clickable="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:srcCompat="@drawable/ic_add" />
</androidx.constraintlayout.widget.ConstraintLayout>
2. stock_item Layout
RecyclerView에서 나열되는 나스닥 종목 아이템의 화면을 만들어 줍니다. 종목명, 현재가, 전일댑, 등락율, 거래량 정보를 표시하도록 합니다.
stock_item xml은 아래와 같습니다.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardCornerRadius="3dp"
app:cardElevation="3dp"
android:padding="1dp">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="54dp">
<TextView
android:id="@+id/stockName"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:text="StockName"
android:textSize="20sp"
android:layout_marginTop="2dp"
android:layout_marginLeft="4dp"/>
<TextView
android:id="@+id/stockPrice"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:gravity="right"
android:text="현재가"
android:layout_marginLeft="170dp"
android:textSize="18sp"
android:textStyle="bold"
android:layout_marginTop="2dp"/>
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="290dp"
app:srcCompat="@drawable/ic_arrow_up"
tools:layout_editor_absoluteX="141dp"
android:layout_marginTop="2dp"/>
<TextView
android:id="@+id/changePrice"
android:layout_width="90dp"
android:layout_height="wrap_content"
android:text="대비"
android:textStyle="bold"
android:layout_marginLeft="300dp"
android:textSize="18sp"
android:gravity="right"
android:layout_marginTop="2dp"/>
<TextView
android:id="@+id/volume"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="거래량"
android:layout_marginTop="30dp"
android:layout_marginLeft="150dp"
android:textSize="15sp"
android:gravity="right"/>
<TextView
android:id="@+id/changePercent"
android:layout_width="90dp"
android:layout_height="wrap_content"
android:text="Percent"
android:layout_marginTop="30dp"
android:layout_marginLeft="300dp"
android:textSize="15sp"
android:gravity="right"
android:textColor="@color/red"/>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
3. activity_add_stock Layout
이번에는 실시간 시세를 조회할 종목을 입력할 수 있는 입력창을 아래와 같이 준비합니다. 입력란에는 이전 포스트에서 기술한 대로 코드 규칙을 반영합니다. 다만 EditText 입력란을 깔끔하게 처리하기 위해서 drawable에 border를 만들어서 적용해 줍니다.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="1dp"
android:color="@color/navyblue"/>
<corners
android:radius="4dp"/>
<padding android:left="10dp"/>
</shape>
activity_add_stock Layout의 완성된 코드는 아래와 같습니다.
<?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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".AddStockActivity">
<EditText
android:id="@+id/stockName"
android:layout_width="320dp"
android:layout_height="50dp"
android:layout_marginTop="156dp"
android:background="@drawable/navyblue_border"
android:ems="10"
android:inputType="text"
android:hint=" 종목명"
android:privateImeOptions="defaultInputmode=korean"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/stockSymbol"
android:layout_width="320dp"
android:layout_height="50dp"
android:layout_marginTop="56dp"
android:background="@drawable/navyblue_border"
android:ems="10"
android:inputType="text"
android:hint=" Symbol "
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.505"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/stockName" />
<EditText
android:id="@+id/stockCode"
android:layout_width="320dp"
android:layout_height="50dp"
android:layout_marginTop="52dp"
android:ems="10"
android:inputType="text"
android:hint=" 거래소명종목코드(ex. D + NAS + AAPL)"
android:background="@drawable/navyblue_border"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.503"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/stockSymbol" />
<Button
android:id="@+id/addStockButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add Stock"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/stockCode"
app:layout_constraintVertical_bias="0.18" />
</androidx.constraintlayout.widget.ConstraintLayout>