Форум программистов, компьютерный форум, киберфорум
Наши страницы
Программирование Android
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 5.00/10: Рейтинг темы: голосов - 10, средняя оценка - 5.00
Hedd
13 / 13 / 2
Регистрация: 21.01.2015
Сообщений: 131
1

GridView. Изменение бекграунда по нажатию

28.01.2015, 02:28. Просмотров 1782. Ответов 28
Метки нет (Все метки)

Есть элемент GridView, который я вызываю через Spinner.
По нажатию на один из элементов GridView, его background должен меняться на другой цвет и приложение вызывает ListView с данными из базы данных. Все действия происходят в одной Activity. Верхняя половина окна - Spinner+ GridView. Нижняя половина - ListView. БД формируется через отдельный класс.
Вызов данных работает отлично, список формируется, но цвет background у нажатого элемента GridView не меняется.
Операция по смене background прописана верно. Проверял в других приложениях. Что примечательно, цвет background меняется, если закоментировать строку с формированием списка ListView из бд.

В чем может быть проблема?

Так я ставлю бекграунд грида:
Java
1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/background_selected" android:state_pressed="true"/>
    <item android:drawable="@color/background_selected" android:state_selected="true"/>
    <item android:drawable="@color/background_default" />
</selector>
Java
1
2
3
4
5
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="background_selected">#ffffff</color>
    <color name="background_default">#ffbe3f38</color>
</resources>
Java
1
2
3
4
5
 <GridView
        android:listSelector="@color/bg_days" 
        ....
        ....>
        </GridView>
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.01.2015, 02:28
Ответы с готовыми решениями:

Textview. Изменение текста по нажатию кнопки не происходит
Добрый день. Подскажите как же реализовывается подобное : в методе onCreat...

Смена бекграунда на андроиде
Всем доброго времени суток. У меня появилась небольшая проблема. Опишу ее...

Смена бекграунда на андроиде
Всем доброго времени суток. У меня появилась небольшая проблема. Опишу ее...

Заполнение GridView по нажатию кнопки
Кстати, а подскажите салаге зелёнейшему: чтоб в эту таблицу вводить данные...

SQL Выборка из 2-х таблиц по нажатию кнопки и отображению в GridView
Всем здравствуйте! Подскажите пожалуйста как сделать выборку из 2х таблиц...

28
Armagedo
210 / 210 / 60
Регистрация: 22.08.2014
Сообщений: 644
28.01.2015, 10:26 2
Можно предположить, что в момент, когда появляется ListView, то фокус уже не у GridView, который теперь и не pressed, и не selected.
0
Hedd
13 / 13 / 2
Регистрация: 21.01.2015
Сообщений: 131
28.01.2015, 10:29  [ТС] 3
Armagedo, Есть идеи как это можно исправить?
Я думал, что конфликт из-за обращения к БД, но нет. Создал отдельное приложение с GridView и ListView. Заполнил ListView по нажатию по GridView обычным массивом String[], который задал в активити. Проблема осталась. фон не отмечается.
0
Armagedo
210 / 210 / 60
Регистрация: 22.08.2014
Сообщений: 644
28.01.2015, 10:59 4
Программно, переписав метод getView() адаптера.
Вешать AdapterView.OnItemClickListener, отлавливать onClick(), получать позицию элемента грида и обновлять грид.

Добавлено через 15 минут
Идея начинается со слов "в лоб" тут Выбираются все пункты в RadioButton
0
Hedd
13 / 13 / 2
Регистрация: 21.01.2015
Сообщений: 131
28.01.2015, 12:33  [ТС] 5
Armagedo, что то я немного запутался..
Идею с глобальной переменной вроде понял, но никак не могу додумать как реализовать 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
public class MainActivity extends ActionBarActivity {
    
    //массив для ListView
    String[] lvArray = {"1", "2", "3", "4", "5"};
    //массив для GridView
    String[] gvArray = {"1", "2", "3", "4", "5"};
 
    int checkedItemPosition = -1;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
      
      //GridView адаптер
      final  GridView gv = (GridView) findViewById(R.id.gridView1);
        final ArrayAdapter<String> gvadapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, gvArray);
        gv.setAdapter(gvadapter);
        
      //нажатие на элемент GridView
        gv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
 
                if (checkedItemPosition != position)
                    checkedItemPosition = position;
                else checkedItemPosition = -1;
 
                gvadapter.notifyDataSetChanged();
 
                showListView();
            }
        });
 
    }
    
    //вызов ListView
    private void showListView() {
 
        final  ListView lv = (ListView) findViewById(R.id.lvMain);
        final ArrayAdapter<String> lvadapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, lvArray);
        lv.setAdapter(lvadapter);
    }
0
Armagedo
210 / 210 / 60
Регистрация: 22.08.2014
Сообщений: 644
28.01.2015, 12:49 6
Лучший ответ Сообщение было отмечено Hedd как решение

Решение

Java
1
2
3
4
5
6
7
8
9
10
11
12
final ArrayAdapter<String> gvadapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, gvArray){
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
         
      View view = super.getView(position, convertView, parent);
 
        if (position==checkedItemPosition)
                                 view.setBackgroundColor(Color.YELLOW);
       
     return view;
};
Добавлено через 6 минут
Не, всё же метод супер-класса лучше отработать...
1
Hedd
13 / 13 / 2
Регистрация: 21.01.2015
Сообщений: 131
28.01.2015, 13:07  [ТС] 7
Armagedo, Спасибо, разобрался! Все получилось. Так же добавил else, чтобы фон предыдущего нажатого элемента убирался, а не оставался.
0
Armagedo
210 / 210 / 60
Регистрация: 22.08.2014
Сообщений: 644
28.01.2015, 13:12 8
Hedd, на здоровье
0
Hedd
13 / 13 / 2
Регистрация: 21.01.2015
Сообщений: 131
28.01.2015, 13:13  [ТС] 9
Armagedo, Кстати, я могу в этом getView() каким то образом так же задать изменение цвета текста по выделению?
0
Armagedo
210 / 210 / 60
Регистрация: 22.08.2014
Сообщений: 644
28.01.2015, 13:25 10
Дык, а че б и нет.

android.R.layout.simple_list_item_1 в себе содержит (два) TextView, для которых доступен метод setTextColor
0
Hedd
13 / 13 / 2
Регистрация: 21.01.2015
Сообщений: 131
28.01.2015, 13:27  [ТС] 11
Цитата Сообщение от Hedd Посмотреть сообщение
Armagedo, Кстати, я могу в этом getView() каким то образом так же задать изменение цвета текста по выделению?
Вроде понял:
Java
1
2
TextView tv1 = (TextView)view.findViewById(android.R.id.text1);
tv1.SetTextColor(...);
Поправьте, если я не прав
0
Armagedo
210 / 210 / 60
Регистрация: 22.08.2014
Сообщений: 644
28.01.2015, 13:29 12
Ну, да.
0
Hedd
13 / 13 / 2
Регистрация: 21.01.2015
Сообщений: 131
28.01.2015, 15:10  [ТС] 13
Armagedo, Теперь столкнулся с другой проблемой, при попытке добавить функционал getView() в свой проект, описанный в первом посте.

Вставил код верно, проект компилируется, приложение запускается, но при нажатии на элемент GridView фон устанавливается только у любого первого нажатого элемента. При нажатии на другой элемент, фон остается на первом нажатом, а на новом нажатом элементе не меняется.
Если в спиннере выбрать другой пункт - GridView обновляется и можно выбрать другой элемент, опять же единожды.

Структура у моего приложения такова:
Spinner, в котором 4 пункта. По нажатию на каждый пункт отображается разный GridView с данными из БД.
GridView - состоит из 5 элементов, по нажатию на каждый пункт, отображается разный ListView с данными из БД.

Вот я и не могу понять почему смена фона срабатывает единожды, пока я не обновлю данные..

Вот код моей Activity:
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
public class MainActivity extends Activity {
    
 //доступ к классу БД
    private ObjectsAdapter oDbHelper;
 
    private SimpleCursorAdapter oDataAdapter;
 
    public static int test;
    public static int test2;
 
    int checkedItemPosition = -1;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
 //Операции с БД при запуске приложения
        oDbHelper = new ObjectsAdapter(this);
        oDbHelper.open();
        oDbHelper.deleteAllObjects();
        oDbHelper.insertObjects();
 
 // Spinner
        ArrayAdapter<?> adapter =
                ArrayAdapter.createFromResource(this, R.array.weeksList, R.layout.spinner_item);
        adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
        Spinner spinner = (Spinner) findViewById(R.id.spinner);
        spinner.setAdapter(adapter);
 
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
 
  //По нажатию на пункт спиннера выбирается соотв. GridView из БД.
  //где test - переменная для класса с БД для выбора данных 
                switch (position+1){
                    case 1: test = 1;  break;
                    case 2: test = 2;  break;
                    case 3: test = 3;  break;
                    case 4: test = 4;  break;
                    default: break;
                }
                
 // отображаем выбранные элементы GridView (описано ниже)
                displayDaysView();
            }
 
            @Override
            public void onNothingSelected(AdapterView<?> parent) {
 
            }
        });
    }
 
    private void displayDaysView() {
        Cursor cursor = oDbHelper.fetchAllDays();
 
        String[] columns = new String[] {
                ObjectsAdapter.KEY_DAY,
                ObjectsAdapter.KEY_DATE
        };
 
        int[] to = new int[] {
                R.id.tvDay,
                R.id.tvDate,
        };
 
 // Адаптер для GridView
        final GridView gvDays = (GridView) findViewById(R.id.gridView1);
        oDataAdapter = new SimpleCursorAdapter(
                this, R.layout.list_days_items, cursor, columns, to, 0){
 
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
 
                View view = super.getView(position, convertView, parent);
 
                TextView tvDay = (TextView) view.findViewById(R.id.tvDay);
                TextView tvDate = (TextView) view.findViewById(R.id.tvDate);
 
                if (position == checkedItemPosition) {
                    view.setBackgroundColor(Color.YELLOW);
                tvDay.setTextColor(Color.WHITE);
                tvDate.setTextColor(Color.WHITE); }
                else {view.setBackgroundColor(Color.TRANSPARENT);
                tvDay.setTextColor(Color.BLACK);
                tvDate.setTextColor(Color.GRAY); }
                return view;
            };
        };
 
        gvDays.setAdapter(oDataAdapter);
 
        gvDays.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
 
                if (checkedItemPosition != position)
                    checkedItemPosition = position;
                else checkedItemPosition = -1;
 
                oDataAdapter.notifyDataSetChanged();
 
// по нажатию на элемент GridView получаем id нажатого элемента из БД.
//где test2 - переменная из класса БД для выборки данных.
                Cursor cursor = (Cursor) gvDays.getItemAtPosition(position);
                String objectsId = cursor.getString(cursor.getColumnIndexOrThrow("_id"));
 
                switch (objectsId) {
                    case "1": test2 = 1; break;
                    case "4": test2 = 4; break;
                    case "8": test2 = 8; break;
                    case "11": test2 = 11; break;
                    case "14": test2 = 14; break;
                }
 //заполняем ListView соответств. данными из БД
                displayObjectsView();
            }
        });
    }
 
 
    private void displayObjectsView() {
        Cursor cursor = oDbHelper.fetchAllObjects();
 
        String[] columns = new String[] {
                ObjectsAdapter.KEY_OBJECT,
                ObjectsAdapter.KEY_TYPE,
                ObjectsAdapter.KEY_PLACE,
                ObjectsAdapter.KEY_TIMESTART,
                ObjectsAdapter.KEY_TIMEFINISH,
                ObjectsAdapter.KEY_TEACHER
        };
 
        int[] to = new int[] {
                R.id.objects_object,
                R.id.objects_type,
                R.id.objects_place,
                R.id.objects_timestart,
                R.id.objects_timefinish,
                R.id.objects_teacher,
        };
 
        oDataAdapter = new SimpleCursorAdapter(
                this, R.layout.list_objects_items, cursor, columns, to, 0);
 
        final ListView lvObjects = (ListView) findViewById(R.id.lvMain);
        lvObjects.setAdapter(oDataAdapter);
    }
}
0
Armagedo
210 / 210 / 60
Регистрация: 22.08.2014
Сообщений: 644
28.01.2015, 17:11 14
Как-то всё запутано у вас в коде...тяжело сходу разбираться...

Почему переменная под адаптер oDataAdapter инициализируется, как адаптер и для грида и для листвью?
Вас это не смущает?

Зачем у вас при каждом клике создаются новые адаптеры гридвью и потом листвью?
Чем они, адаптеры, принципиально отличаются от ранее созданных.

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

Меняйте источники данных для адаптеров через mAdapter.changeCursor(newursor);

И сообщайте, что данные изменились через mAdapter.notifyDataSetChanged();
1
Hedd
13 / 13 / 2
Регистрация: 21.01.2015
Сообщений: 131
28.01.2015, 18:23  [ТС] 15
Armagedo, Действительно, как то я не заметил, что после очередного редактирования один адаптер создал для двух View. Моя ошибка, спасибо. Создал второй адаптер, фон стал меняться корректно.
А как то можно закрепить нажатый элемент?
Т.е. если я опять щелкну по тому же элементу, его фон обратно станет начального цвета.

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

И еще, я как то могу сбросить ListView после вызова из спиннера нового GridView? Сейчас, если я выбираю другой грид через спиннер, данные с предыдыдущего ListView висят на экране, пока я не нажму по элементу грида нововызванного
0
Armagedo
210 / 210 / 60
Регистрация: 22.08.2014
Сообщений: 644
28.01.2015, 18:57 16
Цитата Сообщение от Hedd Посмотреть сообщение
А как то можно закрепить нажатый элемент?
Т.е. если я опять щелкну по тому же элементу, его фон обратно станет начального цвета.
Уберите
else checkedItemPosition = -1;
Цитата Сообщение от Hedd Посмотреть сообщение
И еще, я как то могу сбросить ListView после вызова из спиннера нового GridView? Сейчас, если я выбираю другой грид через спиннер, данные с предыдыдущего ListView висят на экране, пока я не нажму по элементу грида нововызванного
В выборе элемента спиннера

Java
1
2
mListViewAdapter.changeCursor(null);
mListViewAdapter.notifyDataSetChanged();
1
Hedd
13 / 13 / 2
Регистрация: 21.01.2015
Сообщений: 131
28.01.2015, 19:23  [ТС] 17
Armagedo, С фоном разобрался. Спасибо!
ListView удалось сбросить, но только во всех элементах, кроме первого. Если ставить для первого, то приложение закрывается с NullException, что логично, так как сбрасывать нечего. Как этого избежать?

Либо есть еще идея, при выборе другого GridView автоматически включать ListView с позиции первого элемента GridView. Только не знаю как реализовать. Может как то через cursor.moveToFirst.. но не уверен, что так можно..
0
Armagedo
210 / 210 / 60
Регистрация: 22.08.2014
Сообщений: 644
28.01.2015, 19:30 18
Цитата Сообщение от Hedd Посмотреть сообщение
ListView удалось сбросить, но только во всех элементах, кроме первого. Если ставить для первого, то приложение закрывается с NullException, что логично, так как сбрасывать нечего. Как этого избежать?
для какого "первого"?

Выкладывайте код.
0
Hedd
13 / 13 / 2
Регистрация: 21.01.2015
Сообщений: 131
28.01.2015, 19:41  [ТС] 19
Armagedo, ну, если оставить все как было, то у меня же по умолчанию, при запуске приложения, первый пункт спиннера нажат и, соответственный ему GridView показан на экране.
Кликните здесь для просмотра всего текста
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
 // Spinner
        ArrayAdapter<?> adapter =
                ArrayAdapter.createFromResource(this, R.array.weeksList, R.layout.spinner_item);
        adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
        Spinner spinner = (Spinner) findViewById(R.id.spinner);
        spinner.setAdapter(adapter);
 
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
 
 
                switch (position+1){
                    case 1: test = 1;  break;
                    case 2: test = 2;  break;
                    case 3: test = 3;  break;
                    case 4: test = 4;  break;
                    default: break;
                }
 
                ListAdapter.changeCursor(null);
                ListAdapter.notifyDataSetChanged();
 
                displayDaysView();
            }
 
            @Override
            public void onNothingSelected(AdapterView<?> parent) {
 
            }
        });
0
Armagedo
210 / 210 / 60
Регистрация: 22.08.2014
Сообщений: 644
28.01.2015, 20:01 20
ВЕСЬ код вашего класса Activity давайте

Кстати, что это у вас за хитрый код такой для выражения
Java
1
test = position +1
0
28.01.2015, 20:01
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.01.2015, 20:01

Изменение записи в GridView
Здравствуйте. У меня на форме ASP имеется GridView, в котором отображаются...

Изменение ширины колонки в GridView
Добрый день! Проблема такая, написал запрос, вывожу в GridView, однако 4 поля...

Изменение цвета строки gridview
Хочу создать школьный дневник с помошью GridVIew. Но никак не получается...


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

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

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