CustomListView 코틀린 전환하기

 

 

 

CustomListView를 java에서 사용하는 방법

2020/10/27 - [대외 활동/CADI(개발A 보충스터디)] - CustomListView - 1(java)

 

CustomListView - java

CustomListView 구현 CustomListview는 아이템을 별도의 xml로 만들고 그것을 Listview에 적용시켜서 사용하는 것이다. 간단한 문장이나 하나의 아이템만 보여주는 Listview와 달리 아이템을 더 추가하여 리스

dev-seungwon.tistory.com

 

 

 

위의 코드에서 xml부분은 동일하다. 따라서 java->kt파일로 변환된 모습만 살펴보자.

 

 

동일하게 총 3개의 .kt파일을 만들고 기능은 java와 같다.

 

 

 

Adapter에서의 핵심은 findViewById()함수를 사용해 선언할 필요가 없다는 점과 java와 비교하여 보다 간결해진 코드이다.

 

 

ListViewAdpater.kt

class ListViewAdapter : BaseAdapter() {
private val listViewItemList : List<ListViewItem>()
    override fun getCount(): Int {
        return listViewItemList.size
    }

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

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

    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
        var convertView = convertView
        val pos = position
        val context = parent!!.context

        if (convertView == null)
        {
            val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
            convertView = inflater.inflate(R.layout.listview_item, parent, false)
        }

        val listViewItem: User = listViewItemList[pos]

        convertView!!.imageView1.setImageDrawable(listViewItem.icon)
        convertView.tv_title.text = listViewItem.title
        convertView.tv_desc.text = listViewItem.desc
        
        return convertView
    }
    
    fun addItem(icon: Drawable?, title: String?, desc: String?) {
        val item = ListViewItem() // 하나의 리스트 항목을 하나의 객체로 간주함
        item.title
        item.desc
        item.icon
        listViewItemList.add(item)
    }


}

 

 

 

 

MainActivity와 ListViewItem부분도 코드가 간결해졌다.

 

MainActivity.kt

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val listview: ListView
        val adapter = ListViewAdapter()

         listview = findViewById<View>(R.id.listView_Shape) as ListView
        listview.adapter = adapter

        // 첫 번째 아이템 추가.
        adapter.addItem(ContextCompat.getDrawable(this, R.drawable.instagram), "instagram", "this is instagram")

        // 두 번째 아이템 추가.
        adapter.addItem(ContextCompat.getDrawable(this, R.drawable.youtube), "youtube", "this is youtube")

        // 세 번째 아이템 추가.
        adapter.addItem(ContextCompat.getDrawable(this, R.drawable.facebook), "facebook", "this is facebook")

        listview.onItemClickListener =
            OnItemClickListener { parent, v, position, id ->
                val item: ListViewItem = parent.getItemAtPosition(position) as ListViewItem
                Toast.makeText(applicationContext, item.title, Toast.LENGTH_LONG).show()
            }
    }
}

 

 

ListViewItem.kt

class ListViewItem() {
    val icon: Drawable? =null
    val title: String? =null
    val desc: String?=null
}

 

 

 

실행결과 java버전과 똑같이 나온다.

 

CustomListView를 사용하는 방법을 알아보았다.

2020/10/27 - [대외 활동/CADI(개발A 보충스터디)] - CustomListView - java

 

CustomListView - java

CustomListView 구현 CustomListview는 아이템을 별도의 xml로 만들고 그것을 Listview에 적용시켜서 사용하는 것이다. 간단한 문장이나 하나의 아이템만 보여주는 Listview와 달리 아이템을 더 추가하여 리스

dev-seungwon.tistory.com

하지만 ViewHolder를 사용하지 않았을 때의 문제는 list에 추가될때마다 새롭게 view들을 다시 만든다는 것이다.

setTag/getTag를 통해 FindViewByID()를 하지 않아도 이용할 수 있다.

 

우선 위의 예제에서 ViewHolder 클래스와 몇가지 기능만 바꾸면 된다. 따라서 위의 CustomListView구현 방법을 알고 난 후 추가하면 된다.

 

먼저 ViewHolder클래스를 하나 생성한 후

 

ViewHolder에는 각 컴포넌트의 View 원형을 정의하면 된다.

ViewHolder.java

이후 ListViewAdapter에서 이 부분만 수정하면 끝난다.

holder를 convertView가 만들어질 때에만 생성하게 하기 때문에 위에서 말한 findViewById를 계속 호출하지 않아도 된다는 장점을 가지고 있다

 

 

결과는 똑같이 나옴

 

CustomListView 구현

CustomListview는 아이템을 별도의 xml로 만들고 그것을 Listview에 적용시켜서 사용하는 것이다.

간단한 문장이나 하나의 아이템만 보여주는 Listview와 달리 아이템을 더 추가하여 리스트를 보여주는 장점이 있다.

 

 

 

 

 

우선 xml을 만든다.(res->layout에서 원하는 이름으로 xml을 만든다!)

xml을 한칸의 list를 보여줄 item들로 채운다.(이미지,이름,상세정보 등등)

 

 

 

listview_item.xml

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

    <!-- CustomListView 아이템 각 요소별 항목 배치 -->
    <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:id="@+id/imageView1"
        android:layout_weight="0.5" />

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_weight="4">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="New Text"
            android:id="@+id/textView1"
            android:textSize="24dp"
            android:textColor="#000000"
            android:gravity="center_vertical"
            android:layout_weight="2" />

        <TextView
            android:id="@+id/textView2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="New Text"
            android:textColor="#666666"
            android:textSize="16dp" />
    </LinearLayout>
</LinearLayout>

 

 

만든후 총 두개의 java파일을 만들 것이다.

하나는 ListView아이템 요소들과 하나는 그것을 Main에 연결시켜주는 Adapter이다.

 

 

ListViewItem.java

import lombok.Getter;
import lombok.Setter;

// xml 파일에서 생성한 View 객체에 뿌려줄 데이터 클래스를 정의하는 부분
@Setter
@Getter
public class ListViewItem
{
    private Drawable icon ;
    private String title ;
    private String desc ;
    // ? - lombok을 이용하여 getter와 setter 없애기
}

 

여기서 Lombok을 이용하여 getter,setter를 간결화 할 수 있다.

2020/09/22 - [대외 활동/CADI(개발A 보충스터디)] - 룸복(Lombok),제이유닛(Junit),log4j & slf4j 설명!

 

룸복(Lombok),제이유닛(Junit),log4j & slf4j 설명!

룸복(Lombok) 룸복(Lombok)이란 자바에서 model object를 만들때 멤버필드에 대한 Getter,Setter,ToString등 과 같이 불필요하게 반복적으로 만드는 코드를 어노테이션화하여 간결화시키는 라이브러리이

dev-seungwon.tistory.com

 

 

 이 ListViewAdapter에서 만든 addItem함수를 통해 Main에서 list를 추가할 수 있다.

여기서 중요한 것은 @Override가 표시된 부분은 BaseAdapter를 상속할때 반드시 필요한 부분이다!

public class ListViewAdapter extends BaseAdapter
{
    // Adapter에 추가된 데이터를 저장하기 위한 ArrayList
    private ArrayList<ListViewItem> listViewItemList = new ArrayList<ListViewItem>() ;

    // 기본 생성자를 통한 초기화
    // ? - lombok을 이용하여 기본 생성자 부분 없애기
    public ListViewAdapter()
    {
    }

    // Adapter에 사용되는 데이터의 개수를 Return함 : Input되는 데이터 항목의 개수
    @Override
    public int getCount()
    {
        return listViewItemList.size();
    }

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

    @Override
    public long getItemId(int position) //위치값 리턴
    {
        return position;
    }

    // 지정된 Position에 위치한 데이터를 화면에 출력하는데 사용할 View를 불러와 Return
    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        final int pos = position;
        final Context context = parent.getContext();

        // "listview_item" Layout을 inflate하여 convertView 참조 획득.
        if (convertView == null)//틀이 아직 안만들어져있으면
        {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.listview_item, parent, false);
        }

         // 다음주 리사이클러 뷰에서 사용함! (ViewHolder 패턴)
        //할때마다 선언하는 것이 아니라 3개를 하나의Tag로 간주해서 setTag를 통해 효율을 높인다.

        // 화면에 표시될 View(Layout이 inflate된)로부터 위젯에 대한 참조 획득
        ImageView iconImageView = (ImageView) convertView.findViewById(R.id.imageView1) ; //만든 틀에서만 findView한다
        TextView titleTextView = (TextView) convertView.findViewById(R.id.textView1) ;
        TextView descTextView = (TextView) convertView.findViewById(R.id.textView2) ;

        // Data Set(listViewItemList)에서 position에 위치한 데이터 참조 획득
        ListViewItem listViewItem = listViewItemList.get(position);

        // 아이템 내 각 위젯에 데이터 반영
        iconImageView.setImageDrawable(listViewItem.getIcon());
        titleTextView.setText(listViewItem.getTitle());
        descTextView.setText(listViewItem.getDesc());

        return convertView;
    }


    //baseAdapater에 정의된 기능이 아님 별도로 추가
    // 아이템 데이터 추가를 위한 함수. 개발자가 원하는대로 작성 가능.
    public void addItem(Drawable icon, String title, String desc)
    {
        ListViewItem item = new ListViewItem(); // 하나의 리스트 항목을 하나의 객체로 간주함

        item.setIcon(icon);
        item.setTitle(title);
        item.setDesc(desc);

        listViewItemList.add(item);
    }
}

 

만든후 마지막으로 MainActivity에서 사용하면 끝!(클릭했을때 토스트 메세지도 나오게 함)

public class MainActivity extends AppCompatActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ListView listview ;
        ListViewAdapter adapter;

        // Adapter 생성
        adapter = new ListViewAdapter() ;

        // 리스트뷰 참조 및 Adapter달기
        listview = (ListView) findViewById(R.id.listView_Shape);
        listview.setAdapter(adapter);

        // 첫 번째 아이템 추가.
        adapter.addItem(ContextCompat.getDrawable(this, R.drawable.instagram), "instagram", "this is instagram");

        // 두 번째 아이템 추가.
        adapter.addItem(ContextCompat.getDrawable(this, R.drawable.youtube), "youtube", "this is youtube");

        // 세 번째 아이템 추가.
        adapter.addItem(ContextCompat.getDrawable(this, R.drawable.facebook), "facebook", "this is facebook");

        // 위에서 생성한 listview에 클릭 이벤트 핸들러 정의.
        // 아이템을 클릭할 때의 이벤트 리스너를 등록함
        listview.setOnItemClickListener(new AdapterView.OnItemClickListener()
        {
            // AdapterView : 카카오톡 화면과 같이 일정한 디자인 패턴을 갖고 있는 항목
            @Override
            public void onItemClick(AdapterView parent, View v, int position, long id)
            {
                // Posistion에 위치한 값을 가져와 변수에 저장하여 사용가능
                ListViewItem item = (ListViewItem) parent.getItemAtPosition(position);

                Toast.makeText(getApplicationContext(), item.getTitle(), Toast.LENGTH_LONG).show();
            }
        });
    }
}

 

 

 

마지막으로 Main화면의 xml부분은 Listview를 사용하면 된다.

 

 

>>결과물

 

 

+ Recent posts