Adapter는 하나의 Object(객체)로서, 보여지는 View와 그 View에 올릴 Data를 연결하는 일종의 Bridge
즉, 데이터의 원본을 받아 관리하고, 어댑터뷰가 출력할 수 있는 형태로 데이터를 제공하는 중간 객체 역할을 한다.
어댑터는 ArrayAdapter, CursorAdapter, SimpleAdapter 등등이 있다.
즉, 어댑터는 어댑터 뷰가 출력할 수 있는 데이터로 만들어 놓는 공간을 의미하고, 어댑터 뷰는 이 데이터를 출력하는 역할을 하게 된다.
이때 어댑터와 연결된 원본 데이터가 변경되면 notifyDataSetChanged 메서드를 호출하여 어댑터 뷰에 원본이 변경되었다고 알려주어 어댑터 뷰가 다시 그림을 그리도록 해야한다.
Adapter
라는 중간 매개체를 이용하기 때문에 붙여진 이름이다.ViewGroup을 상속
받으므로, 내부적으로 많은 뷰들을 담을 수 있다.onChanged() 단계에서 각 view들이 자기자신을 requestLayout을 하면 listview는 자신의 자식이 붙어있는지를 확인 후 아이템의 수 만큼 getview를 호출되게 된다.
notifydatasetInvalidate()도 notifydatasetChanged와 유사한 메서드다. 다만 , notifydatasetInvalidate를 하게 되면 child의 수가, 처음 data 설정한 갯수만 유지가 되고 추가되거나 삭제된건 반영이 안된다. ( 즉, item의 데이터가 변경된 것만을 보여주게끔하는 것 같음 )
public class MainActivity extends AppCompatActivity {
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = findViewById(R.id.lv_comment_view);
}
class MyAdapter extends BaseAdapter {
}
}
/*
메인 액티비티에서는 ListView listview = findViewById를 통해 리스트뷰를 가리키도록 해주고
이제 이 리스트 뷰(어댑터 뷰)를 이용할 어댑터를 만들어야 하므로
어댑터 클래스인 MyAdapter을 하나 만들어준다.(이때 BaseAdapter을 상속하여 만들도록 한다.)
*/
public class MyItem {
String id;
String phone;
public MyItem(String id, String phone) {
this.id = id;
this.phone = phone;
}
public MyItem() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
// 해당 클래스는 item에 들어갈 항목인 id, phone를 가지며, get, set 함수를 기본적으로 정의
// 뷰를 생성할 때는 필수 생성자가 2개이다.
public class MyItemView extends LinearLayout {
TextView textView, textView2;
public MyItemView(Context context) {
super(context);
init(context);
}
public MyItemView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.my_item, this, true);
textView = findViewById(R.id.tv_id);
textView2 = findViewById(R.id.tv_phone);
}
public void setId(String id){
textView.setText(id);
}
public void setPhone(String phone){
textView2.setText(phone);
}
}
/*
MyItemView 클래스에서 인플레이션을 통해 메모리 객체화를 해야한다.
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
를 해주면 시스템 서비스를 통해 LayoutInflater를 가져다 쓴다고 정의해주고, 이를 캐스팅해서 받아준다.
그 뒤 inflate를 해주는데 my_item을 인플레이션 하고
현재 이 객체가 LinearLayout를 상속받았기에 최상위 레이아웃이 LinearLayout이니 this를 넣어준다.
*/
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = findViewById(R.id.lv_comment_view);
MyAdapter adapter = new MyAdapter();
adapter.addItem(new MyItem("a","123"));
adapter.addItem(new MyItem("bb","010-123"));
adapter.addItem(new MyItem("ccc","010-123-234"));
listView.setAdapter(adapter);
}
class MyAdapter extends BaseAdapter {
private ArrayList<MyItem> items = new ArrayList<>();
public void addItem(MyItem item){
items.add(item);
}
@Override
public int getCount() {
return items.size();
}
@Override
public MyItem getItem(int position) {
return items.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, final View convertView, ViewGroup parent) {
MyItemView view = new MyItemView(getApplicationContext());
MyItem item = items.get(position);
view.setId(item.getId());
view.setPhone(item.getPhone());
return view;
}
}
}