[Android] ListView에 EditText넣기
- Mobile/Android
- 2017. 10. 25.
안녕하세요 이번에는 리스트뷰에 EditText를 넣어보는 작업을 한번 해보도록 하겠습니다. 개발을 하다가 보면 사용자에게 정보를 입력하고 싶을 때 리스트 뷰안에 EditText를 넣고 싶은 경우가 생깁니다. 하지만 EditText를 ListView안에 집어넣으면 포커스가 뒤죽박죽이 되어버려 굉장히 곤란한 상황에 빠지게 되는데요. 그 이유는 ListView는 목록을 스크롤할 때 메모리를 아끼기 위해 ListItem의 뷰를 재사용하기 때문입니다. 그래서 포커스가 바뀌기 전에 입력한 값을 다른 변수에 저장을 해줘야 하는데 TextWatcher라는 함수를 통해서 이 방법을 구현할 수 있습니다.
ListView에 EditText 넣기
예제 파일 올려드립니다.
예제 파일은 동적으로 추가 삭제되는 EditText리스트뷰입니다. 유용하게 사용해주시길 바랍니다.
MainActivity
package com.example.user.junprojecttest;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private ListAdapter adapter;
private Button add;
private Button remove;
private Button result;
private ListView listView;
private int num;
public ArrayList<EditText> find = new ArrayList<>();
public ArrayList<ListItem> listViewItemList = new ArrayList<ListItem>(); //리스트뷰
private ArrayList<ListItem> filteredItemList = listViewItemList; //리스트뷰 임시저장소
public ArrayList<String>find2 = new ArrayList<>();
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
num = 0;
add =(Button)findViewById(R.id.add);
remove=(Button)findViewById(R.id.remove);
result=(Button)findViewById(R.id.result);
listView=(ListView)findViewById(R.id.listview);
adapter = new ListAdapter();
listView.setAdapter(adapter);
add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,num+ "추가되었습니다.", Toast.LENGTH_SHORT).show();
adapter.addItem(num+"","","",num);
adapter.notifyDataSetChanged();
num ++;
}
});
remove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "삭제되었습니다.", Toast.LENGTH_SHORT).show();
adapter.delItem();
adapter.notifyDataSetChanged();
num --;
}
});
result.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "입력되었습니다.", Toast.LENGTH_SHORT).show();
System.out.println(adapter.getItem(0).toString());
for(int i=0;i<listViewItemList.size();i++){
System.out.println(listViewItemList.get(i).getName());
System.out.println(listViewItemList.get(i).getCount());
System.out.println(listViewItemList.get(i).getPrice());
}
}
});
}
//어뎁터 시작
public class ListAdapter extends BaseAdapter {
@Override
public int getCount() {
return filteredItemList.size();
}
@Override
public Object getItem(int position) {
return filteredItemList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final int pos = filteredItemList.get(position).getNum();
final Context context = parent.getContext();
final ViewHolder holder;
// "listview_item" Layout을 inflate하여 convertView 참조 획득.
if (convertView == null) {
holder = new ViewHolder();
LayoutInflater inflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.lyt_listview_list, parent, false);
holder.editText1 = (EditText)convertView.findViewById(R.id.editText1);
holder.editText2 = (EditText)convertView.findViewById(R.id.editText2);
holder.editText3 = (EditText)convertView.findViewById(R.id.editText3);
convertView.setTag(holder);
}else{
holder = (ViewHolder)convertView.getTag();
}
holder.ref = position;
// 화면에 표시될 View(Layout이 inflate된)으로부터 위젯에 대한 참조 획득
final EditText editText1 = (EditText)convertView.findViewById(R.id.editText1);
// Data Set(filteredItemList)에서 position에 위치한 데이터 참조 획득
final ListItem listViewItem = filteredItemList.get(position);
holder.editText1.setText(listViewItem.getName());
holder.editText2.setText(listViewItem.getCount());
holder.editText3.setText(listViewItem.getPrice());
holder.editText1.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
filteredItemList.get(holder.ref).setName(s.toString());
}
});
holder.editText2.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
filteredItemList.get(holder.ref).setCount(s.toString());
}
});
holder.editText3.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
filteredItemList.get(holder.ref).setPrice(s.toString());
find2.add(holder.editText3.getText().toString());
}
});
return convertView;
}
public void addItem(String name, String count, String price, int num) {
ListItem item = new ListItem();
item.setName(name);
item.setCount(count);
item.setPrice(price);
item.setNum(num);
listViewItemList.add(item);
}
public void delItem() {
if (listViewItemList.size() < 1) {
} else {
listViewItemList.remove(listViewItemList.size() - 1);
}
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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"
android:orientation="vertical"
tools:context="com.example.user.junprojecttest.MainActivity">
<LinearLayout
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/add"
android:text="추가"
tools:layout_editor_absoluteY="0dp"
tools:layout_editor_absoluteX="0dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/remove"
android:text="삭제"
tools:layout_editor_absoluteY="0dp"
tools:layout_editor_absoluteX="0dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/result"
android:text="입력"
tools:layout_editor_absoluteY="0dp"
tools:layout_editor_absoluteX="0dp" />
</LinearLayout>
<ListView
android:scrollbars="none"
android:background="@null"
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</LinearLayou>
lyt_listview_list.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="match_parent"
android:background="@android:color/white"
android:orientation="horizontal" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:textColor="@android:color/black"
android:layout_height="wrap_content"
android:text="물품명" />
<EditText
android:id="@+id/editText1"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:ems="10" >
<requestFocus />
</EditText>
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:textColor="@android:color/black"
android:layout_height="wrap_content"
android:text="수량" />
<EditText
android:id="@+id/editText2"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:ems="10" >
<requestFocus />
</EditText>
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:textColor="@android:color/black"
android:layout_height="wrap_content"
android:text="가격" />
<EditText
android:id="@+id/editText3"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:ems="10" >
</LinearLayout>
ListAdapter
package com.example.user.junprojecttest;
import android.content.Context;
import android.graphics.Color;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* Created by user on 2017-10-23.
*/
public class ListAdapter extends BaseAdapter {
public ArrayList<ListItem> listViewItemList = new ArrayList<ListItem>();
private ArrayList<ListItem> filteredItemList = listViewItemList;
public static String name,count,price;
@Override
public int getCount() {
return filteredItemList.size();
}
@Override
public Object getItem(int position) {
return filteredItemList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final int pos = filteredItemList.get(position).getNum();
final Context context = parent.getContext();
final ViewHolder holder;
// "listview_item" Layout을 inflate하여 convertView 참조 획득.
if (convertView == null) {
holder = new ViewHolder();
LayoutInflater inflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.lyt_listview_list, parent, false);
holder.editText1 = (EditText)convertView.findViewById(R.id.editText1);
holder.editText2 = (EditText)convertView.findViewById(R.id.editText2);
holder.editText3 = (EditText)convertView.findViewById(R.id.editText3);
convertView.setTag(holder);
}else{
holder = (ViewHolder)convertView.getTag();
}
holder.ref = position;
// 화면에 표시될 View(Layout이 inflate된)으로부터 위젯에 대한 참조 획득
final EditText editText1 = (EditText)convertView.findViewById(R.id.editText1);
// Data Set(filteredItemList)에서 position에 위치한 데이터 참조 획득
final ListItem listViewItem = filteredItemList.get(position);
holder.editText1.setText(listViewItem.getName());
holder.editText2.setText(listViewItem.getCount());
holder.editText3.setText(listViewItem.getPrice());
name+=holder.editText1.getText()+"#";
count+=holder.editText1.getText()+"#";
price+=holder.editText1.getText()+"#";
holder.editText1.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
filteredItemList.get(holder.ref).setName(s.toString());
}
});
holder.editText2.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
filteredItemList.get(holder.ref).setCount(s.toString());
}
});
holder.editText3.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
filteredItemList.get(holder.ref).setPrice(s.toString());
}
});
return convertView;
}
public void addItem(String name, String count, String price, int num) {
ListItem item = new ListItem();
item.setName(name);
item.setCount(count);
item.setPrice(price);
item.setNum(num);
listViewItemList.add(item);
}
public void delItem() {
if (listViewItemList.size() < 1) {
} else {
listViewItemList.remove(listViewItemList.size() - 1);
}
}
}
ListItem
public class ListItem {
private String name;
private String count;
private String price;
private int num;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCount() {
return count;
}
public void setCount(String count) {
this.count = count;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
ViewHolder
import android.widget.EditText;
/**
* Created by user on 2017-10-23.
*/
public class ViewHolder {
EditText editText2;
EditText editText1;
EditText editText3;
int ref;
}
완성본
추가 버튼을 누르면 동적으로 리스트뷰가 증가되고 삭제를 누르면 삭제됩니다.
그리고 입력을 누르면 로그가 찍히게 됩니다.
'Mobile > Android' 카테고리의 다른 글
[Android] Fragment에서 구글 클라우드비전 사용하기 (0) | 2017.10.27 |
---|---|
[Android] 구글 클라우드비전 API키 발급 및 사용법 (48) | 2017.10.27 |
[Android] ListView를 팝업(AlertDialog)창으로 만들기 (1) | 2017.10.25 |
[Android] LayoutInflater로 동적으로 레이아웃(뷰) 추가하기 (5) | 2017.10.24 |