일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- 스프링 시큐리티 없이
- jpa dto 매핑
- 안드로이드 스튜디오
- sops age
- 시크릿 깃에 올리기
- sops 암호화
- java
- multiview
- jpa bulk insert
- springboot
- 쿠버네티스 #fabric8
- 시크릿 암호화
- mysql multi-row insert
- 채팅방 구현
- android studio
- spring 채팅방
- 로또 앱 만들기
- 스프링 환경변수 설정
- 스프링 소셜 로그인
- hibe
- jpa 최적화
- 로또 등수 코드
- sops
- 로또 등수 알고리즘
- 스프링 오어스
- oauth 로그인
- Androoid Studio
- 스프링 환경변수
- 리사이클러뷰 멀티뷰
- 중간 테이블 엔티티 최적화
- Today
- Total
야미의 개발
[Android Studio] Java Recylerview 멀티뷰 구현하기 , viewtype으로 아이템 분류하기 본문
로또앱 안에 날짜별로 아이템들을 분류하는 기능이 필요했다.
보통 multi view를 쓰는 경우는 간단한 대화용 채팅창 구현이나, 아이템 목록이 여러개인 경우에 분류할 때 쓰는거 같지만
이 앱에서는 날짜 아이템과 일반 아이템으로 나누어 목차처럼 구현 해보았다.
전체 코드는 글 마지막에
전체 복붙을 해서 보며 이해 안가는 부분은 아래의 설명을 참조하면 될 듯 싶다.
1.
MadeNumListAdapter
일단 MadeNumListAdapter 파일 부터 코드를 살펴보겠다.
public class MadeNumListAdapter extends RecyclerView.Adapter<MadeNumListAdapter.ViewHolder> {
ArrayList<MadeNumQuery> items = new ArrayList<MadeNumQuery>();
// view type
private int TYPE_DATE = 201;
private int TYPE_LIST = 202;
먼저 아이템들이 담길 리스트를 선언해준다.
여기서 분류해줄 아이템들은 직접 생성한 로또 번호들이기 때문에 MadeNumQuery를 담는 ArrayList를 선언해 주었다.
이후 두개의 아이템을 편하게 분류 하기 위해
날짜를 의미하는 아이템은 TYPE_DATE으로 201을 일반 아이템은 202로 TYPE_LIST의 인덱스를 지정해 주었다.
@NonNull
@Override
public MadeNumListAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View itemView = inflater.inflate(getViewScr(viewType), parent,false);
return new MadeNumListAdapter.ViewHolder(itemView, viewType);
}
@Override
public void onBindViewHolder(@NonNull MadeNumListAdapter.ViewHolder holder, int position) {
MadeNumQuery item = items.get(position);
holder.bind(item);
}
@Override
public void onBindViewHolder(@NonNull MadeNumListAdapter.ViewHolder holder, int position) {
MadeNumQuery item = items.get(position);
holder.bind(item);
}
@Override
public int getItemCount() {
return items.size();
}
public void addItem(MadeNumQuery item) {
items.add(item);
}
public void setItems(ArrayList<MadeNumQuery> items) {
this.items = items;
}
public MadeNumQuery getItem(int position) {
return items.get(position);
}
public void setItem(int position, MadeNumQuery item) {
items.set(position, item);
}
private int getViewScr(int viewType){
if(viewType == TYPE_DATE){
return R.layout.made_num_date;
}else{
return R.layout.made_num_item;
}
}
이 부분에서 유의해야할 부분은 inflater를 통해 xml을 view로 만들어줄 때 뷰 타입에 맞춰 xml를 적용할수 있게 해야한다는 점이다.
따라서 getViewSrc라는 메소드를 사용해 xml 레이아웃 파일을 지정해 주었다.
@Override
public int getItemViewType(int position) {
if (items.get(position).getId() == -1){
return TYPE_DATE;
} else {
return TYPE_LIST;
}
}
또, getItemViewType를 오버라이드 해야지만 아이템 타입을 분류할 수 있는데
이때 아이템을 분류하는 기준을 id로 정했다.
일반적인 아이템은 id값을 가지고 있는 객체이고 날짜를 표현할 아이템은 id = -1 이므로
item.get(position).getId() == -1 인 경우 DTYPE_DATE를 반환해준다
public class ViewHolder extends RecyclerView.ViewHolder{
private int viewType;
public ViewHolder(@NonNull View itemView, int viewType) {
super(itemView);
this.viewType = viewType;
}
}
public void bind(MadeNumQuery item){
if (viewType== TYPE_DATE){
bindDate(item);
} else if(viewType==TYPE_LIST) {
bindItem(item);
}
}
private void bindDate(MadeNumQuery item){
TextView madeDate = itemView.findViewById(R.id.madeDate);
madeDate.setText(item.getDate());
}
private void bindItem(MadeNumQuery item){
String staticT = "총합:" + item.getTotal() + " 짝홀:" + item.getEven() + "/" + (6 - item.getEven());
TextView nums = itemView.findViewById(R.id.nums);
nums.setText(item.numberString());
TextView statics = itemView.findViewById(R.id.staticsMade);
statics.setText(staticT);
}
}
바인드를 할때는 이렇게 아이템의 타입에 따라 바인드를 하는
bindData, bindItem 두가지를 따로 만들어 주었다.
이렇게 하면 아이템들의 리스트가 올바르게 들어오기만 한다면( 위에 언급했던 대로 Date 아이템의 id = -1 인 경우)
어뎁터가 아이템을 잘 분류해 각각의 xml에 맞추어서 정렬해줄 것이다.
이제 acitivity 파일을 보자.
2.
MadeNumListActivity
날짜 아이템이 없는 리스트를 불러와 리스트안에 추가해주는 작업을 하는 내용이 같이 담겨 있다.
public class MadeNumListActivity extends AppCompatActivity {
List<MadeNumQuery> madeQueryList;
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_made_num_list);
RecyclerView recyclerView = findViewById(R.id.madeNum);
// 기본 리스트를 가져옴
getNumberQueryList();
// 스티커를 포함하고 있는 리스트를 생성함
ArrayList<MadeNumQuery> listWithSticker = (ArrayList<MadeNumQuery>) makeSticker();
LinearLayoutManager layoutManager = new LinearLayoutManager(this,LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager);
MadeNumListAdapter adapter = new MadeNumListAdapter();
adapter.setItems(listWithSticker);
recyclerView.setAdapter(adapter);
이 부분은 일반적인 리사이클러뷰와 동일하다. 코드 중간에 있는 날짜 스티커를 생성하는 메소드를 따로 살펴보면
public List<MadeNumQuery> makeSticker(){
List<MadeNumQuery> newList = new ArrayList<>();
String preDate = "1979";
Collections.reverse(madeQueryList);
for(MadeNumQuery numberQuery : madeQueryList){
if(!numberQuery.getDate().equals(preDate)){
newList.add(new MadeNumQuery(-1,numberQuery.getDate(),new int[]{0}));
preDate = numberQuery.getDate();
}
newList.add(numberQuery);
}
return newList;
}
기본 날짜를 1979년으로 설정해 놓고
madeQuery를 하나씩 읽으며 madeQuery에 저장된 날짜값이 변경되는 경우에 id값이 -1인 DATE 아이템을 추가 해주도록 하였다.
전체 코드 //
프로그램의 구현을 위한 다른 코드들은 임의적으로 삭제하였다
package org.techtown.lottoworld.madeNums;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import org.techtown.lottoworld.MadeNumQuery;
import org.techtown.lottoworld.R;
import java.util.ArrayList;
public class MadeNumListAdapter extends RecyclerView.Adapter<MadeNumListAdapter.ViewHolder> {
ArrayList<MadeNumQuery> items = new ArrayList<MadeNumQuery>();
// view type
private int TYPE_DATE = 201;
private int TYPE_LIST = 202;
@NonNull
@Override
public MadeNumListAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View itemView = inflater.inflate(getViewScr(viewType), parent,false);
return new MadeNumListAdapter.ViewHolder(itemView, viewType);
}
@Override
public void onBindViewHolder(@NonNull MadeNumListAdapter.ViewHolder holder, int position) {
MadeNumQuery item = items.get(position);
holder.bind(item);
}
@Override
public int getItemCount() {
return items.size();
}
public void addItem(MadeNumQuery item) {
items.add(item);
}
public void setItems(ArrayList<MadeNumQuery> items) {
this.items = items;
}
public MadeNumQuery getItem(int position) {
return items.get(position);
}
public void setItem(int position, MadeNumQuery item) {
items.set(position, item);
}
private int getViewScr(int viewType){
if(viewType == TYPE_DATE){
return R.layout.made_num_date;
}else{
return R.layout.made_num_item;
}
}
@Override
public int getItemViewType(int position) {
if (items.get(position).getId() == -1){
return TYPE_DATE;
} else {
return TYPE_LIST;
}
}
public class ViewHolder extends RecyclerView.ViewHolder{
private int viewType;
public ViewHolder(@NonNull View itemView, int viewType) {
super(itemView);
this.viewType = viewType;
}
}
public void bind(MadeNumQuery item){
if (viewType== TYPE_DATE){
bindDate(item);
} else if(viewType==TYPE_LIST) {
bindItem(item);
}
}
private void bindDate(MadeNumQuery item){
TextView madeDate = itemView.findViewById(R.id.madeDate);
madeDate.setText(item.getDate());
}
private void bindItem(MadeNumQuery item){
String staticT = "총합:" + item.getTotal() + " 짝홀:" + item.getEven() + "/" + (6 - item.getEven());
TextView nums = itemView.findViewById(R.id.nums);
nums.setText(item.numberString());
TextView statics = itemView.findViewById(R.id.staticsMade);
statics.setText(staticT);
}
}
}
package org.techtown.lottoworld.madeNums;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import org.techtown.lottoworld.DataAdapter;
import org.techtown.lottoworld.MadeNumQuery;
import org.techtown.lottoworld.NumberQuery;
import org.techtown.lottoworld.R;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MadeNumListActivity extends AppCompatActivity {
List<MadeNumQuery> madeQueryList;
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_made_num_list);
RecyclerView recyclerView = findViewById(R.id.madeNum);
//리스트 불러옴
getNumberQueryList();
//DATE 아이템 포함한 리스트 생성
ArrayList<MadeNumQuery> listWithSticker = (ArrayList<MadeNumQuery>) makeSticker();
LinearLayoutManager layoutManager = new LinearLayoutManager(this,LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager);
MadeNumListAdapter adapter = new MadeNumListAdapter();
adapter.setItems(listWithSticker);
recyclerView.setAdapter(adapter);
}
public int getNumberQueryList(){
int round = 0;
try {
DataAdapter mDbAdapter = new DataAdapter(getApplicationContext());
mDbAdapter.open();
// db에 있는 값들을 model을 적용해서 넣는다.
madeQueryList = mDbAdapter.getMadeNums();
// db 닫기
mDbAdapter.close();
} catch (SQLException e) {
e.printStackTrace();
}
return round;
}
public List<MadeNumQuery> makeSticker(){
List<MadeNumQuery> newList = new ArrayList<>();
String preDate = "1979";
Collections.reverse(madeQueryList);
for(MadeNumQuery numberQuery : madeQueryList){
if(!numberQuery.getDate().equals(preDate)){
newList.add(new MadeNumQuery(-1,numberQuery.getDate(),new int[]{0}));
preDate = numberQuery.getDate();
}
newList.add(numberQuery);
}
return newList;
}
public void deleteNum(long id){
try {
DataAdapter mDbAdapter = new DataAdapter(getApplicationContext());
mDbAdapter.open();
mDbAdapter.deleteMadeNum(id);
mDbAdapter.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
'안드로이드 > 로또 앱' 카테고리의 다른 글
[Android Studio] JAVA 로또 등수 확인 알고리즘 코드 | 로또 번호로 과거 등수 내역 확인하기 (0) | 2023.01.07 |
---|---|
[Android Studio] Java int형 배열 Activity 간 전달 (0) | 2023.01.07 |
[Android Studio] Java Recylerview 뷰페이징 (0) | 2023.01.03 |
로또 앱 개발 개요 (0) | 2023.01.03 |