๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ”ฅ ํ”„๋กœ์ ํŠธ/์กธ์—…ํ”„๋กœ์ ํŠธ

[์•ˆ๋“œ๋กœ์ด๋“œ] SharedPreference ์‚ฌ์šฉ๊ณผ ScrollView Event

by nitronium102 2022. 5. 17.

์žก๋‹คํ•œ ์„œ๋ก 

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

๋ฉ˜ํ† ๋‹˜๊ป˜ ์—ฌ์ญค๋ณด๋‹ˆ ๊ดœ์ฐฎ๋‹ค๊ณ ๋Š” ํ•˜์…จ์ง€๋งŒ, ์„œ๋ฒ„์˜ ๊ธฐ๋Šฅ์ด ๋‚˜๋ˆ ์ ธ์žˆ๋‹ค๋Š” ๊ฒƒ์ด ์กฐ๊ธˆ ์ด์ƒํ•˜๋‹ค๊ณ  ํ•ด์„œ ๊ทธ๋ƒฅ ์•ˆ๋“œ๋กœ์ด๋“œ ์•ˆ์—์„œ ๋ชจ๋“  ๊ฒƒ์„ ํ•ด๊ฒฐํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.  

์ด๋ ‡๊ฒŒ ๊ตฌํ˜„ํ•ด๋„ ์ž‘๋™ํ•˜๋Š”๋ฐ ๋ฌธ์ œ๋Š” ์—†์„ ๊ฒƒ ๊ฐ™์•„์š”. ์ด๋ฏธ ๊ตฌํ˜„๋œ ๋ถ€๋ถ„์ด ์žˆ๋‹ค๋ฉด ์ด๋Œ€๋กœ ๊ตฌํ˜„ํ•˜์…”๋„ ์ƒ๊ด€์—†์„ ๊ฒƒ ๊ฐ™์•„์š”. ๋‹ค๋งŒ ์กฐ๊ธˆ ์–ด์ƒ‰ํ•œ ๊ฑด, ์„œ๋ฒ„์‚ฌ์ด๋“œ์˜ ๊ธฐ๋Šฅ์ด ์—ฌ๋Ÿฌ๊ตฐ๋ฐ ๋‚˜๋‰˜์–ด์ ธ ์žˆ๋Š”๊ฒŒ ์กฐ๊ธˆ ์ด์ƒํ•˜๋„ค์š”. Storage ์˜ ์—ญํ• ๋กœ Firebase ๋ฅผ ์จ์•ผํ•˜๊ณ , ์Œ์•… ๋ถ„์„์„ ์œ„ํ•ด Django ๋ฅผ ์จ์•ผํ•˜๊ณ , ์ต์ˆ™ํ•œ ๊ฑด Spring Boot ๋ผ ์ด๋Ÿฐ ๊ตฌ์กฐ๊ฐ€ ๋œ๊ฑธ๊นŒ์š”? ๊ฐ€์žฅ ๊น”๋”ํ•œ ๊ตฌ์กฐ๋ผ๋ฉด ์„œ๋ฒ„์˜ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ํ•˜๋‚˜์˜ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ๊ตฌํ˜„ํ•˜๊ณ , ํ˜น์‹œ ๊ตฌํ˜„ ์•ˆ๋˜๋Š” ๋ถ€๋ถ„์ด ์žˆ๋‹ค๋ฉด ๊ทธ ์„œ๋ฒ„ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์—ฐ๋™ํ•˜๋Š”๊ฒŒ ์ œ์ผ ๊น”๋”ํ•œ ๊ตฌ์กฐ์ผ ๊ฒƒ ๊ฐ™์•„์š”. ์•„๋งˆ Django ๋ฅผ ์จ์•ผํ•  ๊ฒƒ ๊ฐ™๋„ค์š”. ์•„๋งˆ ์Œ์•… ๋ถ„์„ ์ชฝ์„ ์œ„ํ•ด Django ๋ฅผ ๋ฐ˜๋“œ์‹œ ์จ์•ผ๋งŒ ํ•  ๊ฒƒ ๊ฐ™์œผ๋‹ˆ...

์ด๋ ‡๊ฒŒ ํ•ด์„œ ์•ˆ๋“œ๋กœ์ด๋“œ ๊ฒฝํ—˜์ด ์—†๋Š” ํŒ€์› ์…‹์ด ์•ˆ๋“œ๋กœ์ด๋“œ ๊ฐœ๋ฐœ์„ ์ฒ˜์Œ์œผ๋กœ ์‹œ์ž‘ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค^^

์ด๋ฒˆ ํฌ์ŠคํŠธ์—์„œ๋Š” ์•ˆ๋“œ๋กœ์ด๋“œ๋ฅผ ์ฒ˜์Œ ๊ฐœ๋ฐœํ•˜๋ฉด์„œ ๋งˆ์ฃผ์ณค๋˜ ์–ด๋ ค์šด ๋ถ€๋ถ„์„ ์จ๋ณด๋ ค๊ณ  ํ•œ๋‹ค. 

 

1. SharedPreference๋ฅผ ์ด์šฉํ•œ ์ƒํƒœ ์ €์žฅ

๊ฐœ๋ฐœ์„ ์ง„ํ–‰ํ•˜๋‹ค๋ณด๋ฉด, ํŠน์ • ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์ด ์ข…์ข… ์žˆ๋‹ค. ์šฐ๋ฆฌ ํŒ€์˜ ๊ฒฝ์šฐ ์Œ์—ญ๋Œ€ ํ…Œ์ŠคํŠธ์—์„œ ๊ณ ์Œ ํ…Œ์ŠคํŠธ๋ฅผ ๋งˆ์น˜๊ณ  ๋‚˜๋ฉด isHighDone ๋ณ€์ˆ˜๊ฐ€ true๋กœ ๋ฐ”๋€Œ์–ด์•ผ ํ•˜๊ณ  ์ €์Œ ํ…Œ์ŠคํŠธ๋ฅผ ๋งˆ์น˜๋ฉด isLowDone ๋ณ€์ˆ˜๊ฐ€ true๋กœ ๋ฐ”๋€Œ์–ด์•ผ ํ–ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋‘ ๋ณ€์ˆ˜๊ฐ€ ๋ชจ๋‘ true์—ฌ์•ผ ๋‹ค์Œ ์•กํ‹ฐ๋น„ํ‹ฐ๋กœ ๊ฐ€๋Š” ๋ฒ„ํŠผ์ด ํ™œ์„ฑํ™”๋˜๋Š” ์‹์ด์—ˆ๋Š”๋ฐ, ๋ฌธ์ œ๋Š” ์Œ์—ญ๋Œ€ ํ…Œ์ŠคํŠธ ๋Œ€๊ธฐ ํ™”๋ฉด -> ์Œ์—ญ๋Œ€ ํ…Œ์ŠคํŠธ ์ง„ํ–‰ ํ™”๋ฉด -> ์Œ์—ญ๋Œ€ ํ…Œ์ŠคํŠธ ์™„๋ฃŒ ํ™”๋ฉด์œผ๋กœ ์•กํ‹ฐ๋น„ํ‹ฐ๊ฐ€ ๋„˜์–ด๊ฐ€๋‹ค๋ณด๋‹ˆ, ํ•ด๋‹น ๋ณ€์ˆ˜์˜ ๊ฐ’์ด ์ €์žฅ๋˜์ง€ ์•Š์•˜๋‹ค. ์ด๊ฑธ ํ•˜๋‚˜ํ•˜๋‚˜ intent๋กœ ๋„˜๊ฒจ์ค„ ์ˆ˜๋„ ์—†๋Š” ์ผ์ด๋ผ ๊ณ ๋ฏผํ–ˆ๋Š”๋ฐ, ๊ทธ๋Ÿด ๋•Œ SharedPreference๋ฅผ ์ด์šฉํ•ด์„œ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๋ฉด ์ข‹๋‹ค. 

SharedPreference๋ž€?

์•ฑ ๋‚ด ๊ฐœ๋ณ„ ์ €์žฅ์†Œ์— xml ํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ , ํ•ด๋‹น ํŒŒ์ผ์— key/value ํ˜•ํƒœ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹. ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋Š” ์•ฑ ๋‚ด๋ถ€์— ์ €์žฅ๋˜๊ธฐ ๋•Œ๋ฌธ์—, ๋‹ค๋ฅธ ์•ฑ๊ณผ ๊ณต์œ ํ•  ์ˆ˜ ์—†์œผ๋ฉฐ ์•ฑ์„ ์‚ญ์ œํ•˜๋ฉด ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋„ ๋ชจ๋‘ ์‚ฌ๋ผ์ง„๋‹ค. 

 

1) SharedPreference ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐ ํ˜ธ์ถœ

๊ธฐ๋ณธ์ ์œผ๋กœ SharedPreference๋ฅผ ์„ ์–ธํ•œ ํ›„, onCreate ํ•จ์ˆ˜ ์•ˆ์—์„œ getSharedPreferences()๋ฅผ ์ด์šฉํ•ด ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. 

getSharedPreferences(String name, int mode);

์ ‘๊ทผ ๊ถŒํ•œ์— ๋”ฐ๋ผ mode๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ๊ทธ๋ƒฅ ๊ธฐ๋ณธ ๋ชจ๋“œ์ธ MODE_PRIVATE๋กœ ์„ ์–ธํ•ด์ฃผ์—ˆ๋‹ค.

(MODE_PRIVATE : ์ƒ์„ฑํ•œ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“œ)

๊ทธ๋ฆฌ๊ณ  ์šฐ๋ฆฌ๋Š” ํ…Œ์ŠคํŠธ ์™„๋ฃŒ ์—ฌ๋ถ€๋ฅผ ์‚ฌ์šฉ์ž๋ณ„๋กœ ์ €์žฅํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— sharedPrefFile์ด ๊ตฌ๋ณ„๋˜๋„๋ก ์ƒ์„ฑ ๊ฒฝ๋กœ์— ์‚ฌ์šฉ์ž ์ด๋ฆ„์„ ๋„ฃ์–ด์ฃผ์—ˆ๋‹ค.

	private SharedPreferences mPreferences;
    
 	@Override
    protected void onCreate(Bundle savedInstanceState) {
    String sharedPrefFile = "com.example.android."+userEmail+".SharedPreferences";
    mPreferences = getSharedPreferences(sharedPrefFile, MODE_PRIVATE);
    }

2) SharedPreference์— ๊ฐ’ ์ €์žฅํ•˜๊ธฐ

SharedPreferences.Editor๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐ’์„ ์ €์žฅํ•œ๋‹ค. 

editor์— ์›ํ•˜๋Š” ๊ฐ’์„ key-value ํ˜•ํƒœ๋กœ ๋„ฃ์–ด์ค€ ํ›„, ๋งˆ์ง€๋ง‰์— ๊ผญ apply()๋‚˜ commit() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ์ €์žฅ์ด ๋œ๋‹ค.

private void ApplySharedPreference() {
        SharedPreferences.Editor preferencesEditor = mPreferences.edit();
        if (octaveHighLow.equals("high"))
            preferencesEditor.putBoolean("isHighDone", true);
        else if (octaveHighLow.equals("low"))
            preferencesEditor.putBoolean("isLowDone", true);
        preferencesEditor.apply();
    }

3) SharedPreference์—์„œ ๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ

getString, getBoolean ๋“ฑ์„ ์ด์šฉํ•ด์„œ ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. key๊ฐ’๊ณผ ํ•ด๋‹น ๊ฐ’์ด ์—†์„ ๋•Œ์˜ default value๋ฅผ ์„ ์–ธํ•ด์ฃผ์ž.

getBoolean(key, default value)
private Boolean isHighDone;
private Boolean isLowDone;
    
isHighDone = mPreference.getBoolean("isHighDone", false);
isLowDone = mPreference.getBoolean("isLowDone", false);

 

์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•๋“ค

์‚ฌ์‹ค ์ƒํƒœ๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ๋งŽ๋‹ค. ๊ฐ„๋‹จํ•˜๊ฒŒ ์ ์–ด๋ณด๋ฉด

1) SharedPreference

์ผ์ข…์˜ ํŒŒ์ผ ์“ฐ๊ธฐ์™€ ๋น„์Šทํ•˜๋ฉฐ, ํ™”๋ฉด์ด ๊บผ์ ธ๋„ ๊ฐ’์ด ๋‚จ์•„์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์˜ค๋ž˜๋œ ๋ฐฉ๋ฒ•์ด๋ผ ์ถ”์ฒœํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค. 

 

2) DataStore

SharedPreference์˜ ๋‹จ์ ์„ ๊ทน๋ณตํ•œ ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ.

  • ์ฝ”๋ฃจํ‹ด๊ณผ Flow๋ฅผ ํ†ตํ•ด ์ฝ๊ณ  ์“ฐ๊ธฐ์— ๋Œ€ํ•œ ๋น„๋™๊ธฐ API๋ฅผ ์ œ๊ณตํ•œ๋‹ค.
  • UI ์Šค๋ ˆ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด๋„ ์•ˆ์ „ํ•˜๋‹ค.
  • runtime exception์œผ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•˜๋‹ค.

3) ViewModel

Activity๋‚˜ Fragment์˜ ์ˆ˜๋ช… ์ฃผ๊ธฐ๋ฅผ ๊ณ ๋ คํ•˜์—ฌ UI ๊ด€๋ จ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋œ ํด๋ž˜์Šค

 

4) ์„œ๋ฒ„ ์ž์ฒด์— ์˜ฌ๋ฆฌ๋Š” ๋ฐฉ๋ฒ•

์ด๋ž˜๋„ ๋˜๋‚˜ ์‹ถ์ง€๋งŒ ์‹ค์ œ๋กœ ์‚ฌ์šฉ์ž์˜ ์„ ํƒ ์ •๋ณด๋ฅผ ์„œ๋ฒ„์— ์ €์žฅํ•˜๋Š” ์ผ์ด ๋งŽ๋‹ค๊ณ  ํ•œ๋‹ค! ํšŒ์‚ฌ๋“ค์€ ์œ ์ € ๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜์œผ๋กœ ๋“ฑ ๋‹ค์–‘ํ•œ ์„œ๋น„์Šค๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋Ÿฐ ๊ฒƒ ๊ฐ™๋‹ค. 

 

์ด๋ฒˆ์—๋Š” ์•ˆ๋“œ๋กœ์ด๋“œ์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ๋ถ€์กฑํ•œ ์ƒํƒœ์—์„œ ๊ธ‰ํ•˜๊ฒŒ ๊ฐœ๋ฐœ์„ ํ•˜๋Š๋ผ SharedPreference๋ฅผ ์‚ฌ์šฉํ–ˆ์ง€๋งŒ, ๋ณธ์ธ์ด ์ถฉ๋ถ„ํ•œ ์—ฌ์œ ๊ฐ€ ์žˆ๋‹ค๋ฉด View Model์œผ๋กœ ๊ฐœ๋ฐœํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค!

 

SharedPreference vs SavedInstanceState

์ฒ˜์Œ์—๋Š” SavedInstanceState๋ฅผ ํ˜ธ์ถœํ–ˆ์œผ๋‚˜, ์•กํ‹ฐ๋น„ํ‹ฐ ์—ฌ๋Ÿฌ ๊ฐœ๋ฅผ ์™”๋‹ค๊ฐ”๋‹คํ•˜๋Š” ์šฐ๋ฆฌ ์•ฑ์˜ ํŠน์„ฑ์ƒ savedInstanceState๊ฐ€ ์•„์˜ˆ ์ดˆ๊ธฐํ™”๋˜๋Š” ์ผ์ด ์žฆ์•˜๋‹ค. ๊ทธ๋ž˜์„œ ์ฐพ์•„๋ณด๋‹ค๊ฐ€ SharedPreference๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜์—ˆ๋Š”๋ฐ, ์ด ๊น€์— ๋‘˜์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋น„๊ตํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

 

1) SharedPreference

  • ์•ฑ ๋‚ด ํŒŒ์ผ ํ˜•ํƒœ๋กœ ์ €์žฅ๋˜์–ด ์žˆ์œผ๋ฉฐ, ์ฃผ๋กœ ์„ค์ • ํŒŒ์ผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.
  • ์•ฑ์„ ์‚ญ์ œํ•˜์ง€ ์•Š๋Š” ํ•œ ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ๊ณ„์† ๋‚จ์•„์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ™”๋ฉด์„ ๋„๊ฑฐ๋‚˜ ์•ฑ์„ ์ข…๋ฃŒํ•ด๋„ ๋ฐ์ดํ„ฐ๊ฐ€ ๋‚จ์•„์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœํ•ด์•ผ ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ๋•Œ ์œ ์šฉํ•˜๋‹ค.

2) SavedInstanceState

 

  • ์•กํ‹ฐ๋น„ํ‹ฐ ๋‚ด์˜ ์ƒํƒœ๋ฅผ ์ €์žฅํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋ฉฐ, ์ฃผ๋กœ ํ™”๋ฉด ํšŒ์ „ ์‹œ ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ ์šฉ๋„๋กœ ์‚ฌ์šฉ๋œ๋‹ค.
  • ํ™”๋ฉด์ด ํšŒ์ „ํ•  ๋•Œ๋Š” onCreate()์™€ onDestroy()๊ฐ€ ๋‹ค์‹œ ๋ถˆ๋ฆฌ๊ธฐ ๋–„๋ฌธ์— ์„ค์ •ํ•ด๋‘” ๋ณ€์ˆ˜ ๊ฐ’์ด ๋ชจ๋‘ ์ดˆ๊ธฐํ™”๋˜๋Š”๋ฐ, savedInstanceState๋ฅผ ์ด์šฉํ•ด์„œ onDestroy() ์ „์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ , ์ด ๋ฐ์ดํ„ฐ๋ฅผ onCreate()์—์„œ ๋‹ค์‹œ ๋ถˆ๋Ÿฌ์˜ค๋Š” ํ˜•์‹์œผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.
  • ์•ฑ์„ ์ข…๋ฃŒํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ์•กํ‹ฐ๋น„ํ‹ฐ๋กœ ์ด๋™ํ•  ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ๊ฐ€ ์‚ฌ๋ผ์ง„๋‹ค.

 

2. ScrollView์™€ GridView๋กœ ์ž๋™ ์ด๋™ํ•˜๋Š” ๋…ธ๋ž˜ ์—ฐ์Šตํ™”๋ฉด ๊ตฌํ˜„ํ•˜๊ธฐ

์šฐ๋ฆฌ ํ”„๋กœ์ ํŠธ์—์„œ ์ œ์ผ ๋‚œ์ด๋„๊ฐ€ ๋†’์€ ๋…ธ๋ž˜ ์—ฐ์Šตํ™”๋ฉด! ๋…ธ๋ž˜๋ฐฉ์ด๋‚˜ ๋…ธ๋ž˜ ์—ฐ์Šต ์•ฑ์„ ๋ณด๋ฉด ์•…๋ณด๊ฐ€ ์ž๋™์œผ๋กœ ์ด๋™ํ•˜๋Š” ํ™”๋ฉด์ด ์žˆ๋‹ค. ์šฐ๋ฆฌ ํŒ€๋„ ๋…ธ๋ž˜ ์Œ์ •์„ ๋ธ”๋ก์œผ๋กœ ๋„์›Œ์ฃผ๊ณ , ๋…ธ๋ž˜๊ฐ€ ์ง„ํ–‰๋จ์— ๋”ฐ๋ผ ์ž๋™์œผ๋กœ ๋ธ”๋ก์ด ์ด๋™ํ•˜๋Š” ํ™”๋ฉด์„ ๊ตฌํ˜„ํ•ด์•ผ ํ–ˆ๋‹ค. 

์• ์ฆ์˜ ํ™”๋ฉด....๋„ˆ๋งŒ ์—†์—ˆ์–ด๋„...๊ทผ๋ฐ ์—†์œผ๋ฉด ํ”Œ์  ๋งํ•จ

 

์Œ์ •์„ ํ‘œ์‹œํ•˜๋Š”๋ฐ๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

1) GridView์˜ row, column์˜ ์ƒ‰๊น”์„ ๋ฐ”๊ฟ” cell์œผ๋กœ ๋ธ”๋ก์„ ํ‘œ์‹œํ•ด์ฃผ๋Š” ๊ฒƒ

2) Background๋กœ GridView๋ฅผ ๊ทธ๋ฆฌ๊ณ , ๊ทธ ์œ„์— ํˆฌ๋ช…๋„๋ฅผ ์กฐ์ ˆํ•œ Fragment๋กœ ๋ธ”๋ก์„ ํ‘œ์‹œํ•˜๋Š” ๊ฒƒ

์ด ์ค‘์—์„œ ์šฐ๋ฆฌ๋Š” ๊ตฌํ˜„ ๋‚œ์ด๋„๊ฐ€ ๋” ๋‚ฎ์•„๋ณด์ด๋Š” 1๋ฒˆ์„ ์„ ํƒํ–ˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  ๋…ธ๋ž˜๊ฐ€ ์ง„ํ–‰๋จ์— ๋”ฐ๋ผ ํ™”๋ฉด์„ ๋งž์ถฐ์„œ ์ด๋™์‹œ์ผœ์ค˜์•ผ ํ–ˆ๋Š”๋ฐ, ์ด๊ฒƒ๋„ ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์—ˆ๋‹ค.

1) GridView ๋‚ด์˜ ์Šคํฌ๋กค ๊ธฐ๋Šฅ ์ด์šฉ

2) ์Šคํฌ๋กค๋ทฐ ์•ˆ์— GridView๋ฅผ ๋„ฃ์–ด์„œ ์ด๋™

๊ทธ๋Ÿฐ๋ฐ ์Šคํฌ๋กค๋ทฐ์— ์•ก์…˜์„ ๋„ฃ๋Š” ๊ฒƒ์ด ๋” ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ด๋™์ด ๋˜๋Š” ๊ฒƒ ๊ฐ™์•„ ํ›„์ž๋กœ ์„ ํƒํ–ˆ๋‹ค.

Horizontal ScrollView

์ผ๋‹จ ์šฐ๋ฆฌ๋Š” ์ขŒ->์šฐ๋กœ ์ด๋™ํ•˜๋Š” ํ™”๋ฉด์„ ๋งŒ๋“ค์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ผ๋ฐ˜ scrollView๊ฐ€ ์•„๋‹Œ HorizontalScrollView๋ฅผ ์„ ํƒํ–ˆ๋‹ค. 

1) ObjectAnimator๋ฅผ ์ด์šฉํ•œ ์ž๋™ ์Šคํฌ๋กค ์ด๋ฒคํŠธ ์ƒ์„ฑ

ObjectAnimator๋ž€?

์•ˆ๋“œ๋กœ์ด๋“œ์—์„œ ์ œ๊ณตํ•˜๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜ ๊ตฌํ˜„ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜๋กœ, ํƒ€๊ฒŸ์œผ๋กœ ์„ค์ •ํ•œ object์— ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๋„ฃ์–ด์ค€๋‹ค. 

 

ObjectAnimator Attribute

์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•œ ์†์„ฑ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

propertyName ๊ฐ์ฒด์—์„œ animateํ•  ์†์„ฑ์„ ์ง€์ •ํ•œ๋‹ค. alpha, rotationX, scrollX, translationX ๋“ฑ๋“ฑ
object ํƒ€๊ฒŸ object๋ฅผ ์ง€์ •ํ•œ๋‹ค  
valueTo propertyName์—์„œ ์ง€์ •ํ•œ ์†์„ฑ๊ฐ’์˜ ์ข…๋ฃŒ๊ฐ’์„ ์ง€์ •  
duration ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ง€์† ์‹œ๊ฐ„  

 

์Šคํฌ๋กค๋ทฐ๋ฅผ object๋กœ ๋†“๊ณ , X์ถ• ๋ฐฉํ–ฅ์œผ๋กœ ์ด๋™ํ•˜๋„๋ก ์ง€์ •ํ•˜์˜€์œผ๋ฉฐ, ์ผ๋‹จ ํ™”๋ฉด์˜ ๋๊นŒ์ง€ ๊ฐ€์•ผ ํ•˜๋‹ˆ๊นŒ valueTo์— ์ž„์˜๋กœ ํฐ ๊ฐ’์„ ๋„ฃ์–ด์ฃผ์—ˆ๋‹ค.

์• ๋‹ˆ๋ฉ”์ด์…˜์€ ๋…ธ๋ž˜๊ฐ€ ๋๋‚  ๋•Œ๊นŒ์ง€ ์ง€์†๋˜์–ด์•ผ ํ•˜๋ฏ€๋กœ duration์—๋Š” ๋…ธ๋ž˜ ๊ธธ์ด๋ฅผ ๋„ฃ์–ด์ฃผ์—ˆ๋‹ค.

scrollView.post(new Runnable() {
            @Override
            public void run() {
                ObjectAnimator objectAnimator = ObjectAnimator.ofInt(scrollView, "scrollX", 1000000);
                objectAnimator.setDuration(Math.round(songEndTime)); // song ๊ธธ์ด๋งŒํผ ์ง€์†
                objectAnimator.start();
            }

๊ทธ๋žฌ๋”๋‹ˆ ์ž˜ ์ž‘๋™์€ ๋˜๋Š”๋ฐ...์‹œ์ž‘๊ณผ ๋์—์„œ๋งŒ ์Šคํฌ๋กค ์ด๋™ ์†๋„๊ฐ€ ๋Š๋ฆฌ๊ณ  ์ค‘๊ฐ„์—๋Š” ์—„์ฒญ๋‚˜๊ฒŒ ๋นจ๋ผ์ง„๋‹ค. ๊ทน์ ์ธ ์• ๋‹ˆ๋ฉ”์ด์…˜ ํšจ๊ณผ๋ฅผ ์ฃผ๊ธฐ ์œ„ํ•ด ๊ธฐ๋ณธ์ ์œผ๋กœ ์„ค์ •์ด ๋˜์–ด์žˆ๋Š” ๋“ฏํ•œํ…Œ, ์šฐ๋ฆฌ๋Š” ์ผ์ •ํ•œ ์†๋„๋กœ ๋ทฐ๋ฅผ ๋ณด์—ฌ์ค˜์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด ํšจ๊ณผ๋ฅผ ์—†์• ์•ผ ํ•œ๋‹ค. ์ด๋Ÿด ๋•Œ Interpolator๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

 

2) Interpolator๋ฅผ ์ด์šฉํ•œ ์Šคํฌ๋กค ์†๋„ ์กฐ์ •

Interpolator๋ž€?

์• ๋‹ˆ๋ฉ”์ด์…˜ ์‹œ์ž‘ ์ง€์ ๊ณผ ์ข…๋ฃŒ ์ง€์ ์„ ์—ฐ๊ฒฐํ•˜๋Š” ํšจ๊ณผ. (Linear๊ฐ€ default๋ผ๋Š”๋ฐ ์™œ ๋‚ด ์Šคํฌ๋กค๋ทฐ์—์„œ๋Š” AccelerateDecelerate ํšจ๊ณผ๊ฐ€ ๋‚˜ํƒ€๋‚˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ๋‹ค) ์•„๋ฌดํŠผ ์šฐ๋ฆฌ๋Š” LinearInterpolator๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

AccelerateInterpolator ์‹œ์ž‘ ์‹œ์ ์—์„œ ๊ฐ€์†ํ•œ๋‹ค.
AnticipateInterpolator ์‹œ์ž‘์‹œ์  ๋’ค์ชฝ์œผ๋กœ ์‚ด์ง ์ด๋™ํ•œ ์ดํ›„์— ์ข…๋ฃŒ์‹œ์ ์— ๋„์ฐฉํ•œ๋‹ค.
OvershootInterpolator ์ข…๋ฃŒ์‹œ์ ์„ ์ง€๋‚˜์ณ์„œ ์‚ด์ง ์ด๋™ํ•œ ์ดํ›„์— ๋‹ค์‹œ ์ข…๋ฃŒ์‹œ์ ์œผ๋กœ ๋Œ์•„์˜จ๋‹ค.
BounceInterpolator ์ข…๋ฃŒ ์‹œ์ ์— ๋„์ฐฉํ•œ ์ดํ›„ ๋ช‡ ํšŒ์— ๊ฑธ์ณ ํŠ€์–ด ์˜ค๋ฅธ๋‹ค.
CycleInterpolator ์ข…๋ฃŒ ์‹œ์ ์— ๋„์ฐฉ ํ›„ ๋‹ค์‹œ ์‹œ์ž‘ ์ง€์ ์œผ๋กœ ์ด๋™ํ•œ๋‹ค.
DecelerateInterpolator ์ข…๋ฃŒ ์ง€์ ์œผ๋กœ ๋„์ฐฉํ• ์ˆ˜๋ก ๊ฐ€์†ํ•œ๋‹ค. 
LinearInterpolator(default) ๋™์ผํ•œ ์†๋„๋กœ ์‹œ์ž‘ ์‹œ์ ์—์„œ ์ข…๋ฃŒ ์‹œ์ ์œผ๋กœ ์ด๋™ํ•œ๋‹ค.
AccelerateDecelerateInterpolator ์‹œ์ž‘ ์ง€์ ์—์„œ ๊ฐ€์†ํ–ˆ๋‹ค๊ฐ€ ์ข…๋ฃŒ ์‹œ์ ์— ๊ฐ์†ํ•œ๋‹ค.

์‚ฌ์šฉ ๋ฐฉ๋ฒ•์€ ๊ฐ„๋‹จํ•œ๋‹ค. ๊ทธ๋ƒฅ ์„ ์–ธํ•ด์ฃผ๊ณ  ObjectAnimator์— ์„ค์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค!

 

  LinearInterpolator interpolator = new LinearInterpolator();
        scrollView.post(new Runnable() {
            @Override
            public void run() {
                ObjectAnimator objectAnimator = ObjectAnimator.ofInt(scrollView, "scrollX", 1000000);
                objectAnimator.setInterpolator(new LinearInterpolator()); // interpolator ์„ค์ •
                objectAnimator.start();
            }
        });

 

GridView

์ด์ œ ์Šคํฌ๋กค์ด ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์›€์ง์ด๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ์œผ๋‹ˆ ๋ฐ‘์— ๊น”์•„์ค„ GridView๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž.

1) GridItem.java

์ผ๋‹จ ๋…ธํŠธ์™€ ์ƒ‰์ƒ์„ ํ‘œ์‹œํ•˜๋Š” ์•„์ดํ…œ์„ ๋งŒ๋“ ๋‹ค.

@Getter
@AllArgsConstructor
public class ListItem {
    String note;
    String color;
}

2) GridViewAdapter.java

public class GridListAdapter extends BaseAdapter {

    ArrayList<ListItem> items = new ArrayList<ListItem>();
    Context context; // ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋Œ€ํ•œ ์ •๋ณด

    public void addItem(ListItem item){
        items.add(item);
    }

    @Override
    public int getCount() {
        return items.size();
    }

    @Override
    public Object getItem(int position) {
        return items.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        context = parent.getContext();
        ListItem listItem = items.get(position);

        // listItem์„ inflateํ•˜์—ฌ context๋ฅผ ์ฐธ์กฐ
        if (convertView == null){
            LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.singing_grid_item, parent, false);
        }

        TextView noteText = convertView.findViewById(R.id.noteText);
        TextView colorText = convertView.findViewById(R.id.colorText);

        noteText.setText(listItem.getNote());
        colorText.setText(listItem.getColor());

        return convertView;
    }
}

3)  GridViewActivity.java

public class SingGridActivity extends AppCompatActivity {
	...
    private HorizontalScrollView scrollView;
    private GridView gridView;

    public static FirebaseFirestore database = FirebaseFirestore.getInstance();

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

        gridView = findViewById(R.id.gridView);
        getSongEndTime();
    }

    private void setGridViewAdapters(){
        int columnNum = (int) Math.round(songEndTime / 0.1);
        gridView.setNumColumns(10);
        GridListAdapter adapter = new GridListAdapter();

        adapter.addItem(new ListItem("B4", "๋นจ๊ฐ•"));
        adapter.addItem(new ListItem("B4", "์ฃผํ™ฉ"));
        adapter.addItem(new ListItem("B4", "๋…ธ๋ž‘"));
        adapter.addItem(new ListItem("B4", "์ดˆ๋ก"));
        adapter.addItem(new ListItem("B4", "ํŒŒ๋ž‘"));
        adapter.addItem(new ListItem("B4", "๋ณด๋ผ"));
        adapter.addItem(new ListItem("B4", "๋ถ„ํ™"));
        adapter.addItem(new ListItem("B4", "๊ฐˆ์ƒ‰"));
        adapter.addItem(new ListItem("B4", "ํšŒ์ƒ‰"));
        adapter.addItem(new ListItem("A4", "๋นจ๊ฐ•"));
        adapter.addItem(new ListItem("A4", "์ฃผํ™ฉ"));
        adapter.addItem(new ListItem("A4", "๋…ธ๋ž‘"));
        adapter.addItem(new ListItem("A4", "์ดˆ๋ก"));
        adapter.addItem(new ListItem("A4", "ํŒŒ๋ž‘"));
        adapter.addItem(new ListItem("A4", "๋ณด๋ผ"));
        adapter.addItem(new ListItem("A4", "๋ถ„ํ™"));
        adapter.addItem(new ListItem("A4", "๊ฐˆ์ƒ‰"));
        adapter.addItem(new ListItem("A4", "ํšŒ์ƒ‰"));

        gridView.setAdapter(adapter);
    }
}

GridView์—์„œ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ •์˜ํ•œ ์•„์ดํ…œ์„ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด Adapter๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

GridView๋Š” Adapter๋กœ๋ถ€ํ„ฐ ์ƒ์„ฑ๋œ view๋ฅผ ๋ฐ›์•„ GridView ํ•ญ๋ชฉ์œผ๋กœ ๋ฐฐ์น˜ํ•œ๋‹ค.

4) activity_gridview.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=".Singing.activity.SingGridActivity">

    <HorizontalScrollView
        android:id="@+id/horizontalScrollView"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:fillViewport="true"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <LinearLayout
            android:id="@+id/linearLayout3"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginStart="1dp"
            android:layout_marginTop="1dp"
            android:layout_marginEnd="1dp"
            android:layout_marginBottom="1dp"
            android:orientation="vertical"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <GridView
                android:id="@+id/gridView"
                android:layout_width="1000dp"
                android:layout_height="1000dp"
                android:layout_margin="10dp"
                android:rowCount="10"
                android:horizontalSpacing="10dp"
                android:verticalSpacing="10dp" />
        </LinearLayout>

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

5) gridview_list_item.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">

    <LinearLayout
        android:layout_width="409dp"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/noteText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="10dp"
            android:text="์Œ์ •"
            android:textColor="@android:color/black"/>

        <TextView
            android:id="@+id/colorText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_marginTop="10dp"
            android:text="์ƒ‰๊น”"
            android:textColor="@android:color/black" />

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

 

๊ทธ๋Ÿฌ๋ฉด ์•„๋ž˜์ฒ˜๋Ÿผ ์ž˜ ๋‚˜ํƒ€๋‚˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์Šคํฌ๋กค๋„ ์ž˜ ๋œ๋‹ค!

์ด์ œ ๋ ˆ์ด์•„์›ƒ์„ ๋‹ค๋“ฌ๊ณ  cell๋ณ„ color๋งŒ ๋„ฃ์–ด์ฃผ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ํ™”๋ฉด์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. 

 

'๐Ÿ”ฅ ํ”„๋กœ์ ํŠธ > ์กธ์—…ํ”„๋กœ์ ํŠธ' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[TarsosDSP] Real-time Pitch Detection  (0) 2021.11.19

๋Œ“๊ธ€