2 komentarze

Obsługa kliknięć różnych kontrolek w wierszu ListView

Sierpień 25, 2011 Snippety UI

Kod źródłowy jest przykładem adaptera komponentu ListView. Umożliwia on obsługę kliknięcia na jednym z dwóch przycisków każdego wiersza.

W tym wypadku zwraca on pozycję elementu w kursorze, aczkolwiek zamiast tego możemy przekazywać inne obiekty. Bardziej istotne linijki kodu zostały podkreślone.

Adapter listy

public class ContactListAdapter extends SimpleCursorAdapter {
	private Context context;
	private Cursor c;
	private int displayNameColumnIndex;

	private OnClickListener onItemEditClickListener;
	private OnClickListener onItemDeleteClickListener;

	public ContactListAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
		super(context, layout, c, from, to);
		this.context = context;
		this.c = c;
		displayNameColumnIndex = c.getColumnIndex(Contacts.DISPLAY_NAME);
	}

	static class ViewHolder {
		TextView tvDisplayName;
		ImageButton ibEditContact;
		ImageButton ibDeleteContact;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder viewHolder;
		View rowView = convertView;
		if(rowView == null) {
			LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			rowView = layoutInflater.inflate(R.layout.contact_row, null, true);
			viewHolder = new ViewHolder();
			viewHolder.tvDisplayName = (TextView) rowView.findViewById(R.id.tvDisplayName);
			viewHolder.ibEditContact = (ImageButton) rowView.findViewById(R.id.ibEdit);
			viewHolder.ibDeleteContact = (ImageButton) rowView.findViewById(R.id.ibDelete);
			viewHolder.ibEditContact.setOnClickListener(new OnClickListener() {
				public void onClick(View v) {
					if(onItemEditClickListener != null) onItemEditClickListener.onClick(v);
				}
			});
			viewHolder.ibDeleteContact.setOnClickListener(new OnClickListener() {
				public void onClick(View v) {
					if(onItemDeleteClickListener != null) onItemDeleteClickListener.onClick(v);
				}
			});
			rowView.setTag(viewHolder);
		} else {
			viewHolder = (ViewHolder) rowView.getTag();
		}
		c.moveToPosition(position);
		viewHolder.tvDisplayName.setText(c.getString(displayNameColumnIndex));
		viewHolder.ibEditContact.setTag(new Integer(position));
		viewHolder.ibDeleteContact.setTag(new Integer(position));
		return rowView;
	}

	public void setOnItemDeleteClickListener(
			OnClickListener onItemDeleteClickListner) {
		this.onItemDeleteClickListener = onItemDeleteClickListner;
	}

	public void setOnItemEditClickListener(
			OnClickListener onItemEditClickListener) {
		this.onItemEditClickListener = onItemEditClickListener;
	}
}

Działanie adaptera polega na na ustawieniu onClickListener na każdym przycisku w wierszu (linijki 33-42). Każdy z listenerów przekazuje kliknięcie do kolejnych listenerów (zadeklarowanych w linijce 6 i 7), które będziemy ustawiać już z poziomu Aktywności.

W linijce 49 i 50 do widoku każdego z przycisków dodajemy dodatkowe informacje, w postaci obiektu przechowującego pozycję kursora (za pomocą metody setTag(…) można przekazać dowolny obiekt).

Aktywność korzystająca z powyższego adaptera

public class MainActivity extends ListActivity {
	private ContentResolver contentResolver;
	private Cursor contactsCursor;

	private OnClickListener onItemDeleteClickListener = new OnClickListener() {
		public void onClick(View v) {
			int position = (Integer) v.getTag();
			showToast("Delete: " + position + " item");
		}
	};

	private OnClickListener onItemEditClickListener = new OnClickListener() {
		public void onClick(View v) {
			int position = (Integer) v.getTag();
			showToast("Edit: " + position + " item");
		}
	};
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		contentResolver = getContentResolver();
		contactsCursor = getContactsCursor();
		ContactListAdapter adapter = new ContactListAdapter(
				getApplicationContext(), R.layout.contact_row, contactsCursor,
				new String[0], new int[0]);
		adapter.setOnItemDeleteClickListener(onItemDeleteClickListener);
		adapter.setOnItemEditClickListener(onItemEditClickListener);
		setListAdapter(adapter);
	}

	private Cursor getContactsCursor() {
		Uri uri = Contacts.CONTENT_URI;
		String[] projection = {
			Contacts._ID,
			Contacts.DISPLAY_NAME	
		};
		return contentResolver.query(uri, projection, null, null, null);
	}
	
	private void showToast(String msg) {
		Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
	}
}

W linijkach 5-10 oraz 12-17 definiujemy listenery kliknięć dla elementów pojedynczego wiersza. Wewnątrz nich odzyskiwany jest obiekt przekazany w adapterze (w naszym przypadku pozycja kursora).

Linijki 28 i 29 przekazują listenery do adaptera.

Efekt działania

Komentarze (2) Subskrybuj

 

  1. MST pisze:

    Ostatni wiersz na dole mam błędny, ale jak zrobić by na prawdę skasować wiersz z bazy?
    Mam adapter bazy i w nim metodę deleteObiekty.

    private OnClickListener onItemDeleteClickListener = new OnClickListener() {
    public void onClick(View v) {
    int position = (Integer) v.getTag();
    showToast(„Delete: ” + position + ” pozycja”);

    DatabaseAdapter.deleteObiekty(position);
    }
    };

    • MST pisze:

      private OnClickListener onItemDeleteClickListener = new OnClickListener() {
      public void onClick(View v) {
      int position = (Integer) v.getTag();
      showToast(„Delete: ” + (position+1) + ” pozycja”);

      myDBAdapter.deleteObiekty(position+1);
      }
      };

      Zrobiłem coś takiego i coś tam usuwa ale pozycja chyba nie zgadza się id w bazie,

Prześlij komentarz

Zaloguj się lub skorzystaj z profilu:

[rpxlogin redirect="http://www.android4devs.pl" prompt="" style="large"]

Możesz również zostawić komentarz bez rejestracji, korzystając z poniższego formularza:

Musisz być zalogowany aby móc pisać komentarze.