본문 바로가기

안드로이드

ListView (RecyclerView를 쓰는 이유를 알기위해서)

아래와 같이 확장

ScrollerView(100/100) -> ListView(7/100) -> RecyclerView (p416)

 

ListView는 메모리 관리가 됩니다. 어떻게?

화면 크기(길이)500를 계산하고 하나의 View의 크기100를 계산 합니다. 그래야 한 화면에 몇 개 까지 들어가는 지 계산한다.

5개 까지 들어가는 화면인데 스크롤하면 6번이 걸쳐 지키도 하기 떄문에 여유로 몇개 더 메모리에 띄워져 있다. 7개

 

 

ListView는 ScrollerView랑 똑같은데 강제성이 하나 있어요. Adapter를 사용하도록 강제성이 부여되어 있어요. 장점은 메모리 관리가 됩니다.

 

어댑터는 전체 데이터가 몇 건이지를 알아야함 = collection(size, 번호) 그리고 화면 사이즈(길이)가 얼마인지도 알고 있고 View 크기도 알고 있다. 인덱스 번호를 확인할 수 있다. 

 

어댑터의 역할 - 스크롤할 때 데이터 바인딩을 하는 역할을 한다. 7개! 그리고 1~5번까지 생성된 디자인에다가 데이터를 입혀줍니다. 스크롤 내리면 6~10번, 메모리에는12번까지.

 

 

 

<LinearLayout 안에 <ListView 만들어 넣어요

 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    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:id="@+id/main_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    
    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

 

MainActivity.java

package com.linda.listviewex01;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.material.snackbar.Snackbar;

import java.util.Arrays;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "Main_Activity";
    private Context mContent = MainActivity.this;
    private ListView listView;

    private ArrayAdapter<String> adapter;
    private List<String> mid = Arrays.asList(
      "히어로즈", "24시", "로스트", "프렌즈", "글리", "빅뱅이론",
      "히어로즈", "24시", "로스트", "프렌즈", "글리", "빅뱅이론",
            "해리포터", "어바웃타임", "노트북", "서약"
    );

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

        listView = findViewById(R.id.list_view);
        adapter = new ArrayAdapter<>(mContent, android.R.layout.simple_list_item_1, mid);
        //내 컨텍스트(어떤 액티비티), 디자인(사이즈를 알기위해서), 데이터
        listView.setAdapter(adapter);

    }
}

 

 

 

private List<String> mid = Arrays.asList("", "", "", "", ~~);

 

String만 들어오는 배열에 데이터들을 ArrayAdapter가 데이터 바인딩해서 그려준다.

 

하지만 커스터마이징안 된 이거 잘 안쓴다. 별로 안예뻐요!

 


이번에는 내가 이 ListView를 만들어보자!

 

Adapter도 내가 만든다

 

BaseAdapter를 extends 해서 내가 만들 SingleAdapter를 만든다.

alt + enter해서 implement한다. 함수 5개 오버라이드 된다.

 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    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:id="@+id/main_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    
    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

 

item.xml

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

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="99dp"
        android:text="의미없음"
        android:textSize="30sp"
        android:textStyle="bold"
        android:gravity="center"/>

    <View
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#454242"/>

</RelativeLayout>

 

SingleAdapter.java

package com.linda.listviewex01;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class SingleAdapter extends BaseAdapter {
    private static final String TAG = "Single_Adapter";

    private List<String> items = new ArrayList<>();


    //한번에 데이터 가져오기
    public void addItems(List<String>items){
        this.items = items;
    }

    //필수
    @Override
    public int getCount() {
        Log.d(TAG, "getCount: ");
        return items.size();//화면에 최초에 몇건을 만들 지
    }

    //필수
    @Override
    public Object getItem(int position) {
        Log.d(TAG, "getItem: ");
        return items.get(position); //몇 번째 아이템=그 번호에 해당하는 아이템
    }

    //옵션
    @Override
    public long getItemId(int position) {
        Log.d(TAG, "getItemId: ");
        return position;
    }

    //필수 - 제일 중요한 view를 생성하는 함수
    //최초에 onCreat될 때 아이템 몇개 그려질지 그리고 스크롤하면 몇개 더 아이템을 그리는 일은 한다. 그때 마다 호출됨.
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Log.d(TAG, "getView: "+position);
        //xml파일이 연결된 .java파일이 아니니까 inflate해야 한다.
        LayoutInflater inflater = LayoutInflater.from(parent.getContext()); //p423
        //parent는 ListView를 말한다. item.xml에 item을 activity_main.xml에 ListView에 inflate한다.
        View itemView = inflater.inflate(R.layout.item, parent, false);
        TextView tv=itemView.findViewById(R.id.textView);
        tv.setText(getItem(position).toString()); //이 포지션의 데이터를 넣어줌.
        return itemView;
    }
}

 

MainActivity.java

package com.linda.listviewex01;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;

import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.material.snackbar.Snackbar;

import java.util.Arrays;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "Main_Activity";
    private Context mContent = MainActivity.this;
    private ListView listView;
    private SingleAdapter adapter;

    private List<String> items = Arrays.asList(
            "히어로즈", "24시", "로스트", "프렌즈", "글리", "빅뱅이론",
            "히어로즈", "24시", "로스트", "프렌즈", "글리", "빅뱅이론",
            "해리포터", "어바웃타임", "노트북", "서약"
    );


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

        listView = findViewById(R.id.list_view);
        adapter = new SingleAdapter();

        adapter.addItems(items);//SingleAdapter.java에 List에 데이터 넣어줌.

        listView.setAdapter(adapter);
    }
}

 

 

Adapter의 단점 : 쓸데없는 연산이 너무 많음. view를 계속 그리고 있다. 더 좋은건 

 

껍데기 (view)는 놔두고 데이터만 바꿔준다면 엄청 좋을텐데~!

 

이게 RecyclerView다! 내일 연결해서 배우자!