Урок 54. Кастомизация списка. Создаем свой адаптер
Re: Урок 54. Кастомизация списка. Создаем свой адаптер
Ок, обьясню что этот параметр (android:descendantFocusability="blocksDescendants") делает.
1) Если его нет то onItemClick() вообще не вызовется если на item есть кнопки!
2) Если он есть то onItemClick() будет вызываться при клике на пустом месте в item (или элементах у которых clicable=false) , при клике не кнопку onItemClick() не вызовется
1) Если его нет то onItemClick() вообще не вызовется если на item есть кнопки!
2) Если он есть то onItemClick() будет вызываться при клике на пустом месте в item (или элементах у которых clicable=false) , при клике не кнопку onItemClick() не вызовется
Личные сообщения с просьбой ответить на форуме или написать программу я просто удаляю, если я в хорошем настроении. Если в плохом добавляю автора в черный список. По любым другим вопросам feel free to write to me.
Re: Урок 54. Кастомизация списка. Создаем свой адаптер
Или мы по разному это понимаем или у нас разный android, но конкретно результатом работы android:descendantFocusability="blocksDescendants" становться то, что всем элементам внутри этого layout содержащим в себе focusable или clickable, кнопка это или нет не важно, эти события запрещаются и они становятся простыми list items нажатие на которые и обрабатывает OnItemClickListener... как бы я так это понимаю и у меня именно в таком виде все работает... вопрос у нас разные android ? Ну как бы да добавляя blocksDescendants, у кнопки focusable должен быть true и тогда проблем у системы отличить клик на пустой области или кнопке отличить не будет. Просто у меня все варрианты работают, я же говорю может я где то не там sdk скачал, но списки я разные делал и ну не было проблем... вообще не былоanber писал(а):Ок, обьясню что этот параметр (android:descendantFocusability="blocksDescendants") делает.
1) Если его нет то onItemClick() вообще не вызовется если на item есть кнопки!
2) Если он есть то onItemClick() будет вызываться при клике на пустом месте в item (или элементах у которых clicable=false) , при клике не кнопку onItemClick() не вызовется
Опять таки пошел искать и в точности: http://stackoverflow.com/a/14372750/2611075
Но ок, пойдем другим путем... чем код показанный выше( собственная обработка клика отличается от этого: https://github.com/android/platform_pac ... .java#L381 ??? ), вопрос - почему кто то решил что работать он будет по другому???
Последний раз редактировалось altwin 17 июл 2014, 14:02, всего редактировалось 1 раз.
Re: Урок 54. Кастомизация списка. Создаем свой адаптер
Андроид у меня 4.4.4.
Определимся:
1) у корневого елемента item установлено android:descendantFocusability="blocksDescendants"
2) на нем есть кнопка описанная так:
3) у listview установлено:
4) у кнопки нет никаких обработчиков
У меня происходит следующее:
1) при клике на пустое место item он весь выделяется и срабатывает обработчик onItemClick
2) при клике на кнопку внутри item происходит анимация нажатия на кнопку, item НЕ выделяется, обработчик onItemClick НЕ срабатывает.
>>>Опять таки пошел искать и в точности: http://stackoverflow.com/a/14372750/2611075
это дословно повторяет ой предыдущий пост, разве нет?
Определимся:
1) у корневого елемента item установлено android:descendantFocusability="blocksDescendants"
2) на нем есть кнопка описанная так:
Код: Выделить всё
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button1"
/>
Код: Выделить всё
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// обрабочик onItemClick
}
});
У меня происходит следующее:
1) при клике на пустое место item он весь выделяется и срабатывает обработчик onItemClick
2) при клике на кнопку внутри item происходит анимация нажатия на кнопку, item НЕ выделяется, обработчик onItemClick НЕ срабатывает.
>>>Опять таки пошел искать и в точности: http://stackoverflow.com/a/14372750/2611075
это дословно повторяет ой предыдущий пост, разве нет?
Ок, обьясню что этот параметр (android:descendantFocusability="blocksDescendants") делает.
1) Если его нет то onItemClick() вообще не вызовется если на item есть кнопки!
2) Если он есть то onItemClick() будет вызываться при клике на пустом месте в item (или элементах у которых clicable=false) , при клике не кнопку onItemClick() не вызовется
Личные сообщения с просьбой ответить на форуме или написать программу я просто удаляю, если я в хорошем настроении. Если в плохом добавляю автора в черный список. По любым другим вопросам feel free to write to me.
Re: Урок 54. Кастомизация списка. Создаем свой адаптер
Пуcтое меcто - элемент списка такой же, как и другие, но не имеющий id по умолчанию, соответсвенно button элемент с id, которому не привязанно событие, switсh по id элементов списка?anber писал(а): У меня происходит следующее:
1) при клике на пустое место item он весь выделяется и срабатывает обработчик onItemClick
2) при клике на кнопку внутри item происходит анимация нажатия на кнопку, item НЕ выделяется, обработчик onItemClick НЕ срабатывает.
Re: Урок 54. Кастомизация списка. Создаем свой адаптер
что это вообще и при чем оно тут?altwin писал(а):Но ок, пойдем другим путем... чем код показанный выше( собственная обработка клика отличается от этого: https://github.com/android/platform_pac ... .java#L381 ??? ), вопрос - почему кто то решил что работать он будет по другому???
не понял мысльaltwin писал(а):Пуcтое меcто - элемент списка такой же, как и другие, но не имеющий id по умолчанию, соответсвенно button элемент с id, которому не привязанно событие, switсh по id элементов списка?
Личные сообщения с просьбой ответить на форуме или написать программу я просто удаляю, если я в хорошем настроении. Если в плохом добавляю автора в черный список. По любым другим вопросам feel free to write to me.
- KamiSempai
- Сообщения: 1339
- Зарегистрирован: 17 фев 2012, 21:23
- Откуда: Мордор
Re: Урок 54. Кастомизация списка. Создаем свой адаптер
Коллеги, кажется мы опять уходим от темы в бездну недопонимания.
Мне понравилась идея с вызовом метода performItemClick. Думаю, перепишу свой адаптер под него. Таким образом OnContextButtonClickListener будет совершенно не нужен.
Мне понравилась идея с вызовом метода performItemClick. Думаю, перепишу свой адаптер под него. Таким образом OnContextButtonClickListener будет совершенно не нужен.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.
Хватит таскать макулатуру на тренировку! Используй T Note.
Re: Урок 54. Кастомизация списка. Создаем свой адаптер
я не много уже сам в сути запутался, сейчас вот пытаюсь найти у себя где я использовал такой способ, к сожалению в основном поголовно android:onClick в ImageButton, но я найду и покажу...
Re: Урок 54. Кастомизация списка. Создаем свой адаптер
выложишь что получится, охота глянутьKamiSempai писал(а):Коллеги, кажется мы опять уходим от темы в бездну недопонимания.
Мне понравилась идея с вызовом метода performItemClick. Думаю, перепишу свой адаптер под него. Таким образом OnContextButtonClickListener будет совершенно не нужен.
Личные сообщения с просьбой ответить на форуме или написать программу я просто удаляю, если я в хорошем настроении. Если в плохом добавляю автора в черный список. По любым другим вопросам feel free to write to me.
Re: Урок 54. Кастомизация списка. Создаем свой адаптер
Получается я всех и себя обманул... у меня нет кнопок в listview вообще... есть только imageView....anber писал(а):выложишь что получится, охота глянутьKamiSempai писал(а):Коллеги, кажется мы опять уходим от темы в бездну недопонимания.
Мне понравилась идея с вызовом метода performItemClick. Думаю, перепишу свой адаптер под него. Таким образом OnContextButtonClickListener будет совершенно не нужен.
- KamiSempai
- Сообщения: 1339
- Зарегистрирован: 17 фев 2012, 21:23
- Откуда: Мордор
Re: Урок 54. Кастомизация списка. Создаем свой адаптер
Выкладываю...anber писал(а):выложишь что получится, охота глянуть
[syntax=java]public abstract class ContextualCursorAdapter<Holder> extends CursorAdapter {
private LayoutInflater mInflater;
private int mLayoutId;
private int[] mContextualButtons;
protected int mColumnIndexId;
public ContextualCursorAdapter(Context context, Cursor cursor, int layout,
int[] contextualButtons, int flags) {
super(context, cursor, flags);
mInflater = LayoutInflater.from(context);
mLayoutId = layout;
mContextualButtons = contextualButtons;
onCursorChanged(cursor);
}
abstract Holder newHolder(View view);
abstract void bindHolder(Holder holder, Cursor cursor);
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = mInflater.inflate(mLayoutId, parent, false);
ContextHolder<Holder> contextHolder = new ContextHolder<Holder>();
contextHolder.viewHolder = newHolder(view);
if (parent instanceof AdapterView<?>)
contextHolder.list = (AdapterView<?>) parent;
view.setTag(contextHolder);
if (mContextualButtons != null)
for (int id : mContextualButtons) {
View contextualButton = view.findViewById(id);
if (contextualButton != null) {
contextualButton
.setOnClickListener(mContextButtonClickListener);
contextualButton.setTag(contextHolder);
contextualButton.setSoundEffectsEnabled(false);
contextualButton.setFocusable(false);
}
}
return view;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
@SuppressWarnings("unchecked")
ContextHolder<Holder> contextHolder = (ContextHolder<Holder>) view
.getTag();
contextHolder.position = cursor.getPosition();
contextHolder.id = cursor.getLong(mColumnIndexId);
bindHolder(contextHolder.viewHolder, cursor);
}
@Override
public Cursor swapCursor(Cursor cursor) {
Cursor res = super.swapCursor(cursor);
onCursorChanged(cursor);
return res;
}
protected void onCursorChanged(Cursor newCursor) {
if(newCursor != null)
mColumnIndexId = newCursor.getColumnIndex(BaseColumns._ID);
}
protected void handleContextButtonClick(AdapterView<?> list, View view,
int position, long id) {
list.performItemClick(view, position, id);
}
private OnClickListener mContextButtonClickListener = new OnClickListener() {
@Override
public void onClick(View view) {
@SuppressWarnings("unchecked")
ContextHolder<Holder> contextHolder = (ContextHolder<Holder>) view
.getTag();
if (contextHolder != null && contextHolder.list != null)
handleContextButtonClick(contextHolder.list, view,
contextHolder.position, contextHolder.id);
}
};
private static class ContextHolder<T> {
int position;
long id;
AdapterView<?> list;
T viewHolder;
}
}[/syntax]
Перенес создание ContextHolder в newView так как доступ к parent-у только там есть. А еще отключил звук нажатия на кнопке, так как ListView этот звук воспроизведет после performItemClick (contextualButton.setSoundEffectsEnabled(false)). Плюс, переименовал класс на ContextualCursorAdapter, так вроде более правильно.
По сути ничего не поменялось, только теперь не нужно листенер ставить, будет вызываться onListItemClick. Как то так(Пример из ListFragment):[syntax=java] public void onListItemClick(ListView listView, View view, int position, final long id) {
if(view.getId() == View.NO_ID) {
// нажатие по строке
}
else {
// Нажатие по контекстной кнопке
}
}[/syntax]
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.
Хватит таскать макулатуру на тренировку! Используй T Note.
Re: Урок 54. Кастомизация списка. Создаем свой адаптер
Добрый день! Я использ. ListFragment и простой TimeAdapter. У меня все получилось, но единственное проблемы что список вообще не отображается. У меня нет никаких ошибок Logcat. Не могу найти, в чем проблемы. Может, я что то не правильно написала.
dayfragment.xml
text_fragment.xml
TimeAdapter.java
DayFragment.java
dayfragment.xml
Код: Выделить всё
<?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="match_parent"
android:orientation="vertical" >
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
Код: Выделить всё
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:gravity="center"
android:background="#5ba4e5"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="40px"
android:textColor="#040404"
android:layout_gravity="center"
android:id="@+id/time"/>
</LinearLayout>
Код: Выделить всё
public class TimeAdapter extends BaseAdapter {
Context context;
List<TimeRowItem> rowItem;
TimeAdapter(Context context, List<TimeRowItem> rowItem) {
this.context = context;
this.rowItem = rowItem; }
@Override
public int getCount() {
return rowItem.size();}
@Override
public Object getItem(int position) {
return rowItem.get(position); }
@Override
public long getItemId(int position) {
return rowItem.indexOf(getItem(position)); }
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.list_item, parent, false);}
TextView txtTitle = (TextView) convertView.findViewById(R.id.time);
TimeRowItem row_pos = rowItem.get(position);
txtTitle.setText(row_pos.getTitle());
return convertView; }
}
DayFragment.java
Код: Выделить всё
public class DayFragment extends ListFragment {
String[] menutitles;
TimeAdapter adapter;
private List<TimeRowItem> rowItems;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.dayfragment, container, false); }
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
menutitles = getResources().getStringArray(R.array.titles);
rowItems = new ArrayList<TimeRowItem>();
for (int i = 0; i < menutitles.length; i++) {
TimeRowItem items = new TimeRowItem(menutitles[i]);
rowItems.add(items);}
setListAdapter(adapter);}
}
Re: Урок 54. Кастомизация списка. Создаем свой адаптер
Persik писал(а):Добрый день! Я использ. ListFragment и простой TimeAdapter. У меня все получилось, но единственное проблемы что список вообще не отображается. У меня нет никаких ошибок Logcat. Не могу найти, в чем проблемы. Может, я что то не правильно написала.
DayFragment.javaКод: Выделить всё
public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); menutitles = getResources().getStringArray(R.array.titles); rowItems = new ArrayList<TimeRowItem>(); for (int i = 0; i < menutitles.length; i++) { TimeRowItem items = new TimeRowItem(menutitles[i]); rowItems.add(items);} setListAdapter(adapter);}
TimeAdapter не инициализируется, во время присвоения он у вас null.
Re: Урок 54. Кастомизация списка. Создаем свой адаптер
Может кто-то написать или кинуть ссылку на пример реализации самого простого BaseAdapter'a?
Re: Урок 54. Кастомизация списка. Создаем свой адаптер
R.id.team
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
Re: Урок 54. Кастомизация списка. Создаем свой адаптер
Распишите плиз про метод getView в Base Adapter
Feonix, спасибо
Feonix, спасибо
Re: Урок 54. Кастомизация списка. Создаем свой адаптер
У меня похожая ситуация была. И установка android:focusable="false" не помогала. У меня в кастомном адаптере был обработчик OnClickListener для LinearLayout, и по клику на нем срабатывал этот обработчик, а не обработчик для списка setOnItemClickListener. Теперь я обработчик OnClickListener для LinearLayout убрал (изобретенный велосипед ), а установку android:focusable="false" оставил. Теперь работает, как надо!Artem писал(а):Разобрался, нужно установитьArtem писал(а): ...Подскажите, как реализовать в таком списке с кастомным адаптером обработку нажатия на элемент списка. Простая установка обработчика для списка через setOnItemClickListener к результату не приводит...для чекбокса.Код: Выделить всё
android:focusable="false"
Каждая незаконченная задача - это минус. Но каждый зачеркнутый минус - это плюс.
Re: Урок 54. Кастомизация списка. Создаем свой адаптер
Здравствуйте!
Делаю кастомный список -если упростить, то в каждом элементе списка(строке) есть textview и button при нажатии на которую должен вызываться time-диалог.
После выбора времени textview должно изменяться на на это выбранное время.
Все бы ничего, но изменяется textview в ДРУГОЙ строке.
пробовал решить используя setTag и getTag, но не получилось, мб что-то делал не так и не правильно использовал эти замечательные функции.
подскажите пожалуйста в каком направлении копать, может получше изучить setTag и getTag(т.к. на первый взгляд это самое простое и верное решение)
Делаю кастомный список -если упростить, то в каждом элементе списка(строке) есть textview и button при нажатии на которую должен вызываться time-диалог.
После выбора времени textview должно изменяться на на это выбранное время.
Все бы ничего, но изменяется textview в ДРУГОЙ строке.
пробовал решить используя setTag и getTag, но не получилось, мб что-то делал не так и не правильно использовал эти замечательные функции.
подскажите пожалуйста в каком направлении копать, может получше изучить setTag и getTag(т.к. на первый взгляд это самое простое и верное решение)
Re: Урок 54. Кастомизация списка. Создаем свой адаптер
Какие еще тэги? Менять нужно данные, которые в листвью отображаются. А потом обновлять список.
R.id.team
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
Re: Урок 54. Кастомизация списка. Создаем свой адаптер
Извините, не понял как обратиться именно к нужному мне textview. Думал, что автоматически кнопка в n-ой строке изменяет textview в n-ой строке. А выходит полностью рандомно.Foenix писал(а):Какие еще тэги? Менять нужно данные, которые в листвью отображаются. А потом обновлять список.
посмотрите пожалуйста мой код, делал по аналогии с примером урока, только мне не понадобился дополнительный класс начальных значений, все строки изначально одинаковы
строка - это textview и button, которая изменяет textview
Код: Выделить всё
package com.example.wi_fitimerlistview;
import java.util.ArrayList;
import java.util.Calendar;
import android.app.TimePickerDialog;
import android.app.TimePickerDialog.OnTimeSetListener;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;
import android.widget.TimePicker;
public class BoxAdater extends BaseAdapter {
private TimePickerDialog mTimePickerDialogOn, mTimePickerDialogOff;
Context ctx;
LayoutInflater lInflater;
ArrayList<Period> objects;
TextView t_start_time, t_end_time;
public BoxAdater(Context context, ArrayList<Period> period) {
ctx = context;
objects = period;
lInflater = (LayoutInflater) ctx
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return objects.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return objects.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View view = convertView;
if (view == null) {
view = lInflater.inflate(R.layout.item, parent, false);
}
t_start_time = (TextView) view.findViewById(R.id.textview_start_time);
initTimePickerDialogOn();
Button b_change_start_time = (Button) view
.findViewById(R.id.button_change_start_time);
b_change_start_time.setTag(position);
b_change_start_time.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.d("MY_TAG", v.getTag().toString());
mTimePickerDialogOn.show();
}
});
return view;
}
Period getPeriod(int position) {
return ((Period) getItem(position));
}
private void initTimePickerDialogOn() {
Calendar c = Calendar.getInstance();
int hour = c.get(Calendar.HOUR);
int min = c.get(Calendar.MINUTE);
mTimePickerDialogOn = new TimePickerDialog(ctx,
new OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay,
int minute) {
// SampleService.HOUR_WORK = hourOfDay;
// SampleService.MIN_WORK = minute;
t_start_time.setText(hourOfDay + "------" + minute);
}
}, hour, min, true);
mTimePickerDialogOn.setTitle("Начало");
}
}
Re: Урок 54. Кастомизация списка. Создаем свой адаптер
Обязательно нужен начальный массив значений, пусть даже заполненеый одинак. Значениями. Его и надо потом менять.
R.id.team
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198