본문 바로가기

안드로이드 프로그래밍

[안드로이드 7일차] ListView

WeatherDTO


getter와 setter를 모두 만들어주고, 필요한 생성자를 만든다.

package com.cjwplatform.myapp2;

public class Weather {
private String city;
private String temp;
private String weather;

public Weather(String city, String temp, String weather) {
this.city = city;
this.temp = temp;
this.weather = weather;
}

public String getCity() {
return city;
}

public void setCity(String city) {
this.city = city;
}

public String getTemp() {
return temp;
}

public void setTemp(String temp) {
this.temp = temp;
}

public String getWeather() {
return weather;
}

public void setWeather(String weather) {
this.weather = weather;
}

@Override
public String toString() {
return "Weather{" +
"city='" + city + '\'' +
", temp='" + temp + '\'' +
", weather='" + weather + '\'' +
'}';
}
}


WeatherAdapter

package com.cjwplatform.myapp2;
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.HashMap;
import java.util.List;
import java.util.Map;

// 어댑터를 만들 경우에는 반드시 BaseAdapter를 상속받는다.
public class WeatherAdapter extends BaseAdapter {
private List<Weather> mData;
private Map<String, Integer> mWeatherImageMap; // "맑음","비".. 등이 키이고, 반환값이 int임.

public WeatherAdapter(List<Weather> data) {
this.mData = data;
mWeatherImageMap = new HashMap<>();
mWeatherImageMap.put("맑음",R.drawable.sunny); // 맑음
mWeatherImageMap.put("구름",R.drawable.cloudy); // 흐림
mWeatherImageMap.put("비",R.drawable.rainy); // 비
mWeatherImageMap.put("눈",R.drawable.snow); // 눈
}

// 아이템의 갯수를 표시
@Override
public int getCount() {
return mData.size();
}
// i는 position 의미
@Override
public Object getItem(int i) {
return mData.get(i);
}
// 디비 커서 사용시 수정
@Override
public long getItemId(int i) {
return i;
}
// 한 칸에 보여질 레이아웃을 정의하는 곳 - 파일을 따로 생성한다 -> item_weather.xml

@Override
public View getView(int i, View view, ViewGroup viewGroup) {

ViewHolder holder;

// 매번 호출되므로 cpu 자원을 많이 씀. 리스트를 스크롤할 때마다 layout은 재사용하고 데이터만 바뀔 수 있음.
        // 리스트 첫 번째 아이템일 경우를 말함

if(view == null){

holder = new ViewHolder();

view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_weather,viewGroup,false);

ImageView weatherImage = view.findViewById(R.id.weather_image);
TextView cityText = view.findViewById(R.id.city_text);
TextView tempText = view.findViewById(R.id.temp_text);


holder.weatherImage = weatherImage;

holder.cityText = cityText;

holder.tempText = tempText;


view.setTag(holder); // setTag 는 객체를 넘길 수 있음.


}else{

// 재사용이 되는 경우에는 그냥 홀더를 가져오겠다!!

holder = (ViewHolder) view.getTag();

}


Weather weather = mData.get(i);
holder.setImageResource(mWeatherImageMap.get(weather.getWeather()));

// getWeather() "맑음" 이라는 키를 가져와서 어댑터에서 소스를 리턴한다.
holder.setText(weather.getCity());
holder.setText(weather.getTemp());
return view;
}


// inner class로 선언 -> findViewById를 적게 사용하기 위해 뷰홀더를 사용


static class ViewHolder {

ImageView weatherImage;
TextView cityText;
TextView tempText;


}



}


item_weather.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"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal">

<ImageView
android:id="@+id/weather_image"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@mipmap/ic_launcher"/>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical"
android:padding="8dp">

<TextView
tools:text="도시명"
android:id="@+id/city_text"
android:textSize="30sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

<TextView
tools:text="기온"
android:id="@+id/temp_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="end" />


</LinearLayout>
</LinearLayout>


MainActivity

package com.cjwplatform.myapp2;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// 1. 데이터 준비
ArrayList<Weather> data = new ArrayList<>();
data.add(new Weather("창원","2도","맑음"));
data.add(new Weather("부산","3도","흐림"));
data.add(new Weather("서울","-4도","비"));
data.add(new Weather("제주도","5도","비"));
data.add(new Weather("대구","-1도","비"));
data.add(new Weather("진해","5도","맑음"));
data.add(new Weather("광주","1도","맑음"));
data.add(new Weather("파주","-7도","맑음"));
data.add(new Weather("여수","-2도","흐림"));
data.add(new Weather("영월","3도","눈"));
data.add(new Weather("동해","4도","눈"));
data.add(new Weather("울산","-2도","흐림"));
data.add(new Weather("강릉","-1도","비"));
data.add(new Weather("울진","-2도","눈"));
data.add(new Weather("거제","0도","맑음"));
data.add(new Weather("하남","-4도","흐림"));

// 2. 어댑터를 준비 : 뷰에 데이터를 표시해주는 역할
WeatherAdapter adapter = new WeatherAdapter(data);



// 3. 뷰에 set 하기
ListView listView = findViewById(R.id.list_view);
listView.setAdapter(adapter);

// 4. 클릭했을 경우 Toast 메시지를 출력
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(MainActivity.this,i + "번째 아이템 선택",Toast.LENGTH_SHORT).show();
}
});
}
}


activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context=".MainActivity">

<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>