한 걸음 두 걸음
android studio ] listview 등 adapter 연결시켜 사용하는 방법 정리 본문
리스트뷰 위치 설정
안드로이드스튜디오에서 activity_main.xml에 레이아웃 설정하고 listView 넣어서 위치 잡아줌.
1. 리스트뷰 껍데기 넣어줌
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginStart="0dp"
android:layout_marginLeft="0dp"
android:layout_marginTop="41dp" />
</RelativeLayout>
2. 메인액티비티 수정
일단 만들어놓은 리스트뷰를 가져와주고
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView)findViewById(R.id.listView);
}
어뎁터도 하나 클래스로 만들어주자. 이 클래스는 BaseAdapter를 상속받아 사용할거야
class SingerAdapter extends BaseAdapter{
@Override
public int getCount() {
return 0;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return null;
}
}
여기서 4개의 함수는 BaseAdapter를 사용하기위해 반드시 필요한 4개의 implements야
오버라이드해줬어.
이제 어뎁터가 데이터를 관리해야하니까 ArrayList<String>를 하나 만들어주자.
근데 이 데이터는 String 하나밖에 데이터를 못받아. 즉 걸그룹에 대한 것이라면 걸그룹 이름 하나 정도만 받을 수 있는 거라는거야. 그래서 나는 다양한 데이터셋을 가진
자바 파일을 만들어주기로했어
이렇게 SinerItem이라는 이름으로 java 파일을 하나 만들어주고 안에
아래와 같이 name과 mobile을 갖는 클래스로 만들어줘.
package com.gkskfhdlstmapk.hanpinetree.mylistview;
public class SingerItem {
String name;
String moblie;
public SingerItem(String name, String moblie) {
this.name = name;
this.moblie = moblie;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMoblie() {
return moblie;
}
public void setMoblie(String moblie) {
this.moblie = moblie;
}
@Override
public String toString() {
return "SingerItem{" +
"name='" + name + '\'' +
", moblie='" + moblie + '\'' +
'}';
}
}
여기는 getter / setter 등과 toString 생성자 등 기본적으로 필요한 것들만 넣어주었어.
그리고 이제 ArrayList를 만들 때 String이 아닌 SingerItem를
ArrayList<SingerItem> items = new ArrayList<SingerItem>();
와 같이 넣어서 사용하지.
이제 implement로 넣어주었던 4개의 함수 수정해주고,
//너네 어뎁터 안에 몇 개의 아이템이 있니? 아이템갯수 반환함수
@Override
public int getCount() {
return items.size(); //위의 ArrayList내부의 아이템이 몇 개나 들었는지 알려주게됨
}
@Override
public Object getItem(int position) {
return items.get(position); //position번째의 아이템을 얻을거야.
}
@Override
public long getItemId(int position) {
return position;
}
//이게 중요! 어뎁터가 데이터를 관리하기 때문에 화면에 보여질 각각의 화면에 보일 뷰도 만들어달라는 것
//각각의 아이템 데이터 뷰(레이아웃)을 만들어주어 객체를 만든다음에 데이터를 넣고 리턴해줄 것임
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return null;
}
3. getView에 붙여줄 레이아웃을 단독으로 새로 만들어주자
를 만들어서,
이와 같이 만들어주었음. 아래는 코드임~ 이 레이아웃의 최상위는 Linear인데 이 레이아웃의 Height를 wrap_content로 정해두어야 화면 전체로 안잡아먹겠지.
<?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="wrap_content"
android:orientation="horizontal">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:src="@mipmap/ic_launcher"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:orientation="vertical">
<TextView
android:id="@+id/tetView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="이름"
android:textSize="30dp"
android:textColor="@color/colorPrimaryDark"/>
<TextView
android:id="@+id/tetView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="전화번호"
android:textSize="24dp"
android:textColor="@android:color/holo_orange_dark"/>
</LinearLayout>
</LinearLayout>
4. 자바소스파일과 매칭시켜봅시다.
새로운 자바 단독 소스파일을 하나 더 만들어줄거에요.
여기서 이 자바파일은 LinearLayout을 상속받음으로 Singer_Item 뷰에서 썼던 최상위 레이아웃인 LinearLayout을 인플레이션한 다음에 여기에 그대로 붙여 사용할 수 있게 됩니다.
이제 만들어진 창에 override로 Constructor 2개 해줌
뷰를 생성할 때는 우리가 반드시 두 개의 필수 생성자가 필요하니 추가해줍니다.
package com.gkskfhdlstmapk.hanpinetree.mylistview;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.w3c.dom.Text;
public class SingerItemView extends LinearLayout {
TextView textView1;
TextView textView2;
public SingerItemView(Context context) {
super(context);
init(context);
}
public SingerItemView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context){
//만들어놓은 xml파일을 객체화해와서 붙이는 역할을 하면 되겠죠
//서비스에서 제공하는 LAYOUT_INFLATER_SERVICE를 활용합니다.
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//객체화하기위해서 인플레이션 서비스를 활용함
inflater.inflate(R.layout.singer_item,this,true);
//이 소스가 Linear를 상속받았으므로 siger_item을 바로 this에 붙일 수 있음
textView1 = findViewById(R.id.tetView1);
textView2 = findViewById(R.id.tetView2);
}
//SigerItemView에 데이터를 설정할 수 있게끔 setter함수를 설정해줍시다.
//먼저 걸그룸의 이름
public void setName(String name){
textView1.setText(name);
}
// 다음 걸그룹의 연락처
public void setMobile(String mobile){
textView2.setText(mobile);
}
}
만들어놓은 뷰를 객체화시켜서 가져온 뒤 데이터를 설정해주는 함수를 만들어주었습니다.
이제 MainActivity로 가서 getView를 마저 편집해보자면
@Override
public View getView(int position, View convertView, ViewGroup parent) {
SingerItemView view = new SingerItemView(getApplicationContext());
//어떤 뷰든 안드로이드에서는 Context객체를 받게 되어있으므로 getApplicationCotext로 넣어줍니다.
//이제 이 뷰를 반환해주면 되는데 이 뷰가 몇 번째 뷰를 달라는 것인지 position값이 넘어오므로
SingerItem item = items.get(position); //SigerItem은 참고로 Dataset임. 따로 기본적인것만 구현해놓음
//이 position값을 갖는 아이템의 SigerItem객체를 새로 만들어준 뒤
view.setName(item.getName());
view.setMobile(item.getMoblie());
//이렇게 해당 position에 맞는 값으로 설정해줍니다.
//그렇게 설정을 잘 해놓은 다음에 view를 반환해야 데이터값이 들어간 레이아웃이 반환될거에요~
return view;
}
가 되며,
ArrayList<SingerItem> items = new ArrayList<SingerItem>();
//걸그룹의 이름, 전화번호 등등이 필요할텐데 이거 하나로는 부족하니까
//데이터형을 다양하게 담고있는 java파일을 하나 더 만들어줄거에요
//!! 그런데 ArrayList에 데이터를 넣는 기능이 지금 없으므로 함수를 하나 더 만들어줄게요
public void addItem(SingerItem item){
items.add(item);
}
위처럼 ArrayList의 dataset인 SingerItem을 넣는 함수가 없으므로
addItem함수를 하나 더 만들어줍니다.
이제 Main코드에서
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView)findViewById(R.id.listView);
SingerAdapter adapter = new SingerAdapter();
//adapter에 data값을 줘봅시다.
adapter.addItem(new SingerItem("소녀시대","010-4729-9200"));
adapter.addItem(new SingerItem("소녀시대","010-4729-9200"));
listView.setAdapter(adapter);
//이렇게해서 listView껍데기가 어뎁터에게 몇 개의 데이터가 있고 어떤 뷰를 집어넣어야하는지
//물어보면 어뎁터가 아래의 코드를 통해 만들어놓은 정보를 종합하여 전달함
}
로 데이터값을 설정해주고, (imageview값은 따로 지정해주지 않았으므로 미리 넣어둔 값으로 설정됩니다.)
adapter를 listView에 붙여주면 구현 완성~
전체코드
Main.java
package com.gkskfhdlstmapk.hanpinetree.mylistview;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView)findViewById(R.id.listView);
SingerAdapter adapter = new SingerAdapter();
//adapter에 data값을 줘봅시다.
adapter.addItem(new SingerItem("소녀시대","010-4729-9200"));
adapter.addItem(new SingerItem("소녀시대","010-4729-9200"));
listView.setAdapter(adapter);
//이렇게해서 listView껍데기가 어뎁터에게 몇 개의 데이터가 있고 어떤 뷰를 집어넣어야하는지
//물어보면 어뎁터가 아래의 코드를 통해 만들어놓은 정보를 종합하여 전달함
}
//어뎁터를 사용해서 코드를 간단하게 만들 수 있음, 이미지 및 텍스트를 나중에 커스터마이징 사용해서 사용하기 때문에
//그래서 처음부터 리스트뷰에 들어갈 아이템의 모양을 정해서 넣어주는 구조를 만드는 것이 좋아요
// 그러니 각각의 아이템을 위한 뷰를 만들어서 각각 넣어줄 거에요
class SingerAdapter extends BaseAdapter{
//어뎁터가 데이터를 관리하며 데이터를 넣었다가 뺄 수도 있으므로 ArrayList를 활용하여 구현해보자.
ArrayList<SingerItem> items = new ArrayList<SingerItem>();
//걸그룹의 이름, 전화번호 등등이 필요할텐데 이거 하나로는 부족하니까
//데이터형을 다양하게 담고있는 java파일을 하나 더 만들어줄거에요
//!! 그런데 ArrayList에 데이터를 넣는 기능이 지금 없으므로 함수를 하나 더 만들어줄게요
public void addItem(SingerItem item){
items.add(item);
}
//너네 어뎁터 안에 몇 개의 아이템이 있니? 아이템갯수 반환함수
@Override
public int getCount() {
return items.size(); //위의 ArrayList내부의 아이템이 몇 개나 들었는지 알려주게됨
}
@Override
public Object getItem(int position) {
return items.get(position); //position번째의 아이템을 얻을거야.
}
@Override
public long getItemId(int position) {
return position;
}
//이게 중요! 어뎁터가 데이터를 관리하기 때문에 화면에 보여질 각각의 화면에 보일 뷰도 만들어달라는 것
//각각의 아이템 데이터 뷰(레이아웃)을 만들어주어 객체를 만든다음에 데이터를 넣고 리턴해줄 것임
@Override
public View getView(int position, View convertView, ViewGroup parent) {
SingerItemView view = new SingerItemView(getApplicationContext());
//어떤 뷰든 안드로이드에서는 Context객체를 받게 되어있으므로 getApplicationCotext로 넣어줍니다.
//이제 이 뷰를 반환해주면 되는데 이 뷰가 몇 번째 뷰를 달라는 것인지 position값이 넘어오므로
SingerItem item = items.get(position); //SigerItem은 참고로 Dataset임. 따로 기본적인것만 구현해놓음
//이 position값을 갖는 아이템의 SigerItem객체를 새로 만들어준 뒤
view.setName(item.getName());
view.setMobile(item.getMoblie());
//이렇게 해당 position에 맞는 값으로 설정해줍니다.
//그렇게 설정을 잘 해놓은 다음에 view를 반환해야 데이터값이 들어간 레이아웃이 반환될거에요~
return view;
}
}
}
singerItem.java
package com.gkskfhdlstmapk.hanpinetree.mylistview;
public class SingerItem {
String name;
String moblie;
public SingerItem(String name, String moblie) {
this.name = name;
this.moblie = moblie;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMoblie() {
return moblie;
}
public void setMoblie(String moblie) {
this.moblie = moblie;
}
@Override
public String toString() {
return "SingerItem{" +
"name='" + name + '\'' +
", moblie='" + moblie + '\'' +
'}';
}
}
SingerItemView.java
package com.gkskfhdlstmapk.hanpinetree.day24_1_mylist;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.w3c.dom.Text;
public class SingerItemView extends LinearLayout {
TextView textView;
TextView textView2;
ImageView imageView;
//뷰를 생성할 때는 생성자가 두 개 이상이어야한다.
public SingerItemView(Context context) {
super(context);
init(context);
}
public SingerItemView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context){
//만들어놓은 singer_item xml파일을 인플레이터시켜서 객체화한다음 SingerItemView에 붙여줄 수 있겠죠
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//레이아웃 인플레이터ㅓ로 시스템서비스를 참조할 수 있음
//시스템서비스는 화면에 보이지 않아도 돌아가고있음- 레아웃인플레이터를 이용하겠다.
inflater.inflate(R.layout.singer_item,this,true);
//이렇게 객체화시켜준 다음부터는 findViewById로 가져와 참조할 수 있음
textView = (TextView)findViewById(R.id.textView);
textView2 = (TextView)findViewById(R.id.textView2);
imageView = (ImageView) findViewById(R.id.imageView);
}
//데이터를 설정할 수 있게 만든 함수
public void setName(String name){
textView.setText(name);
//걸그룹의 이름을 설정
}
public void setMobile(String mobile){
textView2.setText(mobile);
}
public void setImageView(int resId){
imageView.setImageResource(resId);
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginStart="0dp"
android:layout_marginLeft="0dp"
android:layout_marginTop="41dp" />
</RelativeLayout>
singer_Item.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="wrap_content"
android:orientation="horizontal">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:src="@mipmap/ic_launcher"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:orientation="vertical">
<TextView
android:id="@+id/tetView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="이름"
android:textSize="30dp"
android:textColor="@color/colorPrimaryDark"/>
<TextView
android:id="@+id/tetView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="전화번호"
android:textSize="24dp"
android:textColor="@android:color/holo_orange_dark"/>
</LinearLayout>
</LinearLayout>
참고
Java의 ArrayList
URL : https://slowlywalk1993.tistory.com/entry/Java-ArrayList%EB%9E%80
'FrontEnd > Android' 카테고리의 다른 글
android ] RAW파일 입출력 처리 (1) | 2019.02.28 |
---|---|
android studio ] listview 등 adapter 연결시켜 사용하는 방법 정리2 (0) | 2019.02.21 |
android studio 안드로이드스튜디오 ] split함수로 텍스트 구분자 설정하여 쪼개기 (0) | 2019.02.18 |
android studio 안드로이드스튜디오 ] txt파일 한글 깨짐현상 해결 (0) | 2019.02.18 |
androidstudio 안드로이드스튜디오 apk파일 빌드 (0) | 2019.02.14 |