Android – SeparatedListAdapter – Как получить точную позицию позиции на onClick?

Я использую класс SeparatedListAdapter от Sharkey, чтобы иметь ListView, который разделен разделами.

Класс отлично работает, но проблема у меня в моем обработчике onListItemClick() . Если у меня есть следующий раздел:

 --------- | A | --------- | Alex | | Allan | --------- | B | --------- | Barry | | Bart | | Billy | | Brian | --------- | C | --------- etc... 

Когда вы хотите щелкнуть элемент в списке, вы получите position элемента, а затем сделаете что-нибудь с ним.

В моем случае мой список – это динамический список имен людей. Имена поступают из базы данных, которая помещается в List<CustomClass> прежде чем переходить в список. Мне важно знать позицию элемента, на который я нажимаю, потому что я использую позицию position чтобы определить другую информацию о человеке в объекте «Список».

Теперь проблема заключается в следующем: когда вы нажимаете элемент в списке, заголовки считаются как элементы, даже если они не имеют значения. В приведенном выше примере позиции в списке выглядят следующим образом

 Alex = 1 Allan = 2 Barry = 4 Bart = 5 Billy = 6 Brian = 7 

Но в моем исходном объекте List заказ выглядит так

 Alex = 0 Allan = 1 Barry = 2 Bart = 3 Billy = 4 Brian = 5 

Поэтому всякий раз, когда я нажимаю на элемент, например Алекс, мой код запускает обработчик onClick , он определяет, что Алекс находится в позиции 1 в List а затем извлекает информацию Allans из List вместо Alex.

Вы видите делимму здесь? Какой подход я должен принять к этой проблеме?

Вы можете использовать setTag() для каждого элемента в listView . Это можно сделать, добавив этот тег, прежде чем возвращать представление из функции getView() в listAdapter . Скажем, ваш адаптер списка возвращает convertView , а затем в адаптер списка.

  public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = mLayoutInflater.inflate(R.layout.morestores_list_item, null); holder = new ViewHolder(); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } // populate holder here, that is what you get in onItemClick. holder.mNameofItem = "NameofaPerson"; return convertView; } static class ViewHolder { TextView mName; Button mAction; ImageView mLogo; // use this class to store the data you need, and use appropriate data types. String mNameofItem. } 

Когда вы нажимаете на элемент списка, используйте

 public void onItemClick(AdapterView<?> arg0, View convertView, int arg2, long arg3) { ViewHolder holder = (ViewHolder) convertView.getTag(); // holder has what ever information you have passed. String nameofItemClicked = holder.mNameofItem; // access the information like this. } 

Этот подход не нуждается в позиции элемента в списке, просто хотел бы сообщить вам другой подход.

НТН.

Мое решение было вместо того, чтобы получить позицию в списке, а затем использовать это, чтобы получить объект из ListArray или Hash, чтобы просто получить объект в этой позиции в адаптере, а затем извлечь из него все необходимые параметры или методы. Сейчас это очевидно, но сначала это не имеет смысла.

UPDATE Это длинный бит кода, поэтому я просто дам обзор:

Вместо передачи в String элемента списка, перейдите в пользовательский объект. Допустим, у этого объекта есть два разных значения, которые он хранит. Имя (восстанавливается с помощью общедоступного метода getName() ) и идентификатора (извлекаемого getId() ).

Вы должны переопределить метод getView() для класса адаптера и сделать его getName() объекта и использовать этот текст для отображения в элементе списка.

Затем, когда элемент щелкнут, просто получите объект от адаптера в этой позиции, а затем получите идентификатор:

 int id = adapter.get(position).getId(); // Then do something with the ID, pass it to an activity/intent or whatever. 

Также я отбросил SeparatedListViewAdapter в пользу этого . Гораздо лучше и гибче.

  int idNo= adapter.get(position).getId(); 

Вы можете попробовать этот код …

Для кого-то еще я слишком недавно столкнулся с этой проблемой и оказался здесь, я решил:

Сначала изменив карту, чтобы взять «id»,

 public Map<String,?> createItem(String title, String caption, String id) { Map<String,String> item = new HashMap<String,String>(); item.put(ITEM_TITLE, title); item.put(ITEM_CAPTION, caption); item.put("id", id); // Add a unique id to retrieve later return item;} 

Во-вторых, добавив раздел, обязательно включите идентификатор:

  List<Map<String,?>> GeneralSection = new LinkedList<Map<String,?>>(); GeneralSection.add(createItem(FirstName[GeneralInt] + " " + LastName[GeneralInt], Whatever[GeneralInt], UniqueId[GeneralInt])); //Unique id could be populated anyway you like, database index 1,2,3,4.. for example like above question. adapter.addSection("GeneralSection ", new SimpleAdapter(getActivity(), GeneralSection , R.layout.list_complex, new String[] { ITEM_TITLE, ITEM_CAPTION }, new int[] { R.id.list_complex_title, R.id.list_complex_caption })); 

Наконец, используйте Map в ItemClickListener для получения «id» правильной позиции:

  @Override public void onItemClick(AdapterView<?> arg0, View v, int position, long arg3) { // TODO Auto-generated method stub Map<String, String> map = (Map<String, String>) arg0.getItemAtPosition(position); String UniqueId = map.get("id"); Log.i("Your Unique Id is", UniqueId); //Can then use Uniqueid for whatever purpose //or any other mapped data for that matter..eg..String FirstName = map.get("ITEM_TITLE"); } 

Надеюсь, это поможет кому-то.