일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- PostgreSQL
- speechAPI
- cmd명령어
- 안드로이드
- 이행은이미다른테이블에속해있습니다
- 청소년복지론
- 자바스크립트for문
- sqlite
- 장고
- 장고프로젝트
- webkitrecognition
- 장고웹프로젝트
- Python
- 자바스크립트날짜
- 파이썬
- 자바스크립트수학
- 자바스크립트forinforof차이
- forof문
- 사례관리
- 오류종류
- 자바스크립트날짜get
- javaScriptError
- speechtoText
- Android
- 장고웹
- 이행은이미다른
- R데이터분석
- 다른테이블에속해있습니다
- 개발
- 자바스크립트날짜형식
- Today
- Total
EMDI는 지금도 개발중
Android : RecyclerView 활용 데이터 추가 본문
1. RecyclerView란?
ListView의 기능을 보완하기 위해서 만들어진 뷰. 기존의 ListView에서 레이아웃 매니저를 추가하여 리스트 타입을 쉽게 변경할 수 있습니다. 또한 ListView와 다르게 Viewholder의 사용이 필수적입니다.
2. RecyclerView활용하기
1) build.gradle (Module: app) 또는 activity_main.xml에서 recyclerView추가하기
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
}
RecyclerView를 사용하기 위해서는 build.gradle에 implementation 'androidx.recyclerview:recyclerview:1.1.0'이 들어가 있어야 합니다. 위와 같이 dependencies에 직접 입력하셔도 되고, activity_main.xml 디자인에서 RecyclerView 다운로드 버튼을 클릭하면 자동으로 dependencies에 추가되니 둘 중 원하시는 방법으로 추가해주세요.
activity_main.xml에서 RecyclerView를 추가하는 방법은 res > layout > activity_main.xml 경로로 들어가신 다음 Palette - Common안에 있는 RecyclerView를 추가해주시면 됩니다.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvCertList"
android:layout_width="475dp"
android:layout_height="245dp"
android:layout_marginStart="1dp"
android:layout_marginLeft="1dp"
android:layout_marginTop="1dp"
android:layout_marginEnd="1dp"
android:layout_marginRight="1dp"
android:layout_marginBottom="11dp" />
<EditText
android:id="@+id/txtPassword"
android:layout_width="241dp"
android:layout_height="wrap_content"
android:layout_below="@+id/rvCertList"
android:layout_marginStart="31dp"
android:layout_marginLeft="31dp"
android:layout_marginTop="22dp"
android:layout_marginEnd="17dp"
android:layout_marginRight="17dp"
android:ems="10"
android:inputType="textPassword" />
<Button
android:id="@+id/btnOK"
android:layout_width="wrap_content"
android:layout_height="62dp"
android:layout_below="@+id/rvCertList"
android:layout_marginStart="5dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="29dp"
android:layout_marginRight="29dp"
android:layout_marginBottom="403dp"
android:layout_toEndOf="@+id/txtPassword"
android:layout_toRightOf="@+id/txtPassword"
android:text="확인" />
</RelativeLayout>
위의 소스는 activity_main.xml의 소스입니다. 소스를 보시면 알 수 있듯이 RecyclerView뿐만 아니라 테스트를 하기 위해 필요한 Button과 TextBox도 생성하였습니다.
- RecyclerView id : rvCertList
- EditText id : txtPassword
- Button id : btnOk
2) RecyclerView에 반복적으로 뿌릴 List! activity_list.xml 생성하기
activity_list.xml
<?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="wrap_content"
tools:context=".MainActivity">
<TextView
android:id="@+id/certNm"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="발급대상"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/certRegorg"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:layout_marginLeft="24dp"
android:padding="5dp"
android:text="발급자"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintLeft_toRightOf="@id/certNm"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.004" />
<TextView
android:id="@+id/certType"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:layout_marginLeft="24dp"
android:padding="5dp"
android:text="구분"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_weight="3"
app:layout_constraintLeft_toRightOf="@id/certRegorg"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.008" />
<TextView
android:id="@+id/certExpdate"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:layout_marginRight="24dp"
android:padding="5dp"
android:text="만료일자"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_weight="3"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
그 다음은 RecyclerView에 반복적으로 뿌려줄 아이템 레이아웃을 생성합니다. 보통 activity_main.xml은 프로젝트를 생성하면 기본적으로 갖춰져있는데 이 activity_list.xml은 제가 따로 생성한 파일입니다. 만드는 방법은 res > layout 폴더에 우클릭한다음 New > Layout resource file을 선택!
저는 이제 인증서목록을 RecyclerView에 뿌리는 테스트를 하고 싶어서 각 TextView의 이름들을 인증서 정보에 맞게 설정하였습니다.
3) MainActivity.java에 코드 추가
RecyclerView는 기본적으로 RecylcerView, Adapter, LayoutManager 총 3개로 구성되어있습니다. View와 View-data를 binding 해주는 Adapter, 그리고 그 배치 형태를 잡아주는 LayoutManager.
MainActivity.java
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
RecyclerAdapter adapter;
RecyclerView.LayoutManager layoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
우선 위의 소스와 같이 3개를 추가해줍니다. 아마 다른것과 다르게 RecyclerAdapter는 빨간줄이 뜰겁니다. 이 오류는 나중에 사라지는 오류이니 너무 신경쓰지 마세요.
제가 만들려고 하는 결과물입니다. 보시다시피 Row에 있는 하나 하나가 RecyclerView에 해당하는 아이템입니다. 이 아이템에 관련된 클래스의 이름은 저는 ListActivity로 지정하였습니다.
ListActivity.java
package com.myapp.certlist;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
public class ListActivity {
public String path ;
public String cn1;
public String cn;
public String ou;
public String o;
public String c;
public String date;
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getCn1() {
return cn1;
}
public void setCn1(String cn1) {
this.cn1 = cn1;
}
public String getCn() {
return cn;
}
public void setCn(String cn) {
this.cn = cn;
}
public String getOu() {
return ou;
}
public void setOu(String ou) {
this.ou = ou;
}
public String getO() {
return o;
}
public void setO(String o) {
this.o = o;
}
public String getC() {
return c;
}
public void setC(String c) {
this.c = c;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public ListActivity(String certName, String certReg, String certType, String certExpDate) {
this.cn = certName;
this.o = certReg;
this.ou = certType;
this.date = certExpDate;
}
@Override
public String toString() {
return path;
}
}
아이템의 클래스도 생성하였으니 이제 다시 MainActivity로 돌아가서 해당 ListActivity와 연관된 리스트를 만들어줍니다.
MainActivity.java
public class MainActivity extends AppCompatActivity {
// 추가사항
private ArrayList<ListActivity> listBundle = new ArrayList<>();
private RecyclerView recyclerView;
private RecyclerAdapter adapter;
private RecyclerView.LayoutManager layoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//추가사항
recyclerView = (RecyclerView) findViewById(R.id.rvCertList);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
((LinearLayoutManager) layoutManager).setReverseLayout(true);
((LinearLayoutManager) layoutManager).setStackFromEnd(true);
recyclerView.setLayoutManager(layoutManager);
adapter = new RecyclerAdapter();
recyclerView.setAdapter(adapter);
}
}
4) RecyclerView Adapter 생성하기
그 다음은 RecylcerAdapter를 생성해보도록 하겠습니다. adapter의 파일이름은 RecyclerAdapter로, 아까 MainActivity에 미리 지정했던 빨간줄 뜨는 adapter변수의 클래스명으로 지정해야합니다.
public class ViewHolder extends RecyclerView.ViewHolder{
public ViewHolder(@NonNull View view) {
super(view);
}
}
우선 public class ViewHolder extends RecyclerView.ViewHolder{ 를 입력하고 Alt + Enter를 누르면 Create constructor matching super라는 알림이 뜨는데 해당 constructor를 클릭해서 위의 소스처럼 생성자를 만들어주세요.
그 다음에는 방금 만들었던 ViewHolder를 상위 클래스에 extends해주세요. 만약 위와 같이 소스를 추가했으면 빨간줄이 뜨는데 Alt + Enter를 누르시면 이번에는 implement method를 생성하라는 문구가 뜹니다. 추가해주세요.
추가한 내용은 onCtreateViewHolder(), onBindViewHolder(), getItemCount() 총 3개입니다.
onCtreateViewHolder()는 RecyclerAdapter와 연결하는 RecyclerView에 추가할 item의 레이아웃과 item Data를 Bind하는거에 쓰입니다. onBindViewHolder()는 RecyclerView 자체와 item 데이터셋을 서로 연결시켜주는 과정을 의미합니다. getItemCount()은 데이터셋의 데이터개수를 의미합니다.
RecyclerAdapter.java
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder>{
@NonNull
@Override
// adapter와 연결하는 recyclerView에 추가할 item레이아웃과 item Data를 bind함
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return null;
}
@Override
// recyclerView 자체와 item 데이터셋을 서로 연결해주는 과정
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
}
@Override
// 데이터셋의 데이터 개수이다.
public int getItemCount() {
return 0;
}
public class ViewHolder extends RecyclerView.ViewHolder{
public ViewHolder(@NonNull View view) {
super(view);
}
}
}
여기까지 오셨으면 위의 소스와 같이 만들어진 모습을 보실 수 있습니다. 이제는 ListActivity에 추가한 데이터셋을 연결해야합니다.
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder>{
// 생성자를 통해 액티비티의 데이터셋과 해당 데이터셋을 얕은 복사를 통해 binding 해준다.
ArrayList<ListActivity> listBundle = new ArrayList<>();
Context mContext;
public RecyclerAdapter(ArrayList<ListActivity> bundle){
this.listBundle = bundle;
}
... 여태까지 한 내용
RecyclerAdapter 클래스 안에 생성자를 만들어서 Bind. 그 외 나중에 필요한 Context도 미리 선언을 해두었습니다.
@NonNull
@Override
// adapter와 연결하는 recyclerView에 추가할 item레이아웃과 item Data를 bind함
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Context mContext = parent.getContext();
LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.activity_list, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
@Override
// 데이터셋의 데이터 개수이다.
public int getItemCount() {
return listBundle.size();
}
그 다음은 onCreateViewHolder()에 위와 같이 써줍니다. R.layout.아까만든데이터셋아이템레이아웃
5) Item Layout 완성하기
activity_list.xml
다시 activity_list.xml로 가서 아무것도 설정하지 않았던 빈 View에 본인이 넣을 TextView를 추가로 합니다. 저같은 경우에는 인증서정보를 보여줄 것이라 발급대상, 발급자, 구분, 만료일자 TextView를 생성하였습니다.
<?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="wrap_content"
tools:context=".MainActivity">
<TextView
android:id="@+id/certNm"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="발급대상"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/certRegorg"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:layout_marginLeft="24dp"
android:padding="5dp"
android:text="발급자"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintLeft_toRightOf="@id/certNm"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.004" />
<TextView
android:id="@+id/certType"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:layout_marginLeft="24dp"
android:padding="5dp"
android:text="구분"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_weight="3"
app:layout_constraintLeft_toRightOf="@id/certRegorg"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.008" />
<TextView
android:id="@+id/certExpdate"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:layout_marginRight="24dp"
android:padding="5dp"
android:text="만료일자"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_weight="3"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
6) RecyclerView Adapter 마무리짓기
activity_list.xml에 생성하였던 TextView를 이제 연결짓도록 합시다. 다시 RecyclerAdapter.java로 돌아와서 레이아웃에 추가했던 item들을 소스에 추가해주세요.
RecyclerAdapter.java
public class ViewHolder extends RecyclerView.ViewHolder{
TextView certNameView;
TextView certRegView;
TextView certTypeView;
TextView certExpDateView;
public ViewHolder(@NonNull View view) {
super(view);
certNameView = view.findViewById(R.id.certNm);
certRegView = view.findViewById(R.id.certRegorg);
certTypeView = view.findViewById(R.id.certType);
certExpDateView = view.findViewById(R.id.certExpdate);
}
}
@Override
// recyclerView 자체와 item 데이터셋을 서로 연결해주는 과정
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
ListActivity list = listBundle.get(position);
holder.certNameView.setText(list.getCn());
holder.certRegView.setText(list.getO());
holder.certTypeView.setText(list.getOu());
holder.certExpDateView.setText(list.getDate());
}
7) MainActivity 클래스 완성시키기
이제 RecylcerAdapter를 활용할 수 있게되었습니다. 아까 MainActivity에서 생성만 했던 RecyclerAdapter를 바꿔주도록 합시다.
private RecyclerAdapter adapter = new RecyclerAdapter(listBundle);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.rvCertList);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
((LinearLayoutManager) layoutManager).setReverseLayout(true);
((LinearLayoutManager) layoutManager).setStackFromEnd(true);
recyclerView.setLayoutManager(layoutManager);
adapter = new RecyclerAdapter(listBundle);
recyclerView.setAdapter(adapter);
//------------------------------------------------------------
// 인증서 목록 뿌리기
final Collection<? extends ListActivity> collection = getCerts();
if(collection == null || collection.size() == 0) return;
for (int i=0; i<collection.size(); i++)
{
listBundle.add(((ListActivity) ((ArrayList) collection).get(i)));
adapter.notifyDataSetChanged();
}
layoutManager.scrollToPosition(listBundle.size()-1);
//------------------------------------------------------------
final Button btnOk = (Button) findViewById(R.id.btnOK);
btnOk.setOnClickListener(new View.OnClickListener() {
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
public void onClick(View v) {
count++;
}
});
}
저는 버튼은 다른 용도로 사용할 예정이라 그냥 화면을 로드할 때 바로 인증서목록이 뿌려지는 것으로 설정했습니다. 이렇게 하니 정상적으로 목록이 보이는걸 확인할 수 있네요!!
for (int i=0; i<collection.size(); i++)
{
listBundle.add(((ListActivity) ((ArrayList) collection).get(i)));
adapter.notifyDataSetChanged();
}
단, 제 소스는 100% 공개한 소스가 아닌 인증서정보를 가져오는 소스는 제외한 글입니다. 만약 정상적으로 연결되는지 테스트가 하고싶은 분들은 이 부분을 수정하시면 정상적으로 뜨실겁니다.
제가 참고로 많이 도움이 되었던 블로그의 링크고 첨부하겠습니다. 사실 이 블로그의 내용을 토대로 만든거라 제가 작성한글도 매우 유사할겁니다.
'네이티브 > Android' 카테고리의 다른 글
Android with Kotlin : 안드로이드 스튜디오 설치하기 with 코틀린 시작 (0) | 2020.09.16 |
---|---|
Android : KISACrypto SEED CBC 적용하기 (0) | 2020.05.25 |
Android : RecyclerView 활용 아이템(데이터) 클릭 이벤트 태우기 (0) | 2020.05.14 |
Android : Alert 알림 창 띄우기 (0) | 2020.05.14 |
Android : missing constraints in constraintlayout 해결방법 (0) | 2020.05.06 |