안드로이드 Custom Listview 이벤트 적용

개발/안드로이드 2017. 10. 2. 15:14
반응형


1. 안드로이드 Custom ListView를 만들어보자

2. 안드로이드 Custom Listview 이벤트 적용

3. 안드로이드 ListView 동작방식 이해하기


이전 포스팅에서는 커스텀 리스트뷰 사용법에 대해 알아보았습니다.

이전에 포스팅 했던 예제에서 이벤트를 적용하도록 하겠습니다.


이벤트는 하나의 아이템 전체 말고 선택 버튼에만 이벤트가 적용되도록 하겠습니다.


0. 이벤트 적용 방법

ListView에 이벤트 적용방법은 여러가지가 있지만 제가 자주 사용하는 방식을 설명드리도록 하겠습니다.

이벤트 적용 방식은 3단계로 절차로 볼 수 있겠습니다.




 ① 각 아이템 마다 setTag로 position을 등록 합니다.

 ② 선택버튼 이벤트를 MainActivity 로 발생되도록 합니다.

 ③ 이벤트 발생 시 getParent 로 선택 버튼 부모를 얻어옵니다. 즉, 아이템 위젯이 얻어와 지겠죠..

     그리고 Tag를 읽어오면 됩니다.

이제 코드를 적용해 볼까요?


1. 이벤트 적용 예제


 1-1) ItemData에 onClickListener 추가 

  MainActivity 에 연결 할 Listener 를 추가합니다.

public class ItemData
{
public String strTitle;
public String strDate;
public View.OnClickListener onClickListener;
}




 1-2) MainActivity의 onCreate에서 onClickListener 를 등록합니다.

@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// 데이터 생성 ============================
String[] strDate = {"2017-01-03", "1965-02-23", "2016-04-13", "2010-01-01", "2017-06-20",
"2012-07-08", "1980-04-14", "2016-09-26", "2014-10-11", "2010-12-24"};
int nDatCnt = 0;
ArrayList<ItemData> oData = new ArrayList<>();
for (int i = 0; i < 1000; ++i)
{
ItemData oItem = new ItemData();
oItem.strTitle = "데이터 " + (i + 1);
oItem.strDate = strDate[nDatCnt++];
oItem.onClickListener = this;
oData.add(oItem);
if(nDatCnt >= strDate.length) nDatCnt = 0;
}
}


  

  1-3) ListAdapter의 getView에서 선택 버튼 Listener를 ItemData Class 의 Listener로 등록해줍니다.

@Override
public View getView(int position, View convertView, ViewGroup parent)
{
if (convertView == null)
{
final Context context = parent.getContext();
if (inflater == null)
{
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
convertView = inflater.inflate(R.layout.listview_item, parent, false);
}

TextView oTextTitle = (TextView) convertView.findViewById(R.id.textTitle);
TextView oTextDate = (TextView) convertView.findViewById(R.id.textDate);
Button oBtn = (Button) convertView.findViewById(R.id.btnSelector);

oTextTitle.setText(m_oData.get(position).strTitle);
oTextDate.setText(m_oData.get(position).strDate);
oBtn.setOnClickListener(m_oData.get(position).onClickListener);

convertView.setTag(""+position);
return convertView;
}


  1-4) MainActivity 의 onClick 을 만들어 이벤트가 호출될 곳을 만들어 줍니다.

public class MainActivity extends AppCompatActivity implements View.OnClickListener
{
private ListView m_oListView = null;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// ...
}

@Override
public void onClick(View v)
{
View oParentView = (View)v.getParent(); // 부모의 View를 가져온다. 즉, 아이템 View임.
TextView oTextTitle = (TextView) oParentView.findViewById(R.id.textTitle);
String position = (String) oParentView.getTag();

AlertDialog.Builder oDialog = new AlertDialog.Builder(this,
android.R.style.Theme_DeviceDefault_Light_Dialog);

String strMsg = "선택한 아이템의 position 은 "+position+" 입니다.\nTitle 텍스트 :" + oTextTitle.getText();
oDialog.setMessage(strMsg)
.setPositiveButton("확인", null)
.setCancelable(false) // 백버튼으로 팝업창이 닫히지 않도록 한다.
.show();
}
}


완성 되었습니다. 

선택 버튼을 누르면 아래 이미지와 같이 팝업창이 호출 될 것입니다.


이해가 잘 안되시면 아래 프로젝트 파일을 실행 시켜보면 이해가 더 빠를 듯합니다.

ListViewSample_small.zip

(필요 없는 부분을 지웠기 때문에 Clean Project & Rebuild Project 하셔야 합니다.)



다음에는 ListView에서 getView가 호출이 언제 되는지 그리고 메모리는 어떻게 절약 할 수 있는지 등.. 동작 방식에대해 설명해 보겠습니다.





이벤트를 버튼에만 적용했더니 타이틀, 날짜 등의 TextView에도 이벤트를 어떻게 적용하는지 문의가 있어서 추가로 수정된 내용을 남깁니다.


방법은 다양하겠지만 저는 간단하게 tag 를 이용하여 구분하는 방법을 설명하도록 하겠습니다. 

수정할 곳은 ListAdapter class 의 getView 함수와 MainActivity class 의 onClick 만 수정하면 됩니다.


ListAdapter - getView

@Override
public View getView(int position, View convertView, ViewGroup parent)
{
if (convertView == null)
{
final Context context = parent.getContext();
if (inflater == null)
{
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
convertView = inflater.inflate(R.layout.listview_item, parent, false);
}

TextView oTextTitle = (TextView) convertView.findViewById(R.id.textTitle);
TextView oTextDate = (TextView) convertView.findViewById(R.id.textDate);
Button oBtn = (Button) convertView.findViewById(R.id.btnSelector);

oTextTitle.setText(m_oData.get(position).strTitle);
oTextDate.setText(m_oData.get(position).strDate);

oBtn.setTag("1");
oTextTitle.setTag("2");
oTextDate.setTag("3");
oBtn.setOnClickListener(m_oData.get(position).onClickListener);
oTextTitle.setOnClickListener(m_oData.get(position).onClickListener);
oTextDate.setOnClickListener(m_oData.get(position).onClickListener);

convertView.setTag(""+position);
return convertView;
}



 MainActivity class 의 onClick

@Override
public void onClick(View v)
{
int nViewTag = Integer.parseInt((String)v.getTag());
String strViewName = "";
View oParentView = (View)v.getParent();
switch (nViewTag)
{
case 1: // 버튼
strViewName = "버튼";
break;
case 2: // 타이틀
strViewName = "타이틀";
oParentView = (View)oParentView .getParent();
break;
case 3: // 날짜
strViewName = "날짜";
oParentView = (View)oParentView .getParent();
break;
}

TextView oTextTitle = (TextView) oParentView.findViewById(R.id.textTitle);
String position = (String) oParentView.getTag();

AlertDialog.Builder oDialog = new AlertDialog.Builder(this,
android.R.style.Theme_DeviceDefault_Light_Dialog);

String strMsg = strViewName + " - 선택한 아이템의 position 은 " + position +
" 입니다.\nTitle 텍스트 :" + oTextTitle.getText();
oDialog.setMessage(strMsg)
.setPositiveButton("확인", null)
.setCancelable(false) // 백버튼으로 팝업창이 닫히지 않도록 한다.
.show();
}




 

반응형
admin