2018년 11월 29일 목요일

[Android] 안드로이드 ListView를 만들어 BaseAdapter를 사용하기.

안드로이드에서 수 많은 리스트들을 관리하는 방법에 대해서 살펴보자.


페이스북이나, 카카오톡 채팅방 같은 수많은 리스트들은 동적으로 생성이 된다.
이러한 리스트들이 어떻게 보여지는지 이번시간에 구현해보도록하겠다.



ListView란?
1개 이상의 리스트들을 보여지도록 설정하는 레이아웃으로 생각하자.



Adapter란?
ListView가 생성이 되면, 이 안에는 수 많은 데이터들이 저장이 될것이다.
어떤 레이아웃이 배치되고 그 안의 데이터는 어떤 데이터가 들어갈것인지 관리해주는 역할을 Adapter가 해준다.


이어서 코드를 통해 살펴보자


다음과 같은 ListView를 만들어보자.

  1.   여러 배경색이 있는 리스트 뷰. (실제 리스트는 3개만 존재하나, 리스트 뷰에는 100개가 보이는것처럼 보임)
  2.   리스트 클릭 시 정보들이 보임. (BaseAdapter를 사용함.)


1) activity_main.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.    xmlns:app="http://schemas.android.com/apk/res-auto"
  4.    xmlns:tools="http://schemas.android.com/tools"
  5.    android:layout_width="match_parent"
  6.    android:layout_height="match_parent"
  7.    tools:context=".MainActivity">
  8.     <ListView
  9.        android:id="@+id/lv"
  10.        android:layout_width="match_parent"
  11.        android:layout_height="wrap_content" />
  12. </android.support.constraint.ConstraintLayout>



2) list_view.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.    android:layout_width="match_parent"
  4.    android:layout_height="wrap_content"
  5.    xmlns:apps="http://schemas.android.com/apk/res-auto">
  6.     <ImageView
  7.        android:id="@+id/iv"
  8.        android:layout_width="100dp"
  9.        android:layout_height="100dp" />
  10.     <TextView
  11.        android:id="@+id/tv"
  12.        android:layout_width="wrap_content"
  13.        android:layout_height="wrap_content"
  14.        apps:layout_constraintStart_toEndOf="@+id/iv"
  15.        apps:layout_constraintTop_toTopOf="@+id/iv"
  16.        apps:layout_constraintBottom_toBottomOf="@+id/iv"
  17.        android:text="텍스트" />
  18. </android.support.constraint.ConstraintLayout>



3) MainActivity.java
  1. package com.example.rhkdg.myapplication;

  2. import android.graphics.Color;
  3. import android.support.v7.app.AppCompatActivity;
  4. import android.os.Bundle;
  5. import android.view.View;
  6. import android.widget.AdapterView;
  7. import android.widget.LinearLayout;
  8. import android.widget.ListView;
  9. import android.widget.Toast;
  10. import java.util.ArrayList;
  11. public class MainActivity extends AppCompatActivity {
  12.     // 보여질 리스트뷰
  13.     private ListView lv;
  14.     // 리스트들의 안에 담을 데이터들을 저장함.
  15.     private ArrayList<ListInfo> arrayList;
  16.     private MyBaseAdapter adapter;
  17.     @Override
  18.     protected void onCreate(Bundle savedInstanceState) {
  19.         super.onCreate(savedInstanceState);
  20.         setContentView(R.layout.activity_main);
  21.         lv = findViewById(R.id.lv);
  22.         arrayList = new ArrayList<>();
  23.         arrayList.add(new ListInfo("빨간색"Color.RED ));
  24.         arrayList.add(new ListInfo("파란색"Color.BLUE));
  25.         arrayList.add(new ListInfo("초록색"Color.GREEN));
  26.         arrayList.add(new ListInfo("노란색"Color.YELLOW));
  27.         // 어댑터를 지정.(각 리스트들의 정보들을 관리해주는 역할을 한다.)
  28.         adapter = new MyBaseAdapter(this, arrayList);
  29.         // 리스트 뷰의 어댑터를 지정한다.
  30.         lv.setAdapter(adapter);
  31.         // 클릭한 리스트의 데이터 정보반환.
  32.         lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
  33.             @Override
  34.             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  35.                 toast(position + "번째 id = " + id);
  36.             }
  37.         });
  38.     }
  39.     public void toast(String msg){
  40.         Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
  41.     }
  42. }



4) MyBaseAdapter.java
  1. package com.example.rhkdg.myapplication;
  2. import android.content.Context;
  3. import android.view.LayoutInflater;
  4. import android.view.View;
  5. import android.view.ViewGroup;
  6. import android.widget.BaseAdapter;
  7. import android.widget.TextView;
  8. import java.util.ArrayList;
  9. public class MyBaseAdapter extends BaseAdapter {
  10.     private ArrayList<ListInfo> data;
  11.     private Context context;
  12.     public MyBaseAdapter(Context context, ArrayList<ListInfo> data){
  13.         this.context = context;
  14.         this.data = data;
  15.     }
  16.         @Override
  17.     public int getCount() {
  18.         return 100; // 실제 데이터는 4개지만, 리스트 뷰가 100개인 것처럼 보임.
  19.     }
  20.     @Override
  21.     public ListInfo getItem(int position) {
  22.         position %= 4; // 0~3의 데이터의 포지션 값으로 지정해야함.
  23.         return data.get(position);
  24.     }
  25.     @Override
  26.     public long getItemId(int position) {
  27.         return position;
  28.     }
  29.     @Override
  30.     public View getView(int position, View convertView, ViewGroup parent) {
  31.         position %= 4; // 0~3의 데이터의 포지션 값으로 지정해야함.
  32.         View v = LayoutInflater.from(context).inflate(R.layout.listviewnull);
  33.         v.findViewById(R.id.iv).setBackgroundColor(data.get(position).getColor());
  34.         TextView tv = v.findViewById(R.id.tv);
  35.         tv.setText(data.get(position).getTitle());
  36.         return v;
  37.     }
  38. }


5) ListInfo
  1. package com.example.rhkdg.myapplication;
  2. public class ListInfo {
  3.     private String title;
  4.     private int color;
  5.     public ListInfo(String title, int color){
  6.         this.title = title;
  7.         this.color = color;
  8.     }
  9.     public String getTitle(){
  10.         return this.title;
  11.     }
  12.     public int getColor(){
  13.         return this.color;
  14.     }
  15. }




▶ 실행화면


(1. 초기화면)
























(2. 노란색 클릭)



























(3. 맨 위 빨간색 클릭)
























(4. 맨 위에서 두번째 파란색 클릭)






















(5. 스크롤 끝)























: 어댑터 뷰를 통해서 다양하게 리스트들의 데이터를 관리하는 방법에 대해서 살펴보았다.
다음에는 ListView의 단점을 보완한 RecyclerView에 대해서 살펴보자.



- ListView뷰의 단점 

MyBaseAdapter부분의 getView()메소드를 보면, findViewById를 수 없이 하게 된다. findViewById는 앱의 성능을 저하시키므로, 이 작업을 시작할 때 미리 등록해 놓으면 이후 리스트를 스크롤할때마다 findViewById를 하지 않게된다. 이것을 보완해서 등장한것이 RecyclerView이다.




댓글 없음:

댓글 쓰기

[Java] N-I/O(Non-Blocking) 파일 읽기 쓰기 - GatheringByteChannel, ScatteringByteChannel, ByteBuffer 사용.

우리는 지금까지 다음과 같이 살펴보았다. 1.  InputStream / OutputStream : 입, 출력 스트림을 바이트로 처리하여 읽기, 쓰기. 2.  FileInputStream / FileOutputStream : 입, 출력 스트림을 ...