각 국가이미지를 클릭했을 때 클릭한 국가에대한 정보가 출력되보도록 하는 작업을 해보겠다.
이렇게 ListView를 만들어 준후에 margin값을 제거해주었다.
그 다음으로 ListView에 연결할 Adapter Class를 만들어준다.
package com.example.step03customadapter;
/*
* ListView에 연결한 adapter 클래스를 정의하고
*
*
*/
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
public class CountryAdapter extends BaseAdapter {
//모델의 갯수를 리턴하는 메서드
@Override
public int getCount() {
return 0;
}
//i번째 index에 해당하는 모델을 리턴
@Override
public Object getItem(int i) {
return null;
}
//i번째 index에 해당하는 모델의 아이디(프라이머리키)가 있다면 리턴 없으면 index를 리턴하여 리턴한 index값을 아이디로사용
@Override
public long getItemId(int i) {
return 0;
}
//i번째 index에 해당하는 cell view를 리턴
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
return null;
}
}
다음으로 국가하나하나의 정보를 담기 위해 DTO를 만들어준다.
그리고 필드와 생성자, Getter,Setter를 만들어준다.
package com.example.step03customadapter;
public class CountryDto {
//필드
private int resId; //출력할 이미지 리소스 아이디 R.id.austria 등등
private String name; //나라의 이름
private String content; //나라에 대한 자세한 설명
//생성자
public CountryDto(){}
public CountryDto(int resId, String name, String content) {
this.resId = resId;
this.name = name;
this.content = content;
}
public int getResId() {
return resId;
}
public void setResId(int resId) {
this.resId = resId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
그러고 난 다음 CountryAdapter에 생성자의 인자로 전달된 값을 필드에 저장할 생성자와 필드를 추가해 준다.
//필드
Context context;
int layoutRes;
List<CountryDto> list;
//생성자 생성 (첫번째 인자로는 Context, 두번째 인자로는 cell의 Layout resource id, 세번째는 모델)
public CountryAdapter(Context context, int layoutRes, List<CountryDto> list){
}
그런다음 MainActivity.java에서 adapter에 연결할 모델 객체 생성과 ListView에 연결할 adapter객체를 생성해준다.
이 때 cell의 Layout resource id는 아직 만들지 않아 기본값인 0을 사용한다.
package com.example.step03customadapter;
import android.os.Bundle;
import android.widget.ListView;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
//필드
List<CountryDto> countries;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//adapter에 연결할 모델 객체를 생성
countries = new ArrayList<>();
//ListView에 연결할 adapter 객체 생성
CountryAdapter adapter = new CountryAdapter(this, 0, countries);
//ListView의 참조값을 얻어와서
ListView listView = findViewById(R.id.listView);
//adapter 연결
listView.setAdapter(adapter);
}
}
다음으로 custom으로 사용할 listview_cell.xml 파일을 만들어준다.
만들어진 xml코드는 아래와 같다.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.constraintlayout.widget.ConstraintLayout>
대충 구상은 아래와 같다
왼쪽 부터 이미지의 거리는 50dp 위아래는 10dp의 거기를 두게 할 것이다.
위처럼 설정해 준다음에 코드를 다시보면 아래와 같다.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="120dp">
<ImageView
android:id="@+id/imageView"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginStart="50dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/belgium" />
</androidx.constraintlayout.widget.ConstraintLayout>
직접 손으로 코드를 짠다면 굉장히 험난 할 것 같다..
그리고 국기 오른쪽에 TextView를 배치해보겠다.
Textview는 오른쪽으로 부터 50dp
ui의 크기는 dp단위 글자의 크기는 sp를 사용한다 dp를 사용하면 해상도와 상관없이 사용가능하다.
코드에서 폰트크기를 30sp로 설정도 해주었다.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="120dp">
<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_marginStart="50dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="101dp"
android:layout_marginBottom="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/textView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/germany" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="50dp"
android:text="TextView"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
이렇게 다 만들어 준 후에 CountryAdapter의 두번째 인자인 cell의 layout resource id를 바꿔준다.
//ListView에 연결할 adapter 객체 생성
CountryAdapter adapter = new CountryAdapter(this, R.layout.listview_cell, countries);
이전 예제를 비교해보겠다.
//step02listview에 있는 adapter 객체 생성코드
//ListView 에 연결할 아답타 객체 생성하기
// new ArrayAdapter<>( Context , layout resource , 모델 )
adapter=new ArrayAdapter<>(
this,
android.R.layout.simple_list_item_1,
names
);
최대한 비슷하게 만들어보았다.
그런 다음 MainAcitivity.java 클래스에 샘플데이터를 넣어준다.
package com.example.step03customadapter;
import android.os.Bundle;
import android.widget.ListView;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
//필드
List<CountryDto> countries;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//adapter에 연결할 모델 객체를 생성
countries = new ArrayList<>();
//셈플데이터
countries.add(new CountryDto(R.drawable.austria,
"오스트리아", "어쩌구.. 저쩌구.."));
countries.add(new CountryDto(R.drawable.belgium,
"벨기에", "어쩌구.. 저쩌구.."));
countries.add(new CountryDto(R.drawable.brazil,
"브라질", "어쩌구.. 저쩌구.."));
countries.add(new CountryDto(R.drawable.france,
"프랑스", "어쩌구.. 저쩌구.."));
countries.add(new CountryDto(R.drawable.germany,
"독일", "어쩌구.. 저쩌구.."));
countries.add(new CountryDto(R.drawable.greece,
"그리스", "어쩌구.. 저쩌구.."));
countries.add(new CountryDto(R.drawable.israel,
"이스라엘", "어쩌구.. 저쩌구.."));
countries.add(new CountryDto(R.drawable.italy,
"이탈리아", "어쩌구.. 저쩌구.."));
countries.add(new CountryDto(R.drawable.japan,
"일본", "🤮"));
countries.add(new CountryDto(R.drawable.korea,
"대한민국", "어쩌구.. 저쩌구.."));
countries.add(new CountryDto(R.drawable.poland,
"폴란드", "어쩌구.. 저쩌구.."));
countries.add(new CountryDto(R.drawable.spain,
"스페인", "어쩌구.. 저쩌구.."));
countries.add(new CountryDto(R.drawable.usa,
"미국", "어쩌구.. 저쩌구.."));
//ListView에 연결할 adapter 객체 생성
CountryAdapter adapter = new CountryAdapter(this, R.layout.listview_cell, countries);
//ListView의 참조값을 얻어와서
ListView listView = findViewById(R.id.listView);
//adapter 연결
listView.setAdapter(adapter);
}
}
package com.example.step03customadapter;
/*
ListView 에 연결할 아답타 클래스 정의하기
- BaseAdapter 추상 클래스를 상속 받아서 만든다.
*/
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 java.util.List;
public class CountryAdapter extends BaseAdapter {
//필드
Context context;
int layoutRes;
List<CountryDto> list;
//생성자 (컨텍스트, cell 의 layout 리소스 아이디, 모델)
public CountryAdapter(Context context, int layoutRes, List<CountryDto> list){
//생성자의 인자로 전달된 값을 필드에 저장한다.
this.context=context;
this.layoutRes=layoutRes;
this.list=list;
}
//모델의 갯수를 리턴 하는 메소드
@Override
public int getCount() {
return list.size();
}
// i 번째 인덱스에 해당하는 모델을 리턴
@Override
public Object getItem(int i) {
return list.get(i);
}
// i 번째 인덱스에 해당하는 모델의 아이디(pk)가 있다면 리턴
@Override
public long getItemId(int i) {
//없으면 인덱스를 리턴
return i;
}
// i 번째 인덱스에 해당하는 cell view 를 리턴하기
/*
인자로 전달되는 i 번째 cell view 를 만들어서 리턴해야 한다.
cell view 는 레이아웃 xml 문서를 전개해서 만들어야 한다.
전개해서 만든 View 의 ImageView 와 TextView 에 적절한 데이터를 출력한다음
View 객체를 리턴해 준다.
cell view 는 모델의 갯수만큼 다 만드는것이 아니라 최소한의 갯수만 만들어서
기존에 만들었던 View 객체를 재사용해야 한다.
*/
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
//만일 null 이면
if(view == null){
//레이아웃 xml 문서를 전개해서 View 객체를 새로 만든다.
LayoutInflater inflater=LayoutInflater.from(context);
view = inflater.inflate(layoutRes, viewGroup, false);
}
// i 에 해당하는 CountryDto 객체
CountryDto dto=list.get(i);
// View 객체 안에 있는 ImageView, TextView 의 참조값을 얻어온다.
ImageView imageView=view.findViewById(R.id.imageView);
TextView textView=view.findViewById(R.id.textView);
// ImageView, TextView 에 정보를 출력한다.
imageView.setImageResource(dto.getResId());
textView.setText(dto.getName());
// i 번째 인덱스에 해당하는 View 를 리턴해 준다.
return view;
}
}
새로 객체를 생성하는지 확인하기 위해 Log를 활용해 보았다 다음사진은 처음 디바이스를 실행했을 때 몇개가 출력되는지 확인해보는 사진이다.
총7개가 출력되었는데 한번 끝까지 내려보면 아래와 같다.
'수업내용' 카테고리의 다른 글
20230721 Android CustomAdapter 2 (0) | 2023.07.21 |
---|---|
20230721 CSS3 Flex (0) | 2023.07.21 |
20230720 CSS3 flex2 (0) | 2023.07.20 |
20230719 Andoroid (0) | 2023.07.19 |
20230719 flex (0) | 2023.07.19 |
댓글