Урок 54. Кастомизация списка. Создаем свой адаптер

Обсуждение уроков
razmus
Сообщения: 82
Зарегистрирован: 26 мар 2013, 10:47

Re: Урок 54. Кастомизация списка. Создаем свой адаптер

Сообщение razmus » 08 мар 2014, 10:16

Нет не верно поняли, дело в том, что из активити с кнопкой, я не могу забрать View EditText из ListView item, которое сейчас выбрано и "возможно" редактируется, я просто не могу узнать его из другого класса. Точнее я себе не представляю конструкцию метода который вернет мне вюху которая сейчас выбрана. Мне нужно сбросить фокус в ListView тогда условие "(!hasFocus)" сработает и данные добавятся куда нужно, решение вынести вставку данных в другое место не поможет. this.notifyDataSetChanged(); Сбрасывает фокус и данные добавляются, условие срабатывает. Но забор данных происходит по чему-то со второго раза, дублировать условие "забора" я пробовал, также пробовал переключать фокус на кнопку, но результата не дало.

класс с "кнопкой"

Код: Выделить всё

public class MainActivity extends Activity implements OnClickListener{

  ArrayList<Product> products = new ArrayList<Product>();
  BoxAdapter boxAdapter;
  Button btnSave;

  /** Called when the activity is first created. */
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Button btnSave = (Button) findViewById(R.id.btnSave);
    btnSave.setOnClickListener(this);

    // создаем адаптер
    fillData();
    boxAdapter = new BoxAdapter(this, products);

    // настраиваем список
    ListView lvMain = (ListView) findViewById(R.id.lvMain);
    lvMain.setAdapter(boxAdapter);
  }

  // генерируем данные для адаптера
  void fillData() {
    for (int i = 1; i <= 20; i++) {
      products.add(new Product("Product " + i, i * 1000,
          R.drawable.ic_launcher, false, ""));
    }
  }

  // выводим информацию о корзине


@Override
public void onClick(View v) {
		    String result = "Товары в корзине:";
		    boxAdapter.unFocus();
		    v.requestFocus();
		        for (Product p : boxAdapter.getBox()) {
		    	if (!p.number.equals(""))
		        result += "\n" + p.number;
		    }
		    Toast.makeText(this, result, Toast.LENGTH_LONG).show();
}
}


razmus
Сообщения: 82
Зарегистрирован: 26 мар 2013, 10:47

Re: Урок 54. Кастомизация списка. Создаем свой адаптер

Сообщение razmus » 11 мар 2014, 11:03

Нашел решение, в onClick добавил v.requestFocusFromTouch(); и все стало отрабатывать как надо)) Спасибо за помощь.

Barrya42
Сообщения: 10
Зарегистрирован: 19 сен 2012, 13:05

Re: Урок 54. Кастомизация списка. Создаем свой адаптер

Сообщение Barrya42 » 02 апр 2014, 10:01

Подскажите, как сделать чтобы адаптер подставлял в ImageView не по ID ресурса, а либо готовый Drawable или картинку по ссылке URL.Спасибо.

aleksbim
Сообщения: 81
Зарегистрирован: 02 фев 2013, 02:52

Re: Урок 54. Кастомизация списка. Создаем свой адаптер

Сообщение aleksbim » 03 июн 2014, 22:44

Подскажите пжл.
Список создается путем добавления новых элементов при нажатии кнопки
1. Как сохранить количество элементов в созданном списке при закрытии приложения?
2. Как сохранить введенные значения в каждом из них?
Вложения
Снимок.JPG
Снимок.JPG (23.36 КБ) 12863 просмотра

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Урок 54. Кастомизация списка. Создаем свой адаптер

Сообщение Foenix » 04 июн 2014, 12:00

использовать базу данных
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

Аватара пользователя
Leeroy
Сообщения: 67
Зарегистрирован: 12 дек 2013, 21:25

Re: Урок 54. Кастомизация списка. Создаем свой адаптер

Сообщение Leeroy » 27 июн 2014, 12:25

Помогите пожалуйста понять, почему данные чекбоксов меняются при прокрутке вниз, затем вверх?

ListView при первом отображении показывает список с чекбоксами, все что на экране правильно отмечены.
При прокрутке списка вниз затем вверх (ничего не выбирая, и не чекая), данные чекбоксов меняются.

Использую pattern ViewHolder, хотя без него тоже самое.

Изображение Изображение

Код: Выделить всё

package com.mytvshed.newraspisanie.adapters;

import java.util.List;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.TextView;

import com.mytvshed.newraspisanie.Channel;
import com.mytvshed.newraspisanie.MapConstants;
import com.mytvshed.newraspisanie.TvConstants;
import com.mytvshed.tvraspisanie.R;

public class PreferenceAdapter extends BaseAdapter {

	private LayoutInflater lInflater;
	private List<Channel> listAllChannel;
	private Context context;

	public PreferenceAdapter(List<Channel> allList, Context ctx) {

		listAllChannel = allList;
		context = ctx;
		lInflater = (LayoutInflater) context
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	}

	private static class ViewHolder {
		ImageView imgeView;
		TextView title;
		CheckBox checkBox;
	}

	@Override
	public int getCount() {
		return listAllChannel.size();
	}

	@Override
	public Object getItem(int position) {
		return listAllChannel.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {

		ViewHolder viewHolder;

		if (convertView == null) {

			Log.d(TvConstants.TAG, "convertView == null " + position);
			viewHolder = new ViewHolder();

			// inflate view
			convertView = lInflater.inflate(R.layout.item_in_preferences,
					parent, false);

			// Find fields ViewHolders
			viewHolder.imgeView = (ImageView) convertView
					.findViewById(R.id.pref_image);
			viewHolder.title = (TextView) convertView
					.findViewById(R.id.pref_text_view);
			viewHolder.checkBox = (CheckBox) convertView
					.findViewById(R.id.pref_check_box);

			convertView.setTag(viewHolder);
		}

		else {
			Log.d(TvConstants.TAG, "convertView != null " + position);
			viewHolder = (ViewHolder) convertView.getTag();
		}

		Channel channel = getChannel(position);

		// Title in item
		String title = channel.getTitle();
		viewHolder.title.setText(title);

		// Image in Item
		Integer imageId = MapConstants.getIdImage(title);
		viewHolder.imgeView.setImageResource(imageId);

		// CheckBox in Item
		boolean checked = channel.isChecked();
		viewHolder.checkBox.setChecked(checked);
		viewHolder.checkBox.setTag(position);

		// CheckedListener
		viewHolder.checkBox
				.setOnCheckedChangeListener(new OnCheckedChangeListener() {
                                          
                                             //change data in list<Channel>
					@Override
					public void onCheckedChanged(CompoundButton buttonView,
							boolean isChecked) {
						Channel channel = getChannel((Integer) buttonView
								.getTag());
						channel.setChecked(isChecked);
					}
				});

		return convertView;
	}

	private Channel getChannel(int position) {
		return (Channel) getItem(position);
	}
}

package com.mytvshed.newraspisanie;

public interface Channel {
	
	public String getTitle();

	public boolean isChecked();

	public void setChecked(boolean isChecked);

	
}
Java Core -> JDBC -> GoF -> Android SDK ->...
Телепрограмма в твоем смарте Телепрограмма

Viewer
Сообщения: 180
Зарегистрирован: 30 апр 2014, 11:42

Re: Урок 54. Кастомизация списка. Создаем свой адаптер

Сообщение Viewer » 27 июн 2014, 13:35

Leeroy писал(а):Помогите пожалуйста понять, почему данные чекбоксов меняются при прокрутке вниз, затем вверх?
Избитая тема, сейчас прилетит Foenix и будет ругаться и вполне справедливо, прошу заметить :)

Где вы сохраняете данные о том какие чекбоксы у вас чекнуты какие нет? Какой адаптер вы используете и биндите (проецируете) ли данные о состоянии чекбоксов на эти чекбоксы?

Я вам могу рассказать почему это происходит, для понимания, хотя это я уже не раз повторял.
ListView не создает и не держит в памяти все элементы списка, это будет очень расточительно по отношению к памяти устройства, он создает только те элементы которые видны на экране. Когда вы прокручиваете список, к примеру, вверх - верхние элементы уходят и когда они становятся не видны, ListView думает - ага, элемент не виден, но в памяти содержится, зачем зря добру пропадать, если можно его использовать повторно для тех элементов, которые выползают и родятся на свет божий снизу, поэтому он без всякого зазрения совести вместо создания нового элемента берет тот, что уполз наверх и просто заполняет его данными, которые ему поставляет адаптер. Если у вас нет данных о состоянии чекбоксов, то он и оставляет их нетронутыми, т.е. те чекбоксы, что были чекнуты и уползли наверх, появятся снизу в том же состоянии и так и будут ходить покругу.

Аватара пользователя
Leeroy
Сообщения: 67
Зарегистрирован: 12 дек 2013, 21:25

Re: Урок 54. Кастомизация списка. Создаем свой адаптер

Сообщение Leeroy » 27 июн 2014, 14:37

Viewer писал(а):
Leeroy писал(а):Помогите пожалуйста понять, почему данные чекбоксов меняются при прокрутке вниз, затем вверх?
Избитая тема, сейчас прилетит Foenix и будет ругаться и вполне справедливо, прошу заметить :)

Где вы сохраняете данные о том какие чекбоксы у вас чекнуты какие нет? Какой адаптер вы используете и биндите (проецируете) ли данные о состоянии чекбоксов на эти чекбоксы?
....
Данные о чекнутых/нечекнутых чекбоксах храню в адаптере в коллекции, которую адаптер получает в конструкторе, оттуда же он их и берет в View getView().
Использую реализацию BaseAdapter.
Java Core -> JDBC -> GoF -> Android SDK ->...
Телепрограмма в твоем смарте Телепрограмма

Viewer
Сообщения: 180
Зарегистрирован: 30 апр 2014, 11:42

Re: Урок 54. Кастомизация списка. Создаем свой адаптер

Сообщение Viewer » 27 июн 2014, 14:41

Leeroy писал(а): Данные о чекнутых/нечекнутых чекбоксах храню в адаптере в коллекции, которую адаптер получает в конструкторе, оттуда же он их и берет в View getView().
Использую реализацию BaseAdapter.
а вот getView() как раз меньше всего подходит чтобы биндить (проецировать) данные на разметку элементов списка. Я не зря повторяю это слово ("биндить") потому как надеюсь, что оно наведет вас на правильные мысли.

getView() нужен для создания самих элементов списка для показа их на экране, а вот за заполнение их данными отвечают совсем другие методы адаптера.

Аватара пользователя
anber
Сообщения: 584
Зарегистрирован: 10 июн 2013, 15:05
Откуда: UA

Re: Урок 54. Кастомизация списка. Создаем свой адаптер

Сообщение anber » 16 июл 2014, 08:47

Viewer писал(а): а вот getView() как раз меньше всего подходит чтобы биндить (проецировать) данные на разметку элементов списка. Я не зря повторяю это слово ("биндить") потому как надеюсь, что оно наведет вас на правильные мысли.

getView() нужен для создания самих элементов списка для показа их на экране, а вот за заполнение их данными отвечают совсем другие методы адаптера.
А какие все же методы адаптера использовать для того чтобы биндить?
Личные сообщения с просьбой ответить на форуме или написать программу я просто удаляю, если я в хорошем настроении. Если в плохом добавляю автора в черный список. По любым другим вопросам feel free to write to me.

Viewer
Сообщения: 180
Зарегистрирован: 30 апр 2014, 11:42

Re: Урок 54. Кастомизация списка. Создаем свой адаптер

Сообщение Viewer » 16 июл 2014, 09:05

anber писал(а): А какие все же методы адаптера использовать для того чтобы биндить?
Для этого есть интерфейс ViewBinder
В простейших случаях можно использовать setViewImage и setViewText

Аватара пользователя
anber
Сообщения: 584
Зарегистрирован: 10 июн 2013, 15:05
Откуда: UA

Re: Урок 54. Кастомизация списка. Создаем свой адаптер

Сообщение anber » 16 июл 2014, 10:45

Viewer писал(а): Для этого есть интерфейс ViewBinder
В простейших случаях можно использовать setViewImage и setViewText
ViewBinder объявлен в классе SimpleAdapter, а никак не в BaseAdapter и его кастомных наследниках. Более того это простая надстройка, которая нужная для метода bindView() который вызывается из getView() т.е. фактически нет разницы делать биндинг вручную в getView() или через биндинг, более того если логика чуть более сложная или view нестандартный(bindView может переванить только если view instanceof Checkable, TextView или ImageView) то нужно это все делать в getView()
Личные сообщения с просьбой ответить на форуме или написать программу я просто удаляю, если я в хорошем настроении. Если в плохом добавляю автора в черный список. По любым другим вопросам feel free to write to me.

Viewer
Сообщения: 180
Зарегистрирован: 30 апр 2014, 11:42

Re: Урок 54. Кастомизация списка. Создаем свой адаптер

Сообщение Viewer » 16 июл 2014, 15:15

anber писал(а): ViewBinder объявлен в классе SimpleAdapter, а никак не в BaseAdapter и его кастомных наследниках. Более того это простая надстройка, которая нужная для метода bindView() который вызывается из getView() т.е. фактически нет разницы делать биндинг вручную в getView() или через биндинг, более того если логика чуть более сложная или view нестандартный(bindView может переванить только если view instanceof Checkable, TextView или ImageView) то нужно это все делать в getView()
Конечно в BaseAdapter этих методов нет, но для лучшей структуризации кода при написании своих адаптеров тоже не помешает отделять данные от представлений это нормальная практика.
Что касается bindView, то если данные SimpleAdapter биндятся не только на view Checkable, TextView или ImageView то имеет смысл реализовать ViewBinder, иначе можно обойтись без него. Считаю что лепить все в getView(), будет не очень грамотно. а если у вас для всех элементов списка используется одна и та же разметка, то и вовсе нет смысла переопределять getView().
Достаточно часто для видоизменения элементов списка, используется прием скрытия/отображения отдельных View-компонентов разметки в зависимости от набора данных, что так же не требует реализации getView().
В общем смысл моего поста не в том что нельзя или можно что-то там сделать, а в том, что если есть дверь, то какой смысл ходить через окно или изобретать велосипеды. Нужно сразу приучать себя писать хороший структуированный код в котором даже самому потом, по прошествии времени, будет легче разобраться, не говоря уже о том, что в вашем коде будет пытаться разобраться кто-то другой.

Аватара пользователя
anber
Сообщения: 584
Зарегистрирован: 10 июн 2013, 15:05
Откуда: UA

Re: Урок 54. Кастомизация списка. Создаем свой адаптер

Сообщение anber » 16 июл 2014, 16:12

Viewer писал(а):Конечно в BaseAdapter этих методов нет, но для лучшей структуризации кода при написании своих адаптеров тоже не помешает отделять данные от представлений это нормальная практика.
Что касается bindView, то если данные SimpleAdapter биндятся не только на view Checkable, TextView или ImageView то имеет смысл реализовать ViewBinder, иначе можно обойтись без него. Считаю что лепить все в getView(), будет не очень грамотно. а если у вас для всех элементов списка используется одна и та же разметка, то и вовсе нет смысла переопределять getView().
Достаточно часто для видоизменения элементов списка, используется прием скрытия/отображения отдельных View-компонентов разметки в зависимости от набора данных, что так же не требует реализации getView().
В общем смысл моего поста не в том что нельзя или можно что-то там сделать, а в том, что если есть дверь, то какой смысл ходить через окно или изобретать велосипеды. Нужно сразу приучать себя писать хороший структуированный код в котором даже самому потом, по прошествии времени, будет легче разобраться, не говоря уже о том, что в вашем коде будет пытаться разобраться кто-то другой.
Я ж не со зла пишу, и не потому что в интернет кто то не прав (с) мне реально интересно.
К примеру довольно частая задача - в элементе списка есть кнопка на которую нужно навесить клик листенер, как это сделать не переопределяя getView() ?

>>>Достаточно часто для видоизменения элементов списка, используется прием скрытия/отображения отдельных View-компонентов разметки в зависимости от набора данных, что так же не требует реализации getView().
Мы же говорит про наследника BaseAdapter или как? Да даже в случае SimpleAdapter как достигается "скрытия/отображения отдельных View-компонентов разметки в зависимости от набора данных" без переопределения getView()?

>>>для лучшей структуризации кода при написании своих адаптеров тоже не помешает отделять данные от представлений это нормальная практика.
абсолютно согласен

>>>Нужно сразу приучать себя писать хороший структуированный код в котором даже самому потом, по прошествии времени, будет легче разобраться, не говоря уже о том, что в вашем коде будет пытаться разобраться кто-то другой
абсолютно согласен

>>>Считаю что лепить все в getView(), будет не очень грамотно
По поводу этого момента я делаю как показано еще в древнем видео "Google I/O 2010 - The world of ListView", может я и не прав. Ведь никто на говорит в методе getView() должно быть больше 1000 строк.
Я обычно использую что-то типа такого:

Код: Выделить всё

            public View getView(int position, View convertView, ViewGroup parent) {
                if (convertView == null) {
                    LayoutInflater inflater = LayoutInflater.from(MyActivity.this);
                    convertView = inflater.inflate(R.layout.item, parent, false);
                }
                instantiateView(convertView, getItem(position));
                return convertView;
            }
            private void instantiateView(View itemViev, SomeType item){...};

Для меня и для тех кто читал мой код он предельно понятен, в методе instantiateView() мапится(проецируется, биндится) item на itemViev без создания всяких дополнительных объектов типа биндер.
Личные сообщения с просьбой ответить на форуме или написать программу я просто удаляю, если я в хорошем настроении. Если в плохом добавляю автора в черный список. По любым другим вопросам feel free to write to me.

Viewer
Сообщения: 180
Зарегистрирован: 30 апр 2014, 11:42

Re: Урок 54. Кастомизация списка. Создаем свой адаптер

Сообщение Viewer » 16 июл 2014, 17:28

Да даже в случае SimpleAdapter как достигается "скрытия/отображения отдельных View-компонентов разметки в зависимости от набора данных" без переопределения getView()?
Легко, в метод setViewValue ViewBinder-а, как и в методы setViewImage и setViewText адаптера передаются сами эти View, ничего не мешает применять к ним метод setVisibility(). Причем это всегда работает правильно и глюков связанных с повторным использованием разметки элементов списка адаптером точно не будет. Да и глюки, перерасход памяти и тормоза ListView чаще всего возникают из-за неправильной реализации getView(), когда программист сводит на нет всю оптимизацию ListView задуманную гугловцами.
Для меня и для тех кто читал мой код он предельно понятен, в методе instantiateView() мапится(проецируется, биндится) item на itemViev без создания всяких дополнительных объектов типа биндер.
Ну так этот ваш instantiateView() это аналог bindView() в SimpleAdapter, а интерфейс ViewBinder применяется для большей универсальности, если вы пишете свой адаптер на базе BaseAdapter-а то конечно можно не писать дополнительных интерфейсов, тут все зависит от личных пристрастий :) тут можно спорить до бесконечности, я так довольно часто пользуюсь интерфейсами (я имею в виду вообще, а не применительно к адаптерам), хотя во многих случаях можно было выкрутиться и без них.

Аватара пользователя
anber
Сообщения: 584
Зарегистрирован: 10 июн 2013, 15:05
Откуда: UA

Re: Урок 54. Кастомизация списка. Создаем свой адаптер

Сообщение anber » 16 июл 2014, 18:03

Написал пример что я имею в виду, опубликую на всякий случай - зря писал что-ли :D

Пример №1 - взят из Урок 50. SimpleAdapter. Используем ViewBinder

Код: Выделить всё

public class BinderActivity extends Activity {

    final String ATTRIBUTE_NAME_TEXT = "text";
    final String ATTRIBUTE_NAME_PB = "pb";
    final String ATTRIBUTE_NAME_LL = "ll";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        int load[] = {41, 48, 22, 35, 30, 67, 51, 88};

        ArrayList<Map<String, Object>> data = new ArrayList<Map<String, Object>>(load.length);
        Map<String, Object> m;
        for (int i = 0; i < load.length; i++) {
            m = new HashMap<String, Object>();
            m.put(ATTRIBUTE_NAME_TEXT, "Day " + (i + 1) + ". Load: " + load[i] + "%");
            m.put(ATTRIBUTE_NAME_PB, load[i]);
            m.put(ATTRIBUTE_NAME_LL, load[i]);
            data.add(m);
        }

        String[] from = {ATTRIBUTE_NAME_TEXT, ATTRIBUTE_NAME_PB, ATTRIBUTE_NAME_LL};
        int[] to = {R.id.tvLoad, R.id.pbLoad, R.id.llLoad};

        SimpleAdapter sAdapter = new SimpleAdapter(this, data, R.layout.item, from, to);
        sAdapter.setViewBinder(new MyViewBinder());

        ListView lvSimple = (ListView) findViewById(R.id.lvSimple);
        lvSimple.setAdapter(sAdapter);
    }

    class MyViewBinder implements SimpleAdapter.ViewBinder {

        int red = getResources().getColor(android.R.color.holo_red_dark);
        int orange = getResources().getColor(android.R.color.holo_orange_dark);
        int green = getResources().getColor(android.R.color.holo_green_dark);

        @Override
        public boolean setViewValue(View view, Object data,
                                    String textRepresentation) {
            int value;
            switch (view.getId()) {
                // LinearLayout
                case R.id.llLoad:
                    value = (Integer) data;
                    if (value < 40) {
                        view.setBackgroundColor(green);
                    } else {
                        if (value < 70) {
                            view.setBackgroundColor(orange);
                        } else {
                            view.setBackgroundColor(red);
                        }
                    }
                    return true;
                // ProgressBar
                case R.id.pbLoad:
                    value = (Integer) data;
                    ((ProgressBar) view).setProgress(value);
                    return true;
            }
            return false;
        }
    }

}
Пример №2 - как я обычно делаю

Код: Выделить всё

public class GetViewActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);


        List<Integer> load = Arrays.asList(41, 48, 22, 35, 30, 67, 51, 88);
        ArrayAdapter<Integer> adapter = new MyListAdapter(this, load);

        ListView lvSimple = (ListView) findViewById(R.id.lvSimple);
        lvSimple.setAdapter(adapter);
    }

    private class MyListAdapter extends ArrayAdapter<Integer> {

        public MyListAdapter(Context context, List<Integer> objects) {
            super(context, 0, objects);
        }

        int red = getResources().getColor(android.R.color.holo_red_dark);
        int orange = getResources().getColor(android.R.color.holo_orange_dark);
        int green = getResources().getColor(android.R.color.holo_green_dark);

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                LayoutInflater inflater = LayoutInflater.from(getApplicationContext());
                convertView = inflater.inflate(R.layout.item, parent, false);
            }
            instantiateView(convertView, getItem(position));
            return convertView;
        }

        private void instantiateView(View itemView, Integer item) {
            // LinearLayout
            View loadView = itemView.findViewById(R.id.llLoad);
            if (item < 40) {
                loadView.setBackgroundColor(green);
            } else {
                if (item < 70) {
                    loadView.setBackgroundColor(orange);
                } else {
                    loadView.setBackgroundColor(red);
                }
            }

            // ProgressBar
            ((ProgressBar) itemView.findViewById(R.id.pbLoad)).setProgress(item);
        }
    }

}
Повторюсь, по моему личному мнению вариант 2 более расширяем и очевиден.
Личные сообщения с просьбой ответить на форуме или написать программу я просто удаляю, если я в хорошем настроении. Если в плохом добавляю автора в черный список. По любым другим вопросам feel free to write to me.

Viewer
Сообщения: 180
Зарегистрирован: 30 апр 2014, 11:42

Re: Урок 54. Кастомизация списка. Создаем свой адаптер

Сообщение Viewer » 17 июл 2014, 02:12

anber писал(а): Повторюсь, по моему личному мнению вариант 2 более расширяем и очевиден.
Мне так более очевиден 1-й вариант, к примеру, если мне нужно будет добавить в элементы списка дополнительные данные, то я сразу вижу куда и что нужно дописать, причем даже если этот код был написан кем-то другим мне на это потребуются считанные минуты. А если добавить простой TextView так вообще пару секунд, достаточно добавить соответствующие элементы во from и to (SimpleAdapter сам знает как вставлять текст в TextView).
Во-вторых код второго варианта будет работать медленнее т.к. в нем используется findViewById для каждого элемента, конечно можно от него избавиться вставив дополнительные костыли, к примеру, сделать цикл, чтобы пройтись и отмапить все элементы за один проход, или как-то кэшировать эти элементы (по типу ViewHolder), но это снизит наглядность кода.

Аватара пользователя
anber
Сообщения: 584
Зарегистрирован: 10 июн 2013, 15:05
Откуда: UA

Re: Урок 54. Кастомизация списка. Создаем свой адаптер

Сообщение anber » 17 июл 2014, 10:12

Ок, согласен это дело вкуса. А что по поводу навешивания клик листенеров на кнопки внутри елемента списка и подгрузки изображений типа ImageLoader?
Личные сообщения с просьбой ответить на форуме или написать программу я просто удаляю, если я в хорошем настроении. Если в плохом добавляю автора в черный список. По любым другим вопросам feel free to write to me.

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Урок 54. Кастомизация списка. Создаем свой адаптер

Сообщение KamiSempai » 17 июл 2014, 10:47

anber писал(а):Ок, согласен это дело вкуса. А что по поводу навешивания клик листенеров на кнопки внутри елемента списка...
Для такого дела, я давно написал абстрактный класс ContextedCursorAdapter. Остается только установить соответствующий листенер.
[syntax=java] public interface OnContextButtonClickListener {
public void onContextButtonClick(AdapterContextMenuInfo menuInfo);
}[/syntax]
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Аватара пользователя
anber
Сообщения: 584
Зарегистрирован: 10 июн 2013, 15:05
Откуда: UA

Re: Урок 54. Кастомизация списка. Создаем свой адаптер

Сообщение anber » 17 июл 2014, 10:49

А более детальный пример кода как этот листенер применять можно?
Личные сообщения с просьбой ответить на форуме или написать программу я просто удаляю, если я в хорошем настроении. Если в плохом добавляю автора в черный список. По любым другим вопросам feel free to write to me.

Ответить