카테고리 없음

(Android) KIS OpenAPI 일자별 주가 가져오기 - ItemClickListener (2)

herbtonic 2025. 2. 1. 10:05

지난 포스트에서 DayPriceActivity 및 Layout 생성 작업까지 진행했습니다. 이번 Post에서는 나머지 작업을 진행합니다. 일자별 주가 또한 RecyclerView에 담을 것이기 때문에 Main에서 진행했던 부분의 반복작업이라고 보시면 됩니다.

 

1. RecyclerView UI

Layout -> New -> Layout Resource File을 클릭하여 New Resource File Dialog에서 Name을 list_dayprice라고 입력하여 생성해 줍니다. 

주식현재가 일자별[v1_국내주식-010] API Json Output을 살펴보면 아래와 같이 나옵니다.

{
  "output": [
    {
      "stck_bsop_date": "20220111",
      "stck_oprc": "125500",
      "stck_hgpr": "128500",
      "stck_lwpr": "124500",
      "stck_clpr": "128000",
      "acml_vol": "3908418",
      "prdy_vrss_vol_rate": "13.31",
      "prdy_vrss": "3500",
      "prdy_vrss_sign": "2",
      "prdy_ctrt": "2.81",
      "hts_frgn_ehrt": "49.39",
      "frgn_ntby_qty": "0",
      "flng_cls_code": "00",
      "acml_prtt_rate": "1.00"
    },
    {
      "stck_bsop_date": "20220110",
      "stck_oprc": "126500",
      "stck_hgpr": "127000",
      "stck_lwpr": "123000",
      "stck_clpr": "124500",
      "acml_vol": "3449197",
      "prdy_vrss_vol_rate": "5.48",
      "prdy_vrss": "-2500",
      "prdy_vrss_sign": "5",
      "prdy_ctrt": "-1.97",
      "hts_frgn_ehrt": "49.39",
      "frgn_ntby_qty": "293389",
      "flng_cls_code": "00",
      "acml_prtt_rate": "0.00"
    }
  ],
  "rt_cd": "0",
  "msg_cd": "MCA00000",
  "msg1": "정상처리 되었습니다!"
}

 

 

우리는 여기서 거래일자, 종가, 전일대비, 등락률, 거래량만을 취할 것이므로, list_dayprice에 다음 코드를 복사해 넣습니다.

<?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="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_margin="0dp"
    app:cardCornerRadius="3dp"
    app:cardElevation="3dp"
    android:padding="8dp">
    <TableLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="5dp"
        android:stretchColumns="*">
        <TableRow>
            <TextView
                android:id="@+id/priceDate"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:text="일자"
                android:textSize="13sp"
                />
            <TextView
                android:id="@+id/currentPrice"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:text="현재가"
                android:textSize="13sp"
                android:gravity="right"
                />

            <TextView
                android:id="@+id/changePrice"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:text="대비"
                android:textSize="13sp"
                android:gravity="right"
                />
            <TextView
                android:id="@+id/changePercent"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:text="Percent"
                android:textSize="13sp"
                android:gravity="center"
                android:textColor="@color/red"
                />
            <TextView
                android:id="@+id/volume"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:text="거래량"
                android:textSize="13sp"
                android:gravity="right"
                />
        </TableRow>
    </TableLayout>
</LinearLayout>

 

2. 주식현재가 일자별[v1_국내주식-010]  관련 Class 작성

 

1) DayPriceRoot Class

    국내주식 등락률 순위 에서 살펴본 것과 같이 동일한 구조이므로, DayPrice의 부모 Class를 아래와 같이 정의해 줍니다.

package com.example.megabomb;

import com.google.gson.annotations.SerializedName;

import java.util.ArrayList;

public class DayPriceRoot {
    @SerializedName("output")
    private ArrayList<DayPrice> output;

    public DayPriceRoot(ArrayList<DayPrice> output) {
        this.output = output;
    }

    public ArrayList<DayPrice> getOutput() {
        return output;
    }
}

 

2) DayPrice Class

 

거래일자, 종가, 전일대비, 등락률, 거래량 Object가 포함된 DayPrice Class를 작성합니다.

package com.example.megabomb;
import com.google.gson.annotations.SerializedName;

public class DayPrice {
    @SerializedName("stck_bsop_date")
    private String stck_bsop_date;
    @SerializedName("stck_clpr")
    private String stck_clpr;
    @SerializedName("acml_vol")
    private String acml_vol;
    @SerializedName("prdy_vrss")
    private String prdy_vrss;
    @SerializedName("prdy_vrss_sign")
    private String prdy_vrss_sign;
    @SerializedName("prdy_ctrt")
    private String prdy_ctrt;

    public DayPrice(String stck_bsop_date, String stck_clpr, String acml_vol, String prdy_vrss, String prdy_vrss_sign, String prdy_ctrt) {
        this.stck_bsop_date = stck_bsop_date;
        this.stck_clpr = stck_clpr;
        this.acml_vol = acml_vol;
        this.prdy_vrss = prdy_vrss;
        this.prdy_vrss_sign = prdy_vrss_sign;
        this.prdy_ctrt = prdy_ctrt;
    }

    public String getStck_bsop_date() {
        return stck_bsop_date;
    }

    public String getStck_clpr() {
        return stck_clpr;
    }

    public String getAcml_vol() {
        return acml_vol;
    }

    public String getPrdy_vrss() {
        return prdy_vrss;
    }

    public String getPrdy_vrss_sign() {
        return prdy_vrss_sign;
    }

    public String getPrdy_ctrt() {
        return prdy_ctrt;
    }
}

 

3) DayPriceAdapter Class

 

일자별 주가를 RecyclerView에 담을 DayPriceAdaper Class를 작성합니다. onBindViewHolder Method에서 주가 등락에 따라 글자 색상을 바꿔줍니다. (상승시 빨간색, 하락 시 파란색)

package com.example.megabomb;

import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;

public class DayPriceAdapter extends RecyclerView.Adapter<DayPriceAdapter.ViewHolder> {
    private List<DayPrice> dayPriceList;
    public DayPriceAdapter(List<DayPrice> dayPriceList) {
        this.dayPriceList = dayPriceList;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.list_dayprice, parent, false);
        return new ViewHolder(view);

    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        holder.priceDate.setText(dayPriceList.get(position).getStck_bsop_date());
        holder.currentPrice.setText(String.format("%,d", Integer.parseInt(dayPriceList.get(position).getStck_clpr())));
        int chPrice = Integer.parseInt(dayPriceList.get(position).getPrdy_vrss());
        if (chPrice == 0) {
            holder.changePrice.setTextColor(Color.parseColor("#FF000000"));
            holder.currentPrice.setTextColor(Color.parseColor("#FF000000"));
        }
        else if (chPrice > 0) {
            holder.changePrice.setTextColor(Color.parseColor("#F44336"));
            holder.currentPrice.setTextColor(Color.parseColor("#F44336"));
        }
        else if (chPrice < 0) {
            holder.changePrice.setTextColor(Color.parseColor("#365FF4"));
            holder.currentPrice.setTextColor(Color.parseColor("#365FF4"));
        }
        holder.changePrice.setText(String.format("%,d",Integer.parseInt(dayPriceList.get(position).getPrdy_vrss())));
        Float chPercent = Float.parseFloat(dayPriceList.get(position).getPrdy_ctrt());
        if (chPercent == 0) {
            holder.changePercent.setTextColor(Color.parseColor("#FF000000"));
        }
        else if (chPercent > 0) {
            holder.changePercent.setTextColor(Color.parseColor("#F44336"));
        }
        else if (chPercent < 0) {
            holder.changePercent.setTextColor(Color.parseColor("#365FF4"));
        }

        holder.changePercent.setText(dayPriceList.get(position).getPrdy_ctrt());
//        holder.sign.setText(dayPriceList.get(position).getPrdy_vrss_sign());
        holder.volume.setText(String.format("%,d",Integer.parseInt(dayPriceList.get(position).getAcml_vol())));
    }

    @Override
    public int getItemCount() {
        return dayPriceList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        TextView priceDate;
        TextView currentPrice;
        TextView changePrice;
        //      TextView sign;
        TextView changePercent;
        TextView volume;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            priceDate = itemView.findViewById(R.id.priceDate);
            currentPrice = itemView.findViewById(R.id.currentPrice);
            changePrice = itemView.findViewById(R.id.changePrice);
            //           sign = itemView.findViewById(R.id.sign);
            changePercent = itemView.findViewById(R.id.changePercent);
            volume = itemView.findViewById(R.id.volume);
        }
    }
}

 

4) ApiInterface에 일자별 주가 Request 추가

    아래와 같이 일자별 주가 @GET 요청을 추가해 줍니다.

public interface ApiInterface {
    @GET("/uapi/domestic-stock/v1/ranking/fluctuation")
    Call<Ranking> getStocks(@HeaderMap Map<String, String> headers,
                            @QueryMap Map<String, String> map
    );
    @GET("/uapi/domestic-stock/v1/quotations/inquire-daily-price")
    Call<DayPriceRoot> getDayliPrice(@HeaderMap Map<String, String> headers,
                                     @QueryMap Map<String, String> map
    );
}