오늘이라도
[Android] 20. 리스트 뷰(List View) ② : 리스트 출력, 선택 항목 하이라이트, 항목 추가 본문
취업성공패키지 SW 개발자 교육/Android
[Android] 20. 리스트 뷰(List View) ② : 리스트 출력, 선택 항목 하이라이트, 항목 추가
upcake_ 2020. 6. 2. 10:32반응형
https://github.com/upcake/Class_Examples
교육 중에 작성한 예제들은 깃허브에 올려두고 있습니다.
gif 파일은 클릭해서 보는 것이 정확합니다.
- 리스트 뷰(List View) ② : 리스트 출력, 선택 항목 하이라이트, 항목 추가 -
▼activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="추가"
android:textSize="24sp" />
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:listSelector="@android:color/holo_blue_bright"/>
</LinearLayout>
▼MainActivity.java
package com.example.my27_listview2;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
/*
1. DB를 만든다
2. DB의 테이블과 똑같은 DTO를 만든다
3. DTO에서 표현하고자 하는 부분을 xml로 만든다
4. 어댑터를 만든다
5. 어댑터에 3에서 만든 xml을 표시할 ViewHolder Class를 만든다
5 - 1 : ViewHolder 작성
5 - 2 : xml 찾기
5 - 3 : getItem > Data 넣기
5 - 4 : 필요한 메서드 만든다.
메인 액티비티 - 리스트 뷰(껍데기)
껍데기에 내용물을 만들어서 보여주는 것이 어댑터
*/
public class MainActivity extends AppCompatActivity {
//객체 선언
Button button1;
ListView listView;
ArrayList<SingerDTO> list;
SingerAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//객체 초기화
button1 = findViewById(R.id.button1);
listView = findViewById(R.id.listView);
list = new ArrayList<>();
//어댑터의 list에 데이터 추가
adapter = new SingerAdapter(MainActivity.this, list);
adapter.addDTO(new SingerDTO("가수1", "010-1111-1111", 30, R.drawable.singer1));
adapter.addDTO(new SingerDTO("가수2", "010-2222-2222", 21, R.drawable.singer2));
adapter.addDTO(new SingerDTO("가수3", "010-3333-3333", 25, R.drawable.singer3));
adapter.addDTO(new SingerDTO("가수4", "010-4444-4444", 33, R.drawable.singer4));
adapter.addDTO(new SingerDTO("가수5", "010-5555-5555", 38, R.drawable.singer5));
//리스트뷰에 어댑터를 붙여준다
listView.setAdapter(adapter);
//리스트뷰의 아이템 클릭했을때 이벤트 추가
//AdapterView<?> parent : 클릭이 발생한 어댑터뷰
//View view : 어댑터뷰 내부의, 클릭이 된 바로 그 뷰
//int position : 어댑터 내부의 그 뷰의 위치(position)
//long id : 클릭된 아이템의 row id
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
SingerDTO dto = (SingerDTO) adapter.getItem(position);
Toast.makeText(MainActivity.this, "선택 : " + position + "\n이름 : " + dto.getName()
+ "\n전화번호 : " + dto.getPhoneNum() +"\n나이 : " + dto.getAge() + "\n이미지 : " +dto.getResId(), Toast.LENGTH_SHORT).show();
}
});
//버튼1(추가 버튼)에 기능 추가
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String name = "가수6";
String phoneNum = "010-6666-6666";
int age = 35;
int resId = R.mipmap.ic_launcher;
SingerDTO dto = new SingerDTO(name, phoneNum, age, resId);
adapter.addDTO(dto);
//adapter.addDTO = (new SingerDTO(name, phoneNum, age, resId));
//adapter.addDTO = (new SingerDTO("가수6", "010-6666-6666", 35, R.mipmap.ic_launcher);
//리스트뷰 데이터 갱신
adapter.notifyDataSetChanged();
}
});
}
}
▼SingerAdapter.java
package com.example.my27_listview2;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
public class SingerAdapter extends BaseAdapter {
//어댑터에 데이터를 받기위해 생성자 만든다.
// 컨텍스트와 리스트는 받아오지만 인플레이터는 안받아온다.
Context context;
ArrayList<SingerDTO> list;
LayoutInflater inflater;
public SingerAdapter(Context context, ArrayList<SingerDTO> list) {
this.context = context;
this.list = list;
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//인플레이터는 시스템에서 가져온다.
}
//리스트(list)에 항목을 추가해 줄 메서드 작성
public void addDTO(SingerDTO dto) {
list.add(dto);
}
//리스트의 항목을 삭제할 메서드 작성
public void delDTO(int position) {
list.remove(position);
}
//리스트의 항목을 모두 삭제할 메서드 작성
public void removeDTOs() {
list.clear();
}
//getCount() : 리스트에서 항목을 몇개나 가져와서 몇개의 화면을 만들 것인지 정하는 메서드
@Override
public int getCount() {
return list.size();
}
//getItem() : 리스트에서 해당하는 인덱스의 데이터(사진, 이름, 전번)를 모두 가져오는 메서드
//Object를 알아서 캐스팅해서 사용하라는 의미로 반환 타입이 Object
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
SingerViewHolder viewHolder;
//화면 구성
if(convertView == null) {
convertView = inflater.inflate(R.layout.singerview, parent, false);
viewHolder = new SingerViewHolder();
viewHolder.tvName = convertView.findViewById(R.id.tvName);
viewHolder.tvPhoneNum = convertView.findViewById(R.id.tvPhoneNum);
viewHolder.imageView = convertView.findViewById(R.id.imageView);
convertView.setTag(viewHolder);
} else {
viewHolder = (SingerViewHolder) convertView.getTag();
}
//DTO에서 데이터를 찾음
SingerDTO dto = list.get(position);
String name = dto.getName();
String phoneNum = dto.getPhoneNum();
int resId = dto.getResId();
//XML의 화면에 찾은 데이터 표시
viewHolder.tvName.setText(name);
//viewHolder.tvName.setText(dto.getName()); // 이렇게 써도 같음
viewHolder.tvPhoneNum.setText(phoneNum);
viewHolder.imageView.setImageResource(resId);
//이미지만 클릭했을때 번호, 이름만 표시되게 기능 추가
viewHolder.imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, "선택 : " + position
+ ", 이름 : " + list.get(position).getName(), Toast.LENGTH_SHORT).show();
}
});
return convertView;
}
//따로 새 자바 파일을 만들지 않고 XML의 내용을 볼 수 있게끔 만든 클래스
public class SingerViewHolder {
public ImageView imageView;
public TextView tvName, tvPhoneNum;
}
}
▼SingerDTO.java
package com.example.my27_listview2;
public class SingerDTO {
String name;
String phoneNum;
int age;
int resId;
public SingerDTO() {}
public SingerDTO(String name, String phoneNum, int age, int resId) {
this.name = name;
this.phoneNum = phoneNum;
this.age = age;
this.resId = resId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhoneNum() {
return phoneNum;
}
public void setPhoneNum(String phoneNum) {
this.phoneNum = phoneNum;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getResId() {
return resId;
}
public void setResId(int resId) {
this.resId = resId;
}
}
▼singerview.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="match_parent">
<ImageView
android:id="@+id/imageView"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/singer1"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:orientation="vertical">
<TextView
android:id="@+id/tvName"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:gravity="center_vertical"
android:text="Name"
android:textColor="@android:color/holo_green_light"
android:textSize="35sp" />
<TextView
android:id="@+id/tvPhoneNum"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:gravity="center_vertical"
android:text="PhoneNum"
android:textColor="@android:color/holo_orange_light"
android:textSize="25sp" />
</LinearLayout>
</LinearLayout>
반응형