마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

listView에서 item이 이상하게 제거됩니다

0 추천

 

메뉴에서 추가하면 오른쪽 주문내역의 탭에 메뉴가 추가되고

주문내역 탭에서 오른쪽의 X버튼을 누르면 해당 아이템이 삭제되는 코드입니다

그런데 불고기 11개를 삭제하면 불고기는 삭제되지만 개수는 마지막 item의 것이 삭제되네요;;

어떻게 해결해야 하나요 ㅠㅠ?

 

 

mainActivity 입니다


public class OrderActivity extends Activity {
	ExpandableListView listView_menu;
	ArrayList<String> array_menuType = new ArrayList<String>();
	HashMap<String, ArrayList<String>> array_menuName = new HashMap<String, ArrayList<String>>();
	
	ListView listView_order;
	ArrayList<String> array_order = new ArrayList<String>();
	OrderListAdapter adapter_order;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_order);
		OnClickListener clickListener;
		
		TabHost tabHost = (TabHost)findViewById(android.R.id.tabhost);
		tabHost.setup();
		
		TabSpec menuTab = tabHost.newTabSpec("Tab1");
		menuTab.setContent(R.id.tab1);
		menuTab.setIndicator("메뉴");
		tabHost.addTab(menuTab);
		
		TabSpec orderTab = tabHost.newTabSpec("Tab2");
		orderTab.setContent(R.id.tab2);
		orderTab.setIndicator("주문내역");
		tabHost.addTab(orderTab);
		
		listView_order = (ListView) findViewById(R.id.listview_order);
		adapter_order = new OrderListAdapter(this, array_order);
		listView_order.setAdapter(adapter_order);
		
		setArrayData();
		listView_menu = (ExpandableListView) findViewById(R.id.listview_menu);
		listView_menu.setAdapter(new MenuListAdapter(this, array_menuType, array_menuName, array_order, adapter_order));
	}
	
	private void setArrayData() {
		array_menuType.add("피자");
		array_menuType.add("치킨");
		array_menuType.add("중국집");
		
		ArrayList<String> arrayPizza = new ArrayList<String>();
		arrayPizza.add("치즈");
		arrayPizza.add("불고기");
		
		array_menuName.put(array_menuType.get(0), arrayPizza);
		array_menuName.put(array_menuType.get(1), arrayPizza);
	}
}

 

메뉴의 리스트 어뎁터 입니다


public class MenuListAdapter extends BaseExpandableListAdapter{
	private Context context;
	private ArrayList<String> arrayGroup;
	private HashMap<String, ArrayList<String>> arrayChild;
	private ArrayList<String> array_order;
	OrderListAdapter orderListAdapter;
	
	public MenuListAdapter(Context context, ArrayList<String> arrayGroup, HashMap<String, ArrayList<String>> arrayChild,
			ArrayList<String> array_order, OrderListAdapter orderListAdapter) {
		super();
		this.context = context;
		this.arrayGroup = arrayGroup;
		this.arrayChild = arrayChild;
		this.array_order = array_order;
		this.orderListAdapter = orderListAdapter;
	}
	@Override
	public View getGroupView(int groupPosition, boolean isExpanded,
			View convertView, ViewGroup parent) {
		// TODO Auto-generated method stub
		String groupName = arrayGroup.get(groupPosition);
		
		if(convertView == null) {
			LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			convertView = (RelativeLayout)inflater.inflate(R.layout.item_menutype, null);
		}
		TextView textGroup = (TextView) convertView.findViewById(R.id.text_menutype);
		textGroup.setText(groupName);
		return convertView;
	}
	
	@Override
	public View getChildView(int groupPosition, int childPosition,
			boolean isLastChild, View convertView, ViewGroup parent) {
		// TODO Auto-generated method stub
		final String childName = arrayChild.get(arrayGroup.get(groupPosition)).get(childPosition);
		
		if(convertView == null) {
			LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			convertView = (RelativeLayout) inflater.inflate(R.layout.item_menuname, null);
		}
		TextView textChild = (TextView) convertView.findViewById(R.id.text_menuname);
		textChild.setText(childName);
		
		Button orderButton = (Button) convertView.findViewById(R.id.button_order);
		orderButton.setText("추가");
		orderButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				array_order.add(childName);
				orderListAdapter.notifyDataSetChanged();
			}
		});
		
		return convertView;
	}
	
	@Override
	public boolean isChildSelectable(int groupPosition, int childPosition) {
		// TODO Auto-generated method stub
		return false;
	}
	
	
}

 

주문내역의 리스트 어뎁터입니다.


public class OrderListAdapter extends BaseAdapter{
	private Context context;
	private ArrayList<String> arrayList;
	ListViewHolder holder;
	
	public OrderListAdapter(Context context, ArrayList<String> arrayList) {
		super();
		this.context = context;
		this.arrayList = arrayList;
	}
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		// TODO Auto-generated method stub
		View v = convertView;
		String str_menuname = arrayList.get(position);
		final int temp = position;
		
		if(v == null) {
			LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			v = (RelativeLayout)inflater.inflate(R.layout.item_order, null);
			
			holder = new ListViewHolder(v);
			v.setTag(holder);
		} else {
			holder = (ListViewHolder) v.getTag();
		}
		
		holder.getText_menuName().setText(str_menuname);
		final EditText edit_quantity = holder.getEdit_quantity();
		
		holder.getButton_plus().setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				int temp = Integer.parseInt(edit_quantity.getText().toString());
				edit_quantity.setText(Integer.toString(temp + 1));
			}
		});
		
		holder.getButton_minus().setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				int temp = Integer.parseInt(edit_quantity.getText().toString());
				edit_quantity.setText(Integer.toString(temp - 1));
			}
		});
		
		holder.getButton_remove().setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				arrayList.remove(temp);
				notifyDataSetChanged();
			}
		});
		return v;
	}
	
	private class ListViewHolder {
		private View v;
		private TextView text_menuname;
		private EditText edit_quantity;
		private Button button_plus;
		private Button button_minus;
		private Button button_remove;
		
		ListViewHolder(View v) {
			this.v = v;
		}
		
		TextView getText_menuName() {
			if(text_menuname == null) {
				text_menuname = (TextView) v.findViewById(R.id.text_order_menuname);
			}
			return text_menuname;
		}
		
		EditText getEdit_quantity() {
			if(edit_quantity == null) {
				edit_quantity = (EditText) v.findViewById(R.id.edit_quantity);
			}
			return edit_quantity;
		}
		
		Button getButton_plus() {
			if(button_plus == null) {
				button_plus = (Button) v.findViewById(R.id.button_plus);
			}
			return button_plus;
		}
		
		Button getButton_minus() {
			if(button_minus == null) {
				button_minus = (Button) v.findViewById(R.id.button_minus);
			}
			return button_minus;
		}
		
		Button getButton_remove() {
			if(button_remove == null) {
				button_remove = (Button) v.findViewById(R.id.button_remove);
			}
			return button_remove;
		}
	}
}

 

위대한용샄 (220 포인트) 님이 2015년 7월 24일 질문

1개의 답변

+2 추천
 
채택된 답변

getView가 호출되는 것은 notifyDataSet등으로 리스트뷰의 데이터에 변화가 생겼을 경우에 다시 그리기 위해 반복적으로 호출됩니다.

생각해보시면 final int temp = position;

문장에서 temp에 어떤 데이터가 저장되어 있을까요?

만약에 주문화면에 주문된 데이터가 10개라면, 0~9까지의 index값에서 getView는 최소한 10번 호출이 될것이고,

0, 1, 2,3,4~~~ 9까지 getView가 호출된다면 temp = 9;

가 되겠지요.

 

그럼 화면에 어느 버튼을 누르더라도 마지막에 저장된 데이터가 삭제될겁니다.

또한 화면을 넘어가는 리스트 예를들어서 30개 이상 주문을 넣었다.

이러면 temp에 저장되는 데이터는 화면에 보이는 리스트의 마지막 index가 저장됩니다.

 

그러니까..... 리스너에 데이터를 전달하기 위해서 final 을 사용하시면 안되요;;;

거참.. 이거 어디서부터 말씀드려야하는지;;;;

dante2k (8,390 포인트) 님이 2015년 7월 24일 답변
위대한용샄님이 2015년 7월 25일 채택됨
답변감사합니다. 그런데 arrayList.remove가 속한 메소드가 getVeiw 안의 Listener라서 final로 선언하지 않으면 에러가 되버리는데 어떻게 다른 방법이 있나요 ?;;
...