Skip to content

Latest commit

ย 

History

History
705 lines (532 loc) ยท 23.5 KB

README.md

File metadata and controls

705 lines (532 loc) ยท 23.5 KB

InventoryBox_Android

๐Ÿฆ–android github๐Ÿฆ– https://github.com/InventoryBox/InventoryBox_Android

์žฌ๊ณ ์ฐฝ๊ณ 

๊ฐœ์ธ ์™ธ์‹ ์‚ฌ์—…์ž๋ฅผ ์œ„ํ•œ ์žฌ๊ณ ๊ด€๋ฆฌ Application ๐Ÿ“ฆ

'๋‚˜๋งŒ์˜ ๋‹ค์ด์–ด๋ฆฌ๋ฅผ ๊ด€๋ฆฌํ•˜๋“ฏ ๋งค์ผ๋งค์ผ ์‰ฝ๊ฒŒ ๊ธฐ๋กํ•˜๊ณ  ์„ฑ์žฅํ•  ์ˆ˜ ์žˆ๋Š” ์žฌ๊ณ ๊ด€๋ฆฌ ํ”Œ๋žซํผ', ์žฌ๊ณ ์ฐฝ๊ณ ์ž…๋‹ˆ๋‹ค.
๋ฐœ์ฃผ์‹œ์ ์„ ๋†“์น˜์ง€ ์•Š๊ฒŒ ๋„์™€์ฃผ๋Š” ๋ฐœ์ฃผ ์•Œ๋ฆผ ๊ธฐ๋Šฅ, ๋ฐ์ดํ„ฐ๋ฅผ ์‰ฝ๊ฒŒ ์ถ•์ ํ•  ์ˆ˜ ์žˆ๋Š” ์žฌ๊ณ  ๊ธฐ๋ก ๊ธฐ๋Šฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ๏ผŒ์žฌ๊ณ ๊ตํ™˜ ๊ธฐ๋Šฅ์„ ํ†ตํ•ด ์žฌ๊ณ ๊ฐ€ ๋–จ์–ด์ง€๋Š” ๊ฐ‘์ž‘์Šค๋Ÿฌ์šด ์ƒํ™ฉ์—๋„ ๊ฐœ์ธ ์‚ฌ์—…์ž๋“ค๊ฐ„ ๋„คํŠธ์›Œํฌ ํ˜•์„ฑ์„ ํ†ตํ•ด ์žฌ๊ณ ๋ฅผ ๋ณด์ถฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Project

  • SOPT 26th APPJAM
  • ํ”„๋กœ์ ํŠธ ๊ธฐ๊ฐ„: 2020.06.13 ~ 2020.07.18


๊ฐœ๋ฐœ ํ™˜๊ฒฝ

* Android Studio, kotlin

์‚ฌ์šฉ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

    //Retrofit ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
    implementation 'com.squareup.retrofit2:retrofit:2.6.2'
    //Retrofit ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‘๋‹ต์œผ๋กœ ๊ฐ€์งœ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด
    implementation 'com.squareup.retrofit2:retrofit-mock:2.6.2'

    //๊ฐ์ฒด ์‹œ๋ฆฌ์–ผ๋ผ์ด์ฆˆ๋ฅผ ์œ„ํ•œ Gson ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
    implementation 'com.google.code.gson:gson:2.8.6'
    //Retrofit ์—์„œ Gson ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
    implementation 'com.squareup.retrofit2:converter-gson:2.6.2'

    //๋ฐฐ๊ฒฝ์ด ๋™๊ทธ๋ž€ ์ด๋ฏธ์ง€๋ทฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
    implementation 'de.hdodenhof:circleimageview:3.1.0'

    //stickyscrollview ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
    implementation 'com.github.didikk:sticky-nestedscrollview:1.0.1'

    //expandable layout
    implementation 'net.cachapa.expandablelayout:expandablelayout:2.9.2'

    // mpandroidchart ๋ง‰๋Œ€ ์ฐจํŠธ
    implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'

    //wheel picker datepicker
    implementation 'com.super_rabbit.wheel_picker:NumberPicker:1.0.1'

    //kakao ์ง€๋„ ๊ฒ€์ƒ‰ api ์ด์šฉ์„ ์œ„ํ•œ ๋ชจ๋“ˆ
    implementation "com.kakao.sdk:v2-user-rx:2.0.0-beta02"
    implementation "com.kakao.sdk:v2-talk-rx:2.0.0-beta02"
    implementation "com.kakao.sdk:v2-story-rx:2.0.0-beta02"
    implementation "com.kakao.sdk:v2-link-rx:2.0.0-beta02"
    implementation "com.kakao.sdk:v2-navi:2.0.0-beta02"

๊ธฐ๋Šฅ ์†Œ๊ฐœ

๊ธฐ๋Šฅ ์ƒ์„ธ ๊ธฐ๋Šฅ ๋‹ด๋‹น
์Šคํ”Œ๋ ˆ์‹œ ์Šคํ”Œ๋ ˆ์‹œ ํ™”๋ฉด ์ „์„ฑ์€
๋กœ๊ทธ์ธ ๋กœ๊ทธ์ธ ์ „์„ฑ์€
ํšŒ์›๊ฐ€์ž… ์ด๋ฉ”์ผ ์ธ์ฆ ์ „์„ฑ์€
ํ™ˆ ์žฌ๊ณ  ๋ชฉ๋ก ์ „์„ฑ์€
๋ฐœ์ฃผ ํ™•์ธ ์ „์„ฑ์€
์ฒดํฌ๋ฐ•์Šค ๊น€๊ฐ€์˜
๋”๋ณด๊ธฐ ์ „์„ฑ์€
๋ฉ”๋ชจ์ˆ˜์ • ์ „์„ฑ์€
Side Menu View ์ „์„ฑ์€
์žฌ๊ณ ๊ธฐ๋ก ์บ˜๋ฆฐ๋” ์ •ํ™”์ง„
Date pickerView Custom ๊น€๊ฐ€์˜
์นดํ…Œ๊ณ ๋ฆฌ ๋ถ„๋ฅ˜ ์ •ํ™”์ง„
์นดํ…Œ๊ณ ๋ฆฌ ํ•„ํ„ฐ ์ •ํ™”์ง„
์นดํ…Œ๊ณ ๋ฆฌ ์ˆ˜์ • ์ •ํ™”์ง„
์นดํ…Œ๊ณ ๋ฆฌ ์ถ”๊ฐ€ ์ •ํ™”์ง„
์žฌ๋ฃŒ ์ถ”๊ฐ€ ์ •ํ™”์ง„
์žฌ๋ฃŒ ๋ชฉ๋ก ์ •ํ™”์ง„
์นดํ…Œ๊ณ ๋ฆฌ ๋ถ„๋ฅ˜ ์ •ํ™”์ง„
Check Box ์ •ํ™”์ง„
Alert Custom ์ •ํ™”์ง„
์žฌ๊ณ ๋Ÿ‰ ์ถ”์ด ์บ˜๋ฆฐ๋” day ๋ถ„๋ฅ˜ ๊น€๊ฐ€์˜
์บ˜๋ฆฐ๋” Week ๋ถ„๋ฅ˜ ๊น€๊ฐ€์˜
์นดํ…Œ๊ณ ๋ฆฌ ์„ ํƒ ๊น€๊ฐ€์˜
์นดํ…Œ๊ณ ๋ฆฌ ํ•„ํ„ฐ ๊น€๊ฐ€์˜
Graph ๊น€๊ฐ€์˜
์บ˜๋ฆฐ๋” ๊น€๊ฐ€์˜
์žฌ๊ณ ๊ตํ™˜ ๊ฐ€๊ฒŒ ์œ„์น˜ ์„ค์ • ๊น€๊ฐ€์˜
์นดํ…Œ๊ณ ๋ฆฌ ๊น€๊ฐ€์˜
๊ฒŒ์‹œ๊ธ€ ์ •๋ ฌ ๊น€๊ฐ€์˜
๊ฒŒ์‹œ๊ธ€ ์ƒ์„ธ ๊น€๊ฐ€์˜
๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก ๊น€๊ฐ€์˜

ํ”„๋กœ๊ทธ๋žจ ๊ตฌ์กฐ

package ๋ถ„๋ฅ˜

ํ”„๋กœ๊ทธ๋žจ ๊ตฌ์กฐ๋Š” ํฌ๊ฒŒ activity, adapter, data, db, fragment, graph, network, viewholder, etc ๋กœ ๋ถ„๋ฅ˜ํ–ˆ๋‹ค. network์—๋Š” ์‹ฑ๊ธ€ํ†ค์ธ RequestToServer, interface์ธ NetworkService, kotlin ํ™•์žฅํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•œ customEnqueue๊ฐ€ ์žˆ์œผ๋ฉฐ GET, POST, PUT์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋ถ„๋ฅ˜ํ–ˆ๋‹ค. graph ํŒจํ‚ค์ง€๋Š” ๋‹ค์–‘ํ•œ ์ข…๋ฅ˜์˜ ๊ทธ๋ž˜ํ”„๋ฅผ ์œ„ํ•œ ํ™•์žฅํ•จ์ˆ˜๋“ค๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค. db ํŒจํ‚ค์ง€์—๋Š” ์œ ์ € ์ •๋ณด ์ €์žฅ์„ ์œ„ํ•œ SharedPreferenceController๊ฐ€ ๋“ค์–ด์žˆ๋‹ค. etc ํŒจํ‚ค์ง€์—๋Š” datepicker, recyclerview decoration ๋“ฑ ๋‹ค์–‘ํ•œ custom์„ ์œ„ํ•œ ํด๋ž˜์Šค์™€ ํ™•์žฅ ํ•จ์ˆ˜๋“ค์ด ์žˆ๋‹ค.

ํ•ต์‹ฌ ๊ธฐ๋Šฅ ๊ตฌํ˜„ ๋ฐฉ๋ฒ• ๋ฐ ๊ตฌํ˜„ ํ™”๋ฉด

<ํ™ˆ>

์ฒดํฌ๋ฐ•์Šค - onHomeCheckLister๋ฅผ ์ด์šฉํ•˜์—ฌ ์ฒดํฌ๋ฐ•์Šค์™€ ์ฒดํฌ๋ฆฌ์ŠคํŠธ๋ฅผ ์—ฐ๊ฒฐ
'์ž์„ธํžˆ' ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ์ตœ๊ทผ 5์ผ์˜ ์žฌ๊ณ  ์ถ”์ด๋ฅผ ํ™•์ธ - expandable list view ์™€ MPAndroidChart ์ด์šฉ



<์žฌ๊ณ  ๊ธฐ๋ก>

WheelPicker ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ปค์Šคํ…€ ๋ฐ์ดํŠธ ํ”ผ์ปค ์ œ์ž‘


<์žฌ๊ณ ๋Ÿ‰ ์ถ”์ด>

MPAndroidChart ์ด์šฉํ•˜์—ฌ ์ฃผ๊ฐ„ ๊ทธ๋ž˜ํ”„ ๊ตฌํ˜„
MPAndroidChart ์ด์šฉํ•˜์—ฌ ๋น„๊ต ๊ทธ๋ž˜ํ”„ ๊ตฌํ˜„


<์žฌ๊ณ  ๊ตํ™˜>

Kakao API ์ด์šฉ, ์ฃผ์†Œ ๊ฒ€์ƒ‰


A-1 ConstraintLayout์„ ์‚ฌ์šฉํ•œ ํ™”๋ฉด ๊ฐœ๋ฐœ

1. match_constraint, chain, guideline ๋“ฑ constraintLayout์˜ ๋‹ค์–‘ํ•œ ์†์„ฑ ํ™œ์šฉ

๋ ˆ์ด์•„์›ƒ์„ ์งค ๋•Œ margin์œผ๋กœ ์—ฌ๋ฐฑ์„ ์ฃผ๊ธฐ๋ณด๋‹ค๋Š” constraintLayout์˜ guideline ์†์„ฑ์„ ์ด์šฉํ•˜์—ฌ ๋ทฐ๋“ค์„ guideline์— ๋งž์ถ”์—ˆ๋‹ค.
ex)


  • activity_login.xml์—์„œ guideline๊ณผ match_constraint ์ด์šฉ guideline์„ ์ด์šฉํ•˜์—ฌ ์–‘์ชฝ ์—ฌ๋ฐฑ์„ ๋งž์ถ”๊ณ  ๋ทฐ๋“ค์˜ width๋ฅผ match_constraint๋กœ ํ•˜์—ฌ guideline์— ๊ฝ‰ ์ฐจ๊ฒŒ ์ง€์ •ํ–ˆ๋‹ค.

  • activity_sign_up.xml์—์„œ match_constraint, chain, guideline ์ด์šฉ guideline์„ ์ด์šฉํ•˜์—ฌ ์–‘์ชฝ ์—ฌ๋ฐฑ์„ ๋งž์ถ”๊ณ  ๋ทฐ๋“ค์˜ width๋ฅผ match_constraint๋กœ ํ•˜์—ฌ guideline์— ๊ฝ‰ ์ฐจ๊ฒŒ ์ง€์ •ํ–ˆ๊ณ , chain์„ ์ด์šฉํ•˜์—ฌ ๊ฐ ๋ทฐ๋“ค์„ ์—ฐ๊ฒฐํ–ˆ๋‹ค.

  • activity_drawer.xml์—์„œ chain ์†์„ฑ ํ™œ์šฉ ๊ฐ ํ•ญ๋ชฉ๋“ค์„ ํ”„๋กœํ•„ constraintlayout๊ณผ chain์œผ๋กœ ์—ฐ๊ฒฐํ•˜๊ณ  Vertical chainStyle์„ packed๋กœ ์ง€์ •ํ•˜์—ฌ ๋ถ™์˜€๋‹ค.

  • activity_drawer.xml์—์„œ match_constraint ์†์„ฑ ํ™œ์šฉ ๋ ˆ์ด์•„์›ƒ์— ๊ฐ ๋ฉ”๋‰ด๋“ค์„ ๊ฝ‰ ์ฐจ๊ฒŒ ๋งž์ถ”๊ธฐ ์œ„ํ•ด ๋ชจ๋“  ๋ฉ”๋‰ด๋“ค์˜ layut_width์— 0dp๋กœ match_constraint ์†์„ฑ์„ ์ ์šฉํ–ˆ๋‹ค.

  • activity_add.xml์—์„œ guidline ์†์„ฑ ํ™œ์šฉ

  • fragment_graph_detail.xml ์—์„œ guideline ์†์„ฑ, match_constraint ์‚ฌ์šฉ

  • fragment_graph_detail.xml ์—์„œ guideline ์†์„ฑ ํ™œ์šฉ ์™ผ์ชฝ์— ๊ฐ™์€ margin ๊ฐ’์„ ์ฃผ๊ธฐ ์œ„ํ•ด guideline์„ ๋งŒ๋“  ํ›„ constraint ์ ์šฉ


2. ์ œ์•ฝ์กฐ๊ฑด์˜ ์—ฐ๊ด€์„ฑ

๋ทฐ๋ฅผ ๋ถ€๋ชจ์™€ ์—ฐ๊ด€์ง€์–ด ์—ฌ๋ฐฑ์„ ์ ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด ์•„๋‹ˆ๋ผ ๊ฐ€๊นŒ์šด ๋ทฐ์—๊ฒŒ ์ œ์•ฝ์กฐ๊ฑด์„ ๊ฑธ์–ด ์—ฌ๋ฐฑ์„ ํ†ตํ•ด ์œ„์น˜๋ฅผ ์ง€์ •ํ–ˆ๋‹ค.


3. width, height ์†์„ฑ์— match_parent, wrap_content, match_constraint ์œ„์ฃผ๋กœ ์‚ฌ์šฉ

  • textView์˜ text ๋‚ด์šฉ์— ๋”ฐ๋ผ ํฌ๊ธฐ๊ฐ€ ๋‹ฌ๋ผ์ ธ์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— width ์†์„ฑ์— wrap_content ์†์„ฑ ์œ„์ฃผ๋กœ ์‚ฌ์šฉ ex) ์‚ฌ์šฉ์ž ์ด๋ฆ„, ์ฃผ์†Œ, ๋‚ ์งœ, ๋ฐœ์ฃผ ํ™•์ธ ๋ชฉ๋ก ๋“ฑ
  • activity_drawer.xml์— match_constraint๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ ˆ์ด์•„์›ƒ์— ๊ฐ ๋ฉ”๋‰ด๋“ค์„ ๊ฝ‰ ์ฐจ๊ฒŒ ์ง€์ •
  • ํšŒ์›๊ฐ€์ž…, ๋กœ๊ทธ์ธ ๋ทฐ์—์„œ match_constraint๋ฅผ ํ™œ์šฉํ•˜์—ฌ guideline์— ๊ฐ editText ๋ทฐ๋“ค์„ ๊ฝ‰ ์ฐจ๊ฒŒ ์ง€์ •

A-2 kotlin collection์˜ ํ™•์žฅํ•จ์ˆ˜ ์‚ฌ์šฉ / custom ํ™•์žฅ ํ•จ์ˆ˜ ์‚ฌ์šฉ

kotlin collection์˜ ํ™•์žฅํ•จ์ˆ˜ ์‚ฌ์šฉ

map

GraphFragment ์—์„œ category์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ’๋“ค์„ ์ƒˆ๋กœ์šด arrayList์— ๋„ฃ์–ด adapter ์— ๋ฐ˜์˜ํ•ด์ฃผ๊ธฐ

if(category_idx>1){  
  sorted_datas_graph = datas_graph.filter {  
  it.categoryIdx==category_idx  
    }.toMutableList()
graph_adapter.datas = sorted_datas_graph
graph_adapter.notifyDataSetChanged()

ExchangeFoodFragment, ExchangeProductFragment ์—์„œ ํ•ด๋‹นํ•˜๋Š” data ๋“ค๋งŒ ๋„ฃ์–ด์ฃผ๊ธฐ

for(data in it.data.postInfo){  
  datas.add(data)  
}  
val sorted : MutableList<PostInfo> = datas.filter {data->  
  data.isFood==1  
}.toMutableList()  
exchangeRVAdapter.datas=sorted  
exchangeRVAdapter.notifyDataSetChanged()
' ' 



### custom ํ™•์žฅ ํ•จ์ˆ˜ ์‚ฌ์šฉ
#### customEnqueue

kotlin extension์„ ์ด์šฉํ•œ ๋ฉ”์†Œ๋“œ๋ฅผ ์ ์šฉํ•˜์˜€๋‹ค. ํ†ต์‹  ๋ถ€๋ถ„๋งˆ๋‹ค customEnqueue ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ฐ˜๋ณต๋˜๋Š” ์š”์†Œ๋“ค์„ ์ค„์ผ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

```kotlin
fun<ResponseType> Call<ResponseType>.customEnqueue(
    onFail:()-> Unit={ Log.d("network", "ํ†ต์‹  ์‹คํŒจ")},
    onSuccess:(ResponseType)->Unit,
    onError:()->Unit={}
){
    this.enqueue(object: Callback<ResponseType> {
        override fun onFailure(call: Call<ResponseType>, t: Throwable){
            onFail()
            Log.d("network", t.message)
        }

        override fun onResponse(call: Call<ResponseType>, response: Response<ResponseType>){
            response.body()?.let{
                onSuccess(it)
            }?:onError()
            Log.d("network", response.message())
            Log.d("network", response.code().toString())
        }
    })
}

getColorFromRes

// color res id๋กœ๋ถ€ํ„ฐ color ๊ฐ’ ๋ฐ˜ํ™˜
fun Context.getColorFromRes(color:Int):Int{
    return ContextCompat.getColor(this, color)
}

draw5DaysGraph

// datas : ์ตœ๊ทผ 5์ผ ์žฌ๊ณ ๋Ÿ‰ int arraylist
// day : ๋งˆ์ง€๋ง‰ ์žฌ๊ณ ๋Ÿ‰์˜ ์š”์ผ - ์ผ์š”์ผ(0) ~ ํ† ์š”์ผ(6)
fun BarChart.draw5DaysGraph(context: Context, datas : ArrayList<Int>, day : Int, count_noti:Int) {

    this.setTouchEnabled(false)
    datas.add(0,-1)
    datas.add(0,-1)

    var data : BarData = createChartData(context, datas,count_noti)
    configureChartAppearance( this,context, day)
    prepareChartData(context, this, data)

    //bar ์œ„์— value ์œ„์น˜ํ•˜๋„
    this.setDrawValueAboveBar(true)
    //์•Œ๋ฆผ ๊ฐœ์ˆ˜ ๋ผ์ธ ๊ทธ๋ฆฌ๊ธฐ
    if(count_noti != -1){
        drawAxisLine(context, this, count_noti)
    }
}

// num์— ํ•ด๋‹นํ•˜๋Š” value์˜ ์ˆ˜ํ‰์„  ๊ทธ๋ฆฐ
private fun drawAxisLine(context: Context, barchart : BarChart, num : Int) {
    val line : LimitLine = LimitLine(num.toFloat(), "๋ฐœ์ฃผ ์•Œ๋ฆผ ๊ฐœ์ˆ˜ $num")
    barchart.axisLeft.addLimitLine(line)
    line.lineColor= context.getColorFromRes(R.color.yellow)
    line.labelPosition = LimitLine.LimitLabelPosition.LEFT_TOP
    line.lineWidth=1f
    line.textColor = context.getColorFromRes(R.color.yellow)
    line.typeface = ResourcesCompat.getFont(context, R.font.nanum_square_extra_bold )
    line.textSize = 12f
    // y ์ถ•์œผ๋กœ๋ถ€ํ„ฐ ๊ฑฐ๋ฆฌ ์„ค์ •
    line.yOffset=3f
//    line.xOffset=-10f
//    barchart.animateX(2000)
//    barchart.animateY(2000)

}

// ๋ฐ์ดํ„ฐ ๋ฐ›์•„์„œ๋‹ค
private fun prepareChartData(context: Context, barchart : BarChart, data: BarData) {
    //value text size ์„ค์ •
    data.setValueTextSize(12f)
    // text color ์„ค
    data.setValueTextColor(context.getColorFromRes(R.color.darkgrey))
    barchart.data=data
    barchart.invalidate()
}

// BarData๋งŒ๋“ค๊ธฐ
private fun createChartData(context: Context, datas :ArrayList<Int>, count_noti: Int): BarData {
    val values: ArrayList<BarEntry> = ArrayList()

    for (i in 0..6){
        values.add(BarEntry(i.toFloat(), datas.get(i).toFloat()))
    }

    val set = CustomBarDataSet(values, "SET_LABEL",count_noti)
    set.colors=
            //listOf(ContextCompat.getColor(this,R.color.yellow),ContextCompat.getColor(this, R.color.gray))
        listOf(context.getColorFromRes(R.color.yellow), context.getColorFromRes(R.color.middlegrey))
    val dataSets = ArrayList<IBarDataSet>()
    dataSets.add(set)



    val data: BarData = BarData(dataSets)
    //value๊ฐ’์„ int๋กœ
    data.setValueFormatter(object: ValueFormatter(){
        override fun getFormattedValue(value: Float): String {
            return if(value>=0) Math.round(value).toString() else "".toString()
        }
    })
    data.setValueTypeface(ResourcesCompat.getFont(context, R.font.nanum_square_extra_bold))

    //๋ง‰๋Œ€ ๋„ˆ๋น„ ์ˆ˜์ •
    data.barWidth=0.2f

    return data
}

//chart ๊ฐ€ ์–ด๋–ป๊ฐ€ ๋ณด์—ฌ์งˆ์ง€
//day ๋Š” ๋งˆ์ง€๋ง‰ ๋ฐ์ดํ„ฐ์˜ ์š”์ผ
private fun configureChartAppearance(barchart : BarChart, context: Context, day: Int) {


    val DAYS = arrayListOf<String>("์ผ","์›”","ํ™”","์ˆ˜","๋ชฉ","๊ธˆ","ํ† ","์ผ","์›”","ํ™”","์ˆ˜","๋ชฉ","๊ธˆ","ํ† ")
    val first_day  = if(day-4>=0) day-4 else day+3


//    Log.d("testtest","firstday = $first_day")
//    val day5 = arrayListOf<String>("","","์ผ","์›”","ํ™”","์ˆ˜","๋ชฉ")
    val day5 = arrayListOf<String>("","")

    for(i in first_day..(first_day+4)){
        day5.add(DAYS.get(i))
    }
    for(i in day5){
//        Log.d("testtest","$i")
    }

    barchart.description.isEnabled=false
    barchart.setDrawValueAboveBar(false)

    //legend์—†์• ๊ธฐ
    barchart.legend.isEnabled=false

    val renderer=RoundedChartRenderer(barchart, barchart.animator, barchart.viewPortHandler)

    renderer.setmRadius(30f)
    barchart.renderer = renderer



    val x_axis = barchart.xAxis

    //x์ถ• bottom์— ์œ„์น˜
    x_axis.position= XAxis.XAxisPosition.BOTTOM
    //x์ถ•์— ์š”์ผ ์ž…๋ ฅ
    x_axis.granularity=1f
    x_axis.setDrawGridLines(false)
    x_axis.valueFormatter= object : ValueFormatter(){
        override fun getFormattedValue(value:Float): String {
            return day5.get(value.toInt())
//            return value.toString()
        }
    }
    x_axis.typeface= ResourcesCompat.getFont(context, R.font.nanum_square_bold )
    x_axis.textSize=11f
//    x_axis.spaceMin = 5f

    //y์ถ•์˜ ํ™œ์„ฑํ™” ์—†์• ๊ฐœ
    val axisLeft = barchart.axisLeft
    axisLeft.granularity=1f
    axisLeft.axisMinimum= 0f
    axisLeft.labelCount=5
    axisLeft.setDrawAxisLine(false)
    axisLeft.setDrawLabels(false)
    axisLeft.setDrawGridLines(false)

    val axisRight = barchart.axisRight



    axisRight.isEnabled=false


}

drawDoubleGraph

fun BarChart.drawDoubleGraph(context:Context, data1: ArrayList<Int>,data2 : ArrayList<Int>){

    this.setTouchEnabled(false)

    var values1 = ArrayList<BarEntry>()
    var values2 = ArrayList<BarEntry>()


    Log.d("drawdoublegraph",""+ data1.toString()+data2.toString())
    // data ๋งŒ๋“ค๊ธฐ
    for(i in 0..6){
        Log.d("drawdoublegraph","a"+ data1[i] + data2[i])
        values1.add(BarEntry(i.toFloat(), data1[i].toFloat()))
        values2.add(BarEntry(i.toFloat(), data2[i].toFloat()))
    }

    val data_set1 =BarDataSet(values1,"")
    val data_set2 =BarDataSet(values2, "")

    data_set1.color= getColorFromRes(context, R.color.middlegrey)
    data_set2.color= getColorFromRes(context, R.color.yellow)


    val data_sets = ArrayList<IBarDataSet>()
    data_sets.add(data_set1)
    data_sets.add(data_set2)

    val datas = BarData(data_sets)
    datas.setValueTextSize(12f)
//    data.setValueTextColor(context.getColorFromRes(R.color.darkgrey))
    datas.setValueTextColor(context.getColorFromRes(R.color.darkgrey))
    datas.setValueTextSize(9f)
    datas.setValueTypeface(ResourcesCompat.getFont(context, R.font.nanum_square_extra_bold))

    datas.setValueFormatter(object :ValueFormatter(){
        override fun getFormattedValue(value: Float): String {
            return if(value>=0)Math.round(value).toString()else ""
        }
    })


    datas.barWidth=0.15f
    this.data=datas
    this.invalidate()
    this.groupBars(-0.5f, 0.5f, 0.1f)




    setAxis(context, this)
    //legend ์ œ๊ฑฐ
//    this.legend.isEnabled=false
    this.legendRenderer
    //legend custom
    val legendEntry1 = LegendEntry("์ฒซ๋ฒˆ์งธ", Legend.LegendForm.LINE, 10f, 2f, null, context.getColorFromRes(R.color.middlegrey))
    val legendEntry2 = LegendEntry("๋‘๋ฒˆ์งธ", Legend.LegendForm.LINE, 10f, 2f, null, context.getColorFromRes(R.color.yellow))

    this.legend.setCustom(arrayListOf(legendEntry1, legendEntry2))
    this.legend.isEnabled=true
    this.legend.horizontalAlignment = Legend.LegendHorizontalAlignment.RIGHT
    this.legend.verticalAlignment = Legend.LegendVerticalAlignment.TOP
    this.legend.typeface = ResourcesCompat.getFont(context,R.font.nanum_square_extra_bold )
    this.legend.textColor = context.getColorFromRes(R.color.darkgrey)

    //๋™๊ทธ๋ž€ ๋ชจ
    val renderer=RoundedChartRenderer(this, this.animator, this.viewPortHandler)
    renderer.setmRadius(30f)
    this.renderer = renderer

    this.description.isEnabled=false

//    var max = this.yChartMax
//    drawAxisLine(this, max.toInt())
//    drawAxisLine(this, max.toInt()/2)



}

fun setAxis(context: Context,barchart:BarChart) {
    val x_axis = barchart.xAxis
    val left_axis = barchart.axisLeft
    val right_axis = barchart.axisRight

    val DAYS= arrayListOf<String>("์ผ","์›”","ํ™”","์ˆ˜","๋ชฉ","๊ธˆ","ํ† ")

    //x์ถ•์— ์ผ-์›” ํ‘œ์‹œ
    x_axis.valueFormatter=object :ValueFormatter(){
        override fun getFormattedValue(value: Float): String {
            return DAYS.get(value.toInt())
        }
    }
    //label์€ ๋ฐ”๋‹ฅ์— ์œ„์น˜ํ•˜๋„๋ก
    x_axis.position=XAxis.XAxisPosition.BOTTOM
    x_axis.setDrawGridLines(false)
    x_axis.typeface= ResourcesCompat.getFont(context,R.font.nanum_square_bold )
    x_axis.textSize=11f

    left_axis.setDrawGridLines(false)
    left_axis.setDrawLabels(false)
    left_axis.setDrawAxisLine(false)
    left_axis.axisMinimum=0f
    left_axis.granularity=10f

    right_axis.isEnabled=false



//    left_axis.isEnabled=false
//
//
//    right_axis.setDrawLabels(false)
//    right_axis.setDrawAxisLine(false)
//    right_axis.isEnabled=false)

}

fun getColorFromRes(context: Context, color : Int) :Int{
    return ContextCompat.getColor(context, color)
}
private fun drawAxisLine(barchart: BarChart, num : Int) {
    val line : LimitLine = LimitLine(num.toFloat())
    barchart.axisLeft.addLimitLine(line)
//    line.lineColor= getColorFromRes(R.color.yellow)

}

drawSingleGraph

// ์ผ์š”์ผ์—์„œ ์›”์š”์ผ๊นŒ์ง€์˜ ๋ฐ์ดํ„ฐ๋ฅผ ArrayList๋กœ ์ „๋‹ฌ๋ฐ›์•„ ๊ทธ๋ž˜ํ”„๋ฅผ ๊ทธ๋ ค์ฃผ๋Š” ํ•จ์ˆ˜

fun BarChart.drawSingleGraph(context: Context, datas : ArrayList<Int>, count_noti:Int) {

    this.setTouchEnabled(false)

    var data : BarData = createChartData(context, datas,count_noti)
    configureChartAppearance( this,context)
    prepareChartData(context, this, data)

    //bar ์œ„์— value ์œ„์น˜ํ•˜๋„
    this.setDrawValueAboveBar(true)
    //์•Œ๋ฆผ ๊ฐœ์ˆ˜ ๋ผ์ธ ๊ทธ๋ฆฌ๊ธฐ
    if(count_noti > 0){
        drawAxisLine(context, this, count_noti)
    }else{
        this.axisLeft.removeAllLimitLines()
    }
}

// num์— ํ•ด๋‹นํ•˜๋Š” value์˜ ์ˆ˜ํ‰์„  ๊ทธ๋ฆฐ
private fun drawAxisLine(context: Context, barchart : BarChart, num : Int) {

    barchart.axisLeft.removeAllLimitLines()
    val line :LimitLine = LimitLine(num.toFloat())
    barchart.axisLeft.addLimitLine(line)
    line.lineColor= context.getColorFromRes(R.color.yellow)
    line.lineWidth=1f
//    barchart.animateX(2000)
//    barchart.animateY(2000)

}

// ๋ฐ์ดํ„ฐ ๋ฐ›์•„์„œ๋‹ค
private fun prepareChartData(context: Context, barchart : BarChart,data: BarData) {
    //value text size ์„ค์ •
    data.setValueTextSize(12f)
    // text color ์„ค
    data.setValueTextColor(context.getColorFromRes(R.color.darkgrey))
    barchart.data=data
    barchart.invalidate()
}

// BarData๋งŒ๋“ค๊ธฐ
private fun createChartData(context: Context, datas :ArrayList<Int>, count_noti: Int): BarData {
    val values: ArrayList<BarEntry> = ArrayList()

    for (i in 0..6){
        values.add(BarEntry(i.toFloat(), datas.get(i).toFloat()))
    }

    val set = CustomBarDataSet(values, "SET_LABEL", count_noti)
    set.colors=
            //listOf(ContextCompat.getColor(this,R.color.yellow),ContextCompat.getColor(this, R.color.gray))
        listOf(context.getColorFromRes(R.color.yellow), context.getColorFromRes(R.color.middlegrey))
    val dataSets = ArrayList<IBarDataSet>()
    dataSets.add(set)



    val data:BarData = BarData(dataSets)
    //value๊ฐ’์„ int๋กœ
   data.setValueFormatter(object: ValueFormatter(){
        override fun getFormattedValue(value: Float): String {
            return if(value>=0) Math.round(value).toString() else "".toString()
        }
    })
    data.setValueTypeface(ResourcesCompat.getFont(context, R.font.nanum_square_extra_bold))

    //๋ง‰๋Œ€ ๋„ˆ๋น„ ์ˆ˜์ •
    data.barWidth=0.2f

    return data
}

//chart ๊ฐ€ ์–ด๋–ป๊ฐ€ ๋ณด์—ฌ์งˆ
private fun configureChartAppearance(barchart : BarChart, context: Context) {


    val DAYS = arrayListOf<String>("์ผ","์›”","ํ™”","์ˆ˜","๋ชฉ","๊ธˆ","ํ† ")

    barchart.description.isEnabled=false
    barchart.setDrawValueAboveBar(false)

    //legend์—†์• ๊ธฐ
    barchart.legend.isEnabled=false

    val renderer=RoundedChartRenderer(barchart, barchart.animator, barchart.viewPortHandler)

    renderer.setmRadius(30f)
    barchart.renderer = renderer



    val x_axis = barchart.xAxis

    //x์ถ• bottom์— ์œ„์น˜
    x_axis.position=XAxis.XAxisPosition.BOTTOM
    //x์ถ•์— ์š”์ผ ์ž…๋ ฅ
    x_axis.setDrawGridLines(false)
    x_axis.valueFormatter= object : ValueFormatter(){
        override fun getFormattedValue(value:Float): String {
            return DAYS.get(value.toInt())
        }
    }
    x_axis.typeface=ResourcesCompat.getFont(context,R.font.nanum_square_bold )
    x_axis.textSize=11f
//    x_axis.spaceMin = 5f

    //y์ถ•์˜ ํ™œ์„ฑํ™” ์—†์• ๊ฐœ
    val axisLeft = barchart.axisLeft
    axisLeft.granularity=10f
    axisLeft.axisMinimum= 0f
    axisLeft.setDrawAxisLine(false)
    axisLeft.setDrawTopYLabelEntry(false)
    axisLeft.setDrawZeroLine(false)
    axisLeft.setDrawLabels(false)
    axisLeft.setDrawGridLines(false)

    val axisRight = barchart.axisRight



    axisRight.isEnabled=false


}

ExchangeFoodFragment

fun TextView.categorySetClicked(context: Context){  
  this.background = ContextCompat.getDrawable(context, R.drawable.rec18_yellow)  
  this.setTextColor(context.getColor(R.color.white))  
}  
fun TextView.categorySetUnClicked(context: Context){  
  this.background = null  
 this.setTextColor(context.getColor(R.color.grey))  
}


๐Ÿ’ป Developer