Форум программистов, компьютерный форум, киберфорум
Наши страницы

Программирование Android

Войти
Регистрация
Восстановить пароль
 
Sleep37
4 / 4 / 1
Регистрация: 06.01.2013
Сообщений: 16
#1

Не понятное поведение BaseAdapter - Программирование Android

12.08.2014, 11:51. Просмотров 788. Ответов 7
Метки нет (Все метки)

Добрый день!
Проблема в следующем: есть ListView, есть адаптер унаследованный от BaseAdapter.
В адаптере в методе getView загружаю лайоут, на лайоуте два элемента TextView и Button.
На кнопку вешаю обработчик onClick, при вызове которого в TextView, (который рядом с кнопкой) пишу текст, например: - ok. Проблема в том, что это срабатывает не только для одного TextView во всем ListView, а для каждого TextView который находится на новом экране.
Т.е например во всем ListView 10, на экране отображается по 5 элементов, получается 2 экрана, при клике на самую первую кнопку, TextView изменится в 0 позиции ( т.е самый первый ) и в 6 ( т.к 6 позиция расположена на другом экране)

код адаптера:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public class MYAdapter extends BaseAdapter{
 
    private List<String> items;
    private LayoutInflater layoutInflater;
    public MYAdapter(Context context, List<String> items) {
        this.items = items;
        this.layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }
 
    @Override
    public int getCount() {
        return items.size();
    }
 
    @Override
    public String getItem(int position) {
        return items.get(position);
    }
 
    @Override
    public long getItemId(int position) {
        return position;
    }
 
    @Override
    public View getView(final int position, View convertView, final ViewGroup parent) {
        ViewHolder viewHolder;
        if(convertView == null){
            convertView = layoutInflater.inflate(R.layout.item, null);
            viewHolder = new ViewHolder();
            viewHolder.button = (Button) convertView.findViewById(R.id.button);
            convertView.setTag(viewHolder);
        }else{
            viewHolder = (ViewHolder) convertView.getTag();
        }
        viewHolder.button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                View rootView = (View) v.getParent();
                TextView txt = (TextView) rootView.findViewById(R.id.text);
                txt.setText("OK");
            }
        });
        return convertView;
    }
    static class ViewHolder{
        Button button;
    }
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.08.2014, 11:51
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Не понятное поведение BaseAdapter (Программирование Android):

BaseAdapter - Программирование Android
Есть контейнер для фрагментов (container), есть фрагмент (fragment), есть BaseAdapter и Product Я хочу сделать адаптер из списка в...

BaseAdapter - Программирование Android
Доброго времени суток Есть класс адаптера скопированный с http://idev.by/android/311/ Код: package ru.myscanner.scannerth; ...

Не вижу абстрактных методов в классе BaseAdapter - Программирование Android
Когда создаю свой класс, наследующий BaseAdapter, требуется реализовать 4 абстрактных метода: getCount(), getItem(), getItemId, getView....

Изменение данных через BaseAdapter в Activity - Программирование Android
Добрый день, у меня возникла следующая проблема. У меня имеется стандартное активити с listview и в этом же активити сверху имеется text...

Как вывести в BaseAdapter картинки, занесенные в таблицу? - Программирование Android
Всем привет! Подскажите пожалуйста, как вывести в BaseAdapter картинки которые я занес в таблицу @Override public View...

При клики в BaseAdapter меняется массив строк, как пересоздать ListView с новым массивом? - Программирование Android
Здравствуйте! Имеется класс: package ru.contedevel.mathworker; import java.util.ArrayList; import...

7
YuraAAA
1577 / 1318 / 271
Регистрация: 25.10.2009
Сообщений: 3,438
Записей в блоге: 2
12.08.2014, 15:17 #2
Цитата Сообщение от Sleep37 Посмотреть сообщение
@Override public void onClick(View v) { View rootView = (View) v.getParent(); TextView txt = (TextView) rootView.findViewById(R.id.text); txt.setText("OK"); }
на

Java
1
2
3
4
 @Override
            public void onClick(View v) {
TextView.class.cast(v).setText("OK");
}
v это всегда будет нужная TextView
0
Sleep37
4 / 4 / 1
Регистрация: 06.01.2013
Сообщений: 16
12.08.2014, 15:50  [ТС] #3
не помогло (
0
NiRamz
211 / 211 / 16
Регистрация: 26.12.2010
Сообщений: 691
12.08.2014, 18:22 #4
Создаем
Java
1
2
3
4
5
6
7
8
9
10
11
12
   private class MyListener implements View.OnClickListener {
 
        private ViewHolder viewHolder;
        public MyListener(ViewHolder vh) {
            viewHolder = vh;
        }
 
        @Override
        public void onClick(View v) {
            vh.textView.setText("ok");
        }
    }
и вешаем его

Java
1
viewHolder.button.setOnClickListener(new MyListener(viewHolder));
0
Sleep37
4 / 4 / 1
Регистрация: 06.01.2013
Сообщений: 16
14.08.2014, 00:11  [ТС] #5
NiRamz, работает, но при скрытии элемента всё сбивается. Т.е я нажал на вторую кнопку, после пролистал вниз. пролистал вверх и всё сбилось.(стал отображаться ни текст который был установлен в onClik'e)
а текст который был задан в android:text="New Text"
0
646kapeh064
59 / 58 / 15
Регистрация: 09.12.2013
Сообщений: 208
14.08.2014, 00:16 #6
Sleep37, потому-что элементы списка пересоздаются (невидимые элементы удаляются, чтоб не загружать память мусором).
Храни например в своём ViewHolder введенный текст в текстовое поле.
0
NiRamz
211 / 211 / 16
Регистрация: 26.12.2010
Сообщений: 691
14.08.2014, 11:10 #7
Цитата Сообщение от 646kapeh064 Посмотреть сообщение
Sleep37, потому-что элементы списка пересоздаются (невидимые элементы удаляются, чтоб не загружать память мусором).
Храни например в своём ViewHolder введенный текст в текстовое поле.
Не пересоздаются, если правильно создан адаптер, а подтягиваются из кэша вьюх.
Что бы запомнить, на какой позиции был введен текст, создаем небольшой кэш в адаптере, куда пихаем позиции элементов и в getView проверяем его, если там есть такая позиция, назначаем полю нужный текст
0
kvaka
31 / 31 / 3
Регистрация: 26.06.2012
Сообщений: 166
03.02.2015, 23:19 #8
Там система такая. Вообще для отображения элементов вьюх, являющимися позициями списка используется ограниченное число элементов. Т.е., допустим, одновременно на экране может отображаться не более 3х позиций. Для полного функционирования Андроид создает 4 вьюхи (в общем случае, может и больше) - те, которые сейчас на экране и та, которая будет использована для вьюхи, которая появится на экране при скролле. Вьюха, ушедшая за пределы отображаемой области попадает в специальный объект, называемый Recycler, который и использует его для создания нового элемента списка. Поэтому в getView мы и делаем проверку на cjnvertView == null. Т.е. если он null - то у нас нету объекта в ресайклере, который может быть использован для создания позиции списка, соответственно и наполнение у него будет такое, какое при создании инфлейтером из лейаута. В твоем же случае - ты внес в элемен изменение - изменил текст, в этом виде вьюха уехала за экран, далее при создании новой позиции используется та же вьюха. Наполнение текста в getView ты здесь не контролируешь, поэтому он остается таким, каким он уезжал за экран. Таким образом - выводимый на текстВью позиции списка у тебя должен каждый раз доставаться в getView независимо от того создаешь ты вьюху заново или переиспользуешь. Соответственно информацию о нажатых вьюхах ты должен где-то сохранять

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
public class MYAdapter extends BaseAdapter{
 
    private HashSet<Integer> pressedPositions; // здесь будешь хранить номера нажатых позиций
 
    private List<String> items;
    private LayoutInflater layoutInflater;
    public MYAdapter(Context context, List<String> items) {
        this.items = items;
        this.layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 
        pressedPositions = new HashSet();
    }
 
    @Override
    public int getCount() {
        return items.size();
    }
 
    @Override
    public String getItem(int position) {
        return items.get(position);
    }
 
    @Override
    public long getItemId(int position) {
        return position;
    }
 
    @Override
    public View getView(final int position, View convertView, final ViewGroup parent) {
        ViewHolder viewHolder;
        if(convertView == null){
            convertView = layoutInflater.inflate(R.layout.item, null);
            viewHolder = new ViewHolder();
            viewHolder.button = (Button) convertView.findViewById(R.id.button);
            viewHolder.textView = (TextView) convertView.findViewById(R.id.text);
            convertView.setTag(viewHolder);
 
            // лисенер достаточно определить один раз для каждого холдера - при его создании
            viewHolder.button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {               
               View rootView = (View) v.getParent();
                TextView txt = (TextView) rootView.findViewById(R.id.text);
                txt.setText("OK");
               pressedPositions.put(position);
            }
        });
 
 
        }else{
            viewHolder = (ViewHolder) convertView.getTag();
            // проверяем нажата ли позиция
            if (!pressedPositions.contains(position)){
                // если не нажата - ставим нужный текст - не знаю какой, но пусть будет так для примера:
                viewHolder.textView.setText(items.get(position));
            }    
        }
        
        return convertView;
    }
    static class ViewHolder{
        Button button;
        TextView textView;
    }
}
В работе не пробовал, но думаю суть понятна.
1
03.02.2015, 23:19
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.02.2015, 23:19
Привет! Вот еще темы с ответами:

Не понятное поведение DBLookupComboBox - C++ Builder БД
Здравствуйте, при написании проекта возникла необходимость изменять параметр DBLookupComboBox-&gt;KeyValue с другой формы. Это происходит так...

Curl не понятное поведение - PHP Сети
Пытаюсь определить город по ip таким образом $link = 'http://ipgeobase.ru:7020/geo?ip='.$_SERVER; $ch = curl_init(); curl_setopt($ch,...

Не понятное поведение диалогового окна из UI - jQuery
Всем привет. Есть проблема, не корректно отображается окно JQuery UI. На локальном сервере все хорошо работает, а на хостинге ведет себя не...

jQuery.post не понятное поведение - jQuery
Всем привет! с jQuery.post работаю впервые, возможно что то не до понимаю вообще так ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.