[Android ๊ธฐ์ดˆ] 11. ์–ด๋Œ‘ํ„ฐ๋ทฐ - ๋ฆฌ์ŠคํŠธ๋ทฐ(ListView), ๊ทธ๋ฆฌ๋“œ๋ทฐ(GridView)
๋ฐ˜์‘ํ˜•

 

 

 


 

ListView

 

 

 

1. ๋ฆฌ์ŠคํŠธ๋ทฐ(ListView)

 

 

  •  ListView๋Š” ์–ด๋Œ‘ํ„ฐ ๋ทฐ์˜ ๋Œ€ํ‘œ ์œ„์ ฏ์œผ๋กœ์„œ, ๋ณต์ˆ˜ ๊ฐœ์˜ ํ•ญ๋ชฉ์„ ์ˆ˜์ง์œผ๋กœ ํ‘œ์‹œ

 

 

 

 


2. ๋ฆฌ์ŠคํŠธ๋ทฐ ์„ค์ • ์ ˆ์ฐจ

  1. ์‚ฌ์šฉํ•  ๋ ˆ์ด์•„์›ƒ์— ListView ์œ„์ ฏ ์ •์˜ (XML์ฝ”๋“œ)
  2. ์–ด๋Œ‘ํ„ฐ ๊ฐ์ฒด ์ƒ์„ฑ (Kotlin ์ฝ”๋“œ)
  3. ListView ๊ฐ์ฒด์— ์–ด๋Œ‘ํ„ฐ ์—ฐ๊ฒฐ (Kotlin ์ฝ”๋“œ)

 

 

2-1. ์‚ฌ์šฉํ•  ๋ ˆ์ด์•„์›ƒ์— ListView์œ„์ ฏ ์ •์˜

  • ์‚ฌ์šฉํ•  ๋ ˆ์ด์•„์›ƒ XML์— ListView์œ„์ ฏ์„ ์ถ”๊ฐ€
  • XML๋ ˆ์ด์•„์›ƒ ํŒŒ์ผ์— ์ •์˜๋œ ListView ์œ„์ ฏ์„ ์ฝ”ํ‹€๋ฆฐ ์ฝ”๋“œ์—์„œ ์ฐธ์กฐํ•˜๊ธฐ ์œ„ํ•˜์—ฌ id์†์„ฑ์„ ์ •์˜ํ•จ
~.xml

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

    <ListView // ๋ฆฌ์ŠคํŠธ๋ทฐ ์ถ”๊ฐ€
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
       />
       
</LinearLayout>


    

2-2. ์–ด๋Œ‘ํ„ฐ ๊ฐ์ฒด ์ƒ์„ฑ

  • ๋ฐ์ดํ„ฐ ์›๋ณธ์ด ๋ฐฐ์—ด(Array)์ธ ๊ฒฝ์šฐ์— ArrayAdapter๊ฐ์ฒด ์‚ฌ์šฉ
  • ArrayAdapter ์ƒ์„ฑ์ž
    ArrayAdapter(Context context, int textViewResourceId, T[] objects)
    • context: ํ˜„์žฌ ์ปจํ…์ŠคํŠธ
    • resource: ํ•ญ๋ชฉ์œผ๋กœ ํ‘œ์‹œ๋  ํ…์ŠคํŠธ ๋ทฐ์˜ ๋ฆฌ์†Œ์Šค ID
    • objects: ์–ด๋Œ‘ํ„ฐ๋กœ ๊ณต๊ธ‰๋  ๋ฐ์ดํ„ฐ ์›๋ณธ์œผ๋กœ ๋‹จ์ˆœ ๋ฐฐ์—ด

 

string ๋ฐฐ์—ด์„ ์ด์šฉํ•œ ArrayAdapter ๊ฐ์ฒด ์ƒ์„ฑ ์˜ˆ์ œ


class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // ๋ฐ์ดํ„ฐ ์›๋ณธ ์ค€๋น„
        val items = arrayOf<String?>("item1", "item2", "item3", "item4", "item5", "item6", "item7", "item8", "item5", "item6", "item7", "item8", "item5", "item6", "item7", "item8", "item5", "item6",  "item7", "item8")

        //์–ด๋Œ‘ํ„ฐ ์ค€๋น„ (๋ฐฐ์—ด ๊ฐ์ฒด ์ด์šฉ, simple_list_item_1 ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ
        val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, items)

   }
}

 

 

2-3. ๋ฆฌ์ŠคํŠธ๋ทฐ ๊ฐ์ฒด์— ์–ด๋Œ‘ํ„ฐ ์—ฐ๊ฒฐ

  • ํ˜„์žฌ ํ™”๋ฉด ๋ ˆ์ด์•„์›ƒ XML์— ์ •์˜ ๋œ ๋ทฐ ์ค‘์—์„œ, id๊ฐ€ listView์ธ ListView๊ฐ์ฒด๋ฅผ ViewBinding์„ ํ†ตํ•ด์„œ ์–ป์–ด์˜ด
  • ์–ป์–ด ์˜จ ListView๊ฐ์ฒด์— ์ƒ์„ฑ๋œ ์–ด๋Œ‘ํ„ฐ ๊ฐ์ฒด(์˜ˆ: ArrayAdapter๊ฐ์ฒด - adapter)๋ฅผ ์—ฐ๊ฒฐ

 

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // ๋ฐ์ดํ„ฐ ์›๋ณธ ์ค€๋น„
        val items = arrayOf<String?>("item1", "item2", "item3", "item4", "item5", "item6", "item7", "item8", "item5", "item6", "item7", "item8", "item5", "item6", "item7", "item8", "item5", "item6",  "item7", "item8")

        //์–ด๋Œ‘ํ„ฐ ์ค€๋น„ (๋ฐฐ์—ด ๊ฐ์ฒด ์ด์šฉ, simple_list_item_1 ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ
        val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, items)

        // ์–ด๋Œ‘ํ„ฐ๋ฅผ ListView ๊ฐ์ฒด์— ์—ฐ๊ฒฐ
        binding.listView.adapter = adapter

    }
}

 

 

 

 

 

 


 

GridView

 

 

 

1. ๊ทธ๋ฆฌ๋“œ๋ทฐ (GridView)

  • GridView๋Š” 2์ฐจ์› ์Šคํฌ๋กค ๊ฐ€๋Šฅํ•œ ๊ทธ๋ฆฌ๋“œ์— ํ•ญ๋ชฉ์„ ํ‘œ์‹œ

 

 

 

 


2. ๊ทธ๋ฆฌ๋“œ๋ทฐ ์„ค์ • ์ ˆ์ฐจ

  1. ์‚ฌ์šฉํ•  ๋ ˆ์ด์•„์›ƒ์— GridView์œ„์ ฏ ์ •์˜ (XML์ฝ”๋“œ)
  2. ArrayAdapter๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ
  3. GridView๊ฐ์ฒด์— ์—ฐ๊ฒฐ (Kotlin ์ฝ”๋“œ)

 

2-1. ์‚ฌ์šฉํ•  ๋ ˆ์ด์•„์›ƒ์— GridView์œ„์ ฏ ์ •์˜

  • ์‚ฌ์šฉํ•  ๋ ˆ์ด์•„์›ƒ(์˜ˆ: activity_main.xml)์— GridView์œ„์ ฏ์„ ์ถ”๊ฐ€
  • XML๋ ˆ์ด์•„์›ƒ ํŒŒ์ผ์— ์ •์˜๋œ GridView ์œ„์ ฏ์„ Kotlin์ฝ”๋“œ์—์„œ ์ฐธ์กฐํ•˜๊ธฐ ์œ„ํ•˜์—ฌ id์†์„ฑ์„ ์ •์˜
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/gridview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:columnWidth="100dp"
    android:numColumns="auto_fit"
    android:verticalSpacing="10dp"
    android:horizontalSpacing="10dp"
    android:stretchMode="columnWidth"
    android:gravity="center"
    />
  • android:columnWidth="100dp" : ๊ทธ๋ฆฌ๋“œ ํ•ญ๋ชฉ ํ•˜๋‚˜์˜ ํญ์„ 100dp๋กœ ์„ค์ •
  • android:numColumns="auto_fit”: ์—ด์˜ ํญ๊ณผ ํ™”๋ฉด ํญ์„ ๋ฐ”ํƒ•์œผ๋กœ ์ž๋™ ๊ณ„์‚ฐ
  • android:verticalSpacing: ํ•ญ๋ชฉ ๊ฐ„์˜ ๊ฐ„๊ฒฉ ์„ค์ •
  • android:stretchMode="columnWidth": ์—ด ๋‚ด๋ถ€์˜ ์—ฌ๋ฐฑ์„ ํญ์— ๋งž๊ฒŒ ์ฑ„์›€

 

2-2/3. ArrayAdapter๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  GridView๊ฐ์ฒด์— ์—ฐ๊ฒฐ

  • ArrayAdapter ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ
  • id๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋ฉ”์ธํ™”๋ฉด ๋ ˆ์ด์•„์›ƒ(activity_main.xml)์— ์ •์˜๋œ GridView ๊ฐ์ฒด ๋กœ๋”ฉ
  • ์ƒ์„ฑ๋œ ArrayAdapter ๊ฐ์ฒด๋ฅผ GridView ๊ฐ์ฒด์— ์—ฐ๊ฒฐ
  • ๋ฆฌ์ŠคํŠธ๋ทฐ ๋งŒ๋“ค์—ˆ๋˜ ๋ฐฉ๋ฒ•๊ณผ ๋˜‘๊ฐ™์Œ!
class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // ๋ฐ์ดํ„ฐ ์›๋ณธ ์ค€๋น„
        val items = arrayOf<String?>("item1", "item2", "item3", "item4", "item5", "item6", "item7", "item8", "item5", "item6", "item7", "item8", "item5", "item6", "item7", "item8", "item5", "item6",  "item7", "item8")

        //์–ด๋Œ‘ํ„ฐ ์ค€๋น„ (๋ฐฐ์—ด ๊ฐ์ฒด ์ด์šฉ, simple_list_item_1 ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ
        val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, items)

        // ์–ด๋Œ‘ํ„ฐ๋ฅผ GridView ๊ฐ์ฒด์— ์—ฐ๊ฒฐ
        binding.gridView.adapter = adapter

    }
}

 

 

 

 

 

 

3. ์ด๋ฏธ์ง€ ๊ทธ๋ฆฌ๋“œ ๋ทฐ ์„ค์ • ์ ˆ์ฐจ

  • ๋ฐฉ์‹์€ ์ผ๋ฐ˜ ๊ทธ๋ฆฌ๋“œ ๋ทฐ์™€ ๋˜‘๊ฐ™์Œ (๋ ˆ์ด์•„์›ƒ XML์ฝ”๋“œ ์ž‘์„ฑ, ์–ด๋Œ‘ํ„ฐ ์ •์˜, ์–ด๋Œ‘ํ„ฐ ์—ฐ๊ฒฐ)
  • ํ•˜์ง€๋งŒ ์–ด๋Œ‘ํ„ฐ ์ •์˜๊ฐ€ ๋‹ค๋ฆ„
XML ํŒŒ์ผ : ๊ธฐ์กด ๊ทธ๋ฆฌ๋“œ๋ทฐ ์ƒ์„ฑ๊ณผ ๋™์ผ

<GridView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/gridview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:columnWidth="100dp"
    android:gravity="center"
    android:horizontalSpacing="10dp"
    android:numColumns="auto_fit"
    android:stretchMode="columnWidth"
    android:verticalSpacing="10dp" />
์–ด๋Œ‘ํ„ฐ ์ •์˜ : ๊ธฐ์กด ๊ทธ๋ฆฌ๋“œ๋ทฐ์™€ ๋‹ค๋ฆ„

class ImageAdapter : BaseAdapter() {
    override fun getCount(): Int {
        return mThumbIds.size
    }

    override fun getItem(position: Int): Any {
        return mThumbIds[position]
    }

    override fun getItemId(position: Int): Long {
        return position.toLong()
    }

    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
        val imageView: ImageView
        if (convertView == null) {
            imageView = ImageView(parent!!.context)
            imageView.layoutParams = AbsListView.LayoutParams(200, 200)
            imageView.scaleType = ImageView.ScaleType.CENTER_CROP
            imageView.setPadding(8, 8, 8, 8)
        } else {
            imageView = convertView as ImageView
        }

        imageView.setImageResource(mThumbIds.get(position))
        return imageView
    }

    private val mThumbIds = arrayOf<Int>(
        R.drawable.sample_2, R.drawable.sample_3,
        R.drawable.sample_4, R.drawable.sample_5,
        R.drawable.sample_6, R.drawable.sample_7,
        R.drawable.sample_0, R.drawable.sample_1,
        R.drawable.sample_2, R.drawable.sample_3,
        R.drawable.sample_4, R.drawable.sample_5,
        R.drawable.sample_6, R.drawable.sample_7,
        R.drawable.sample_0, R.drawable.sample_1,
        R.drawable.sample_2, R.drawable.sample_3,
        R.drawable.sample_4, R.drawable.sample_5,
        R.drawable.sample_6, R.drawable.sample_7
    )
}
  • ๊ทธ๋ฆฌ๋“œ ๋ทฐ์˜ ํ•ญ๋ชฉ์œผ๋กœ ๊ฐ„๋‹จํ•œ ํ…์ŠคํŠธ๊ฐ€ ์•„๋‹Œ ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š”
    ๊ทธ๋ฆฌ๋“œ๋ทฐ์˜ ํ•ญ๋ชฉ์œผ๋กœ ์ด๋ฏธ์ง€๋ฅผ ๊ณต๊ธ‰ํ•˜๋Š” ImageAdapter๋ฅผ BaseAdapter๋กœ๋ถ€ํ„ฐ ํŒŒ์ƒํ•˜์—ฌ ์ •์˜
  • app>res>drawable ํ•˜์œ„์— ์ด๋ฆ„์ด sample_0์—์„œ sample_7๊นŒ์ง€์ธ 8๊ฐœ์˜ ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ์ถ”๊ฐ€
  • ImageAdapter๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐ์ดํ„ฐ๋Š” ํŽธ์˜์ƒ ์ง์ ‘ ImageAdapter ๋‚ด๋ถ€์— Image ๋ฆฌ์†Œ์Šค ID์˜ ๋ฐฐ์—ด๋กœ ์„ค์ •
  • BaseAdapter์˜ getCount(), getItem(), **getItemId()**, **getView()** ๋ฉ”์†Œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•จ
        - getCount() : ํ•ญ๋ชฉ์˜ ์ด ๊ฐœ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด mThumbIds ๋ฐฐ์—ด์˜ ํฌ๊ธฐ๋ฅผ ๋ฐ˜ํ™˜
        - getItem() : ํŠน์ • ์œ„์น˜์˜ ํ•ญ๋ชฉ์„ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด mThumbIds ๋ฐฐ์—ด์˜ ์ง€์ •๋œ ์œ„์น˜์˜ ํ•ญ๋ชฉ์„ ๋ฐ˜ํ™˜
        - getItemId() : ํŠน์ • ์œ„์น˜์˜ ํ•ญ๋ชฉ ์•„์ด๋””๋ฅผ ๋ฐ˜ํ™˜, ์—ฌ๊ธฐ์„œ๋Š” ๋ฐฐ์—ด์˜ ์œ„์น˜(์ˆœ์„œ)๋ฅผ ํ•ญ๋ชฉ์˜ ์•„์ด๋””๋กœ ๊ฐ„์ฃผ
        - getView() : ์ฒซ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ฃผ์–ด์ง„ ์œ„์น˜์˜ ํ•ญ๋ชฉ ๋ทฐ๋ฅผ ๋ฐ˜ํ™˜
                             mThumbIds ๋ฐฐ์—ด์˜ position ์œ„์น˜์— ์žˆ๋Š” ์ด๋ฏธ์ง€ ๋ฆฌ์†Œ์Šค๋ฅผ ImageView์˜ ์ด๋ฏธ์ง€๋กœ ์„ค์ •
                             ์„ค์ •๋œ ImageView ๊ฐ์ฒด๋ฅผ ๊ทธ๋ฆฌ๋“œ ๋ทฐ์˜ ํ•ญ๋ชฉ๋ทฐ๋กœ ๋ฐ˜ํ™˜
  • getView() ๋ฉ”์†Œ๋“œ์˜ ๋‘๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ์ธ convertView๋Š” ์ด์ „์— ์ƒ์„ฑ๋œ ํ•ญ๋ชฉ๋ทฐ (์—ฌ๊ธฐ์„œ๋Š” ImageView)๋ฅผ ์˜๋ฏธ
    ๋งŒ์•ฝ ํ•ด๋‹น ์œ„์น˜์˜ ํ•ญ๋ชฉ๋ทฐ๊ฐ€ ์ฒ˜์Œ ๋งŒ๋“ค์–ด์ง€๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด, ์ƒˆ๋กœ์šด ์ด๋ฏธ์ง€๋ทฐ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  ํฌ๊ธฐ, ์Šค์ผ€์ผํƒ€์ž…, ํŒจ๋”ฉ ์„ค์ •
    ๋งŒ์•ฝ ์ด์ „์— ์ด๋ฏธ ๋งŒ๋“ค์–ด์ง„ ๊ฒƒ์ด๋ผ๋ฉด, ์ด๋ฅผ ์žฌ์‚ฌ์šฉ
  • ์ด๋ฏธ์ง€ ๋ทฐ์˜ scaleType์€ ์›๋ณธ ์ด๋ฏธ์ง€๋ฅผ ์ด๋ฏธ์ง€ ๋ทฐ์— ๋งž๊ฒŒ ํ™•๋Œ€ ๋ฐ ์ถ•์†Œ์‹œํ‚ฌ ๋•Œ, ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ง€๋ฅผ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์ธ๋ฐ, ์—ฌ๊ธฐ์„œ CENTER_CROP์€ ์ข…ํšก๋น„๋ฅผ ์œ ์ง€ํ•˜์—ฌ ์Šค์ผ€์ผ๋งํ•˜๋ฉฐ ๋ทฐ์˜ ํฌ๊ธฐ ์ด์ƒ์œผ๋กœ ์ฑ„์šฐ๊ฒŒ ๋จ์„ ์˜๋ฏธ
    ๋”ฐ๋ผ์„œ ์ด๋ฏธ์ง€ ์ผ๋ถ€๊ฐ€ ์ž˜๋ฆด ์ˆ˜ ์žˆ์Œ
class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // ImageAdapter ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  GridView ๊ฐ์ฒด์— ์—ฐ๊ฒฐ
        binding.gridview.adapter = ImageAdapter()


    }
}

 

 

 

4. ํ•ญ๋ชฉ ํด๋ฆญ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ

  • AdapterView์˜ ํ•ญ๋ชฉ์ด ํด๋ฆญ ๋  ๋•Œ, ํ˜ธ์ถœ๋˜๋Š” callbackmethod์˜ ์ธํ„ฐํŽ˜์ด์Šค
class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // ImageAdapter ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  GridView ๊ฐ์ฒด์— ์—ฐ๊ฒฐ
        binding.gridview.adapter = ImageAdapter()

        // ํ•ญ๋ชฉ ํด๋ฆญ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ
        binding.gridview.setOnItemClickListener{ parent, view, position, id ->
            Toast.makeText(this@MainActivity,"" + (position + 1) + "๋ฒˆ์งธ ์„ ํƒ",           
                Toast.LENGTH_SHORT).show()
        }
    }
}

 

 

 

 

 

 

๋ฐ˜์‘ํ˜•
 ๐Ÿ’ฌ C O M M E N T