Страница 2 из 8

Re: Урок 44. События в ListView

Добавлено: 05 сен 2012, 12:03
KamiSempai
Может быть Вы забыли указать слушателя в импорте?

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

import android.widget.AdapterView.OnItemClickListener

Re: Урок 44. События в ListView

Добавлено: 05 сен 2012, 12:14
math64
Т.е. ошибка не на слушателе, а на спиннере (т.е. создание слушателя не комментируешь)?
Попробуй сменить версию СДК (у меня например, стоит android-16 (4.1 - последняя версия с исходниками) и android-10 (2.3.3 - как телефоне).
Если при этом ошибка пропадёт - по видимому, та версия скачалась с ошибками, попробуй обновить.
KamiSempai писал(а):Может быть Вы забыли указать слушателя в импорте?
Ну. да - может быть импорт не на тот слушатель.
Я советую оставить

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

import android.widget.AdapterView
и писать

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

AdapterView.OnItemClickListener spinnerListner = new AdapterView.OnItemClickListener() { ... };

Re: Урок 44. События в ListView

Добавлено: 05 сен 2012, 13:41
etlt
Сейчас стоят API 10, 15, 16
переустановил API 10 т.к. пишу именно под неё
в импорте все норм пробовал и OnItemClickListener и AdapterView.OnItemClickListener

Очень странно, но такая ерунда только со спеннерами

Re: Урок 44. События в ListView

Добавлено: 05 окт 2012, 19:49
dil_android
Здравствуйте.

Пытаясь разобраться в адаптерах, приходишь к удивительным открытиям.
Так например, пытаясь реализовать удаление записей при помощи метода onContextItemSelected (урок 51) приминительно к ArrayAdapter<CharSequence>, узнал, что этот вид адаптера удаление, дополнение и редактирование записей не поддерживает (read-only).

http://stackoverflow.com/questions/3476 ... rayadapter

Проверил на примере:

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

public class MainActivity extends Activity {

    private static final int CM_DELETE_ID = 1;
    ArrayAdapter<CharSequence> adapter;

    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        String[] strings = new String[]{"One", "Two", "Three"};
        adapter = new ArrayAdapter<CharSequence>(this, android.R.layout.simple_list_item_1, android.R.id.text1, strings);

        ListView list = (ListView) this.findViewById(R.id.list);
        list.setAdapter(adapter);
        registerForContextMenu(list);

    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
            ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        menu.add(0, CM_DELETE_ID, 0, "Удалить запись");
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        if (item.getItemId() == CM_DELETE_ID) {
            // получаем инфу о пункте списка
            AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) item.getMenuInfo();
            // удаляем Map из коллекции, используя позицию пункта в списке

            adapter.remove(adapter.getItem(acmi.position));

            // уведомляем, что данные изменились
            adapter.notifyDataSetChanged();
            return true;
        }
        return super.onContextItemSelected(item);
    }
}

действительно, приложение валится при нажатии на удалить.
Скажите пожалуйста, это так должно быть или все таки есть возможности удаления, дополнения и редактирования записей в ArrayAdapter<CharSequence>.
Если да, можно ли пример.

Re: Урок 44. События в ListView

Добавлено: 05 окт 2012, 20:31
rezak90
всё он поддерживает, проверь что возвращает acmi.position, было бы легче найти ошибку если бы указывал строку где вылетает и лог ошибок.
А так я тысячу раз буду повторять что лучше писать кастомные адаптеры и всегда будешь знать где что не работает.

Re: Урок 44. События в ListView

Добавлено: 06 окт 2012, 02:20
AndreyI
rezak90 писал(а): лучше писать кастомные адаптеры и всегда будешь знать где что не работает.
А исходники на что?

Теперь по вопросу
Для любого адаптера источник данных всегда первичен, от него и нужно плясать (как от печки :)), ListView это только инструмент для отображения данных, а адаптер "знает" как связать источник данных и ListView. Поэтому, если вы хотите что-то изменить в ListView думайте прежде всего о том, что нужно будет, прежде всего, изменять источник данных.
В данном случае в качестве источника данных используется строковый массив String[]
Если обратиться к исходникам и посмотреть конструктор адаптера, который используется для данного примера, то мы увидим следующее:

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

   public ArrayAdapter(Context context, int textViewResourceId, T[] objects) {
        init(context, textViewResourceId, 0, Arrays.asList(objects));
    }
Строковый массив преобразуется в List с помощью статического метода Arrays.asList далее смотрим справку по этому методу
Returns a List of the objects in the specified array. The size of the List cannot be modified, i.e. adding and removing are unsupported, but the elements can be set. Setting an element modifies the underlying array.
Из чего нетрудно догадаться почему адаптер не может модифицировать источник данных для нашего ListView.
Собственно, логику разработчиков можно понять, т.к. в качестве источника данных используется массив, а в JAVA размеры массива после его создания изменить нельзя и дабы не возникало коллизий между источником данных и их отображением в ListView они использовали для преобразования именно этот метод, хотя вполне можно было преобразовать и в нормальный ArrayList.

Выход здесь прост, чтобы можно было динамически изменять ListView нужно применять такой источник данных, который тоже можно изменять (добавлять, удалять элементы и т.п.). В данном случае, в качестве такого источника лучше всего подходит ArrayList.
Строковый массив нужно преобразовать в ArrayList и использовать его в конструкторе адаптера в качестве источника данных:

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

...
String[] strings = new String[]{"One", "Two", "Three"};
ArrayList<CharSequence> array= new ArrayList(Arrays.asList(itemList));
adapter = new ArrayAdapter<CharSequence>(this, android.R.layout.simple_list_item_1, android.R.id.text1, array);
...

Re: Урок 44. События в ListView

Добавлено: 06 окт 2012, 07:35
dil_android
Андрей,
ваше объяснение понял, но логику разработчиков понять не могу.
После предложенного вами преобразования в ArrayList выкидывается ошибка:
error: no suitable constructor found for ArrayAdapter(MainActivity,int,int,ArrayList<String>)
Посмотрел исходники, действительно ArrayList не поддерживается.

ArrayAdapter(Context context, int textViewResourceId)
Constructor
ArrayAdapter(Context context, int resource, int textViewResourceId)
Constructor
ArrayAdapter(Context context, int textViewResourceId, T[] objects)
Constructor
ArrayAdapter(Context context, int resource, int textViewResourceId, T[] objects)
Constructor
ArrayAdapter(Context context, int textViewResourceId, List<T> objects)
Constructor
ArrayAdapter(Context context, int resource, int textViewResourceId, List<T> objects)
Constructor

Подскажите, что в этом случае делать.

И еще, получается, что каждый из адаптеров ущербен в определенном смысле этого слова, так как изначально писался под определенную логику разработчиков? Опять таки, возвращаясь к checkboxes, почему работа с ними требует написания отдельного метода для View?

P.S. Я не прошу Вас отвечать за разработчиков, и ответ: "мир не совершенен"; меня вполне устроит :)
Однако, если есть приемлемое решение по вопросу поднятому выше, буду признателен.

Спасибо.

Re: Урок 44. События в ListView

Добавлено: 06 окт 2012, 11:53
AndreyI
Исправил, попробуйте снова ;)

Re: Урок 44. События в ListView

Добавлено: 06 окт 2012, 12:02
dil_android
Где?

Re: Урок 44. События в ListView

Добавлено: 06 окт 2012, 12:05
AndreyI
В сообщении, блин
ArrayList<CharSequence> array= new ArrayList(Arrays.asList(itemList));

Re: Урок 44. События в ListView

Добавлено: 06 окт 2012, 12:14
dil_android
Работает. Спасибо, ваше объяснение оказалось не только правильным, но и практически реализованным.
В качестве рекомендации, мне кажется, автору следует дополнить уроки по адаптерам.
Такого же характера вопросы, какие возникают у меня, я видел у многих, посещающих этот форум.

Еще раз спасибо за разъяснение и реализацию.

Re: Урок 44. События в ListView

Добавлено: 08 окт 2012, 21:16
Quqush
damager82 писал(а):Возможно мало опыта работы с Java? Попробуйте что-нибудь прочесть из этой темы: viewtopic.php?f=17&t=147
Огромное спасибо за наводку (http://www.ibm.com/developerworks/ru/ed ... tion9.html). Я и слыхом не слыхивал про родовые типы в Java когда знакомился с языком в 2003 году. Поэтому конструкции типа "AdapterView<?> parent" вызывали недоумение.

Re: Урок 44. События в ListView

Добавлено: 04 ноя 2012, 20:24
arthur07
Здравствуйте. Используя код ваших примеров я попытался сделать список, по нажатию на который значения двух переменных передаются в другое активити.
Но после нажатия на item в другом окне значения не принимаются и возвращается null. Подскажите, пожалуйста, в чем дело
Вот первое активити

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

  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    lvMain = (ListView) findViewById(R.id.lvMain);
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
        this, R.array.names,
        android.R.layout.simple_list_item_1);
    lvMain.setAdapter(adapter);    
    lvMain.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
          Log.d(LOG_TAG, "itemClick: position = " + position + ", id = " + id);
        
          Intent intent = new Intent(MainActivity.this, ViewActivity.class);
          intent.putExtra("position", position);
          intent.putExtra("id", id);
          startActivity(intent);
   
        }
      });

  }
код второго активити

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

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.view);
    
    tvView = (TextView) findViewById(R.id.tvView);
    
    Intent intent = getIntent();
    
    String fName = intent.getStringExtra("position");
    String lName = intent.getStringExtra("id");
    
    tvView.setText("Your name is: " + fName + " " + lName);
  }

Re: Урок 44. События в ListView

Добавлено: 04 ноя 2012, 21:23
rezak90
потому что кладёте int, a извлекаете String

Re: Урок 44. События в ListView

Добавлено: 04 ноя 2012, 21:41
arthur07
спасибо) исправил вот так)

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

intent.putExtra("position", Integer.toString(position));
intent.putExtra("id", Long.toString(id));
теперь передается)

Re: Урок 44. События в ListView

Добавлено: 21 ноя 2012, 01:59
xottabut
Скажите пожалуйста, зачем в донном уроке TextView ?

Re: Урок 44. События в ListView

Добавлено: 21 ноя 2012, 09:35
damager82
xottabut писал(а):Скажите пожалуйста, зачем в донном уроке TextView ?
Хороший вопрос! По ходу ошибка копипаста ... Пофиксю, спасибо!

Re: Урок 44. События в ListView

Добавлено: 03 фев 2013, 18:21
dcbp
Друзья! Столкнулся с неожиданной трудностью.
Пишу код:

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

@Override
    public void onResume() {

    	setContentView(R.layout.main);
		

		filesList = (ListView) findViewById(R.id.filesList);
			
		filesList.setOnItemClickListener(new OnItemClickListener() {
		      public void onItemClick(AdapterView<?> parent, View view,
		              int position, long id) {
		            Log.d("myLogs", "itemClick: position = " + position + ", id = "
		                + id);
		          }
		        });
		
           String[] from = { "filename", "creationDate" , "id" };
           int[] to = { R.id.tvFileName, R.id.tvDate , R.id.bDelete };
		
		
	    files = new ArrayList<Map<String, Object>>();
	    adapter = new SimpleAdapter(Main.this, files, R.layout.files_item2, from, to);
	    
	    	mfiles = new HashMap<String, Object>();
	    	mfiles.put("filename", "dvsds");
	    	mfiles.put("creationDate", "svdvsdv");
	    	mfiles.put("id", 1);
	    	mfiles.put("file_id", 2);
		files.add(mfiles);
	    
	    filesList.setAdapter(adapter);
	    
		
    	super.onResume();
    }
а он не работает(
Просто никак не реагирует на клик по элементу списка. Порядок строк менял по разному. Что я упускаю?

На всякий случай вот вью элемента

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

<?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="wrap_content"
    android:layout_marginBottom="5dp"
    android:layout_marginTop="5dp"
    android:background="#ff6600"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/tvDate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:layout_marginBottom="10dp"
        android:layout_marginRight="5dp"
        android:text="date"
        android:textColor="#000" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1" >

        <TextView
            android:id="@+id/tvFileName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="20dp"
            android:layout_marginLeft="10dp"
            android:layout_weight="1"
            android:text="FileName"
            android:textColor="#000"
            android:textSize="18sp" />

        <Button
            android:id="@+id/bDelete"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="10dp"
            android:text="X" />

    </LinearLayout>

</LinearLayout>

Re: Урок 44. События в ListView

Добавлено: 03 фев 2013, 19:27
dens
Может, попробовать родительский метод вызывать ДО своего кода?

Re: Урок 44. События в ListView

Добавлено: 03 фев 2013, 20:18
dcbp
Не помогает.