Форум программистов, компьютерный форум, киберфорум
Программирование Android
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/18: Рейтинг темы: голосов - 18, средняя оценка - 4.89
1 / 1 / 0
Регистрация: 01.02.2016
Сообщений: 13

Восстановление позиции ListView по возвращении из другого Activity

17.04.2016, 01:19. Показов 3558. Ответов 13

Студворк — интернет-сервис помощи студентам
Доброго времени суток.

Имеется activity с ListView, заполняемого из базы данных. При нажатии элемента идёт переход на новое активити с передачей в него данных. По возвращении обратно хотелось бы, чтобы позиция списка сохранялась. Пересмотрел кучу ответов и пробовал все варианты - ни один не работает, при возвращении список отображается сначала, уже не знаю как решить проблему. Последний вариант выглядит так:
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
152
153
154
155
156
157
158
159
160
161
162
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.FilterQueryProvider;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import java.sql.SQLException;
 
public class ElectroActivity extends AppCompatActivity {
 
    EditText objectFilter;
    ListView objectList;
    DatabaseHelper sqlHelper;
    Cursor userCursor;
    SimpleCursorAdapter userAdapter;
    //Parcelable state;
    private static final String LIST_STATE = "listState";
    private Parcelable mListState = null;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_electro);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
 
        objectFilter = (EditText)findViewById(R.id.objectFilter);
        objectList = (ListView)findViewById(R.id.objectList);
        sqlHelper = new DatabaseHelper(getApplicationContext());
        // создаем базу данных
        sqlHelper.create_db();
       }
 
    @Override
    protected void onRestoreInstanceState(Bundle state) {
        super.onRestoreInstanceState(state);
        mListState = state.getParcelable(LIST_STATE);
    }
 
    @Override
    public void onResume(){
        super.onResume();
        try {
            sqlHelper.open();
            userCursor = sqlHelper.database.rawQuery("select * from " + DatabaseHelper.TABLE, null);
            String[] headers = new String[]{DatabaseHelper.COLUMN_NAME, DatabaseHelper.COLUMN_ENERGY,
                DatabaseHelper.COLUMN_SET, DatabaseHelper.COLUMN_ID};
            userAdapter = new SimpleCursorAdapter(this, R.layout.my_list_item,
                userCursor, headers, new int[]{R.id.textname, R.id.textenergy, R.id.textset}, 0);
 
            objectList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    Cursor cursor = (Cursor)objectList.getItemAtPosition(position);
 
                    Intent intent = new Intent(getApplicationContext(), ElDataActivity.class);
                    //intent.putExtra("id",cursor.getString(userCursor.getColumnIndex("_id")));
                    intent.putExtra("object", cursor.getString(userCursor.getColumnIndex("objects")));
                    intent.putExtra("balans", cursor.getString(userCursor.getColumnIndex("balans")));
                    intent.putExtra("napr", cursor.getString(userCursor.getColumnIndex("napr")));
                    intent.putExtra("numTP", cursor.getString(userCursor.getColumnIndex("numTP")));
                    intent.putExtra("numTR", cursor.getString(userCursor.getColumnIndex("numTR")));
                    intent.putExtra("sumTR", cursor.getString(userCursor.getColumnIndex("sumTR")));
                    intent.putExtra("set", cursor.getString(userCursor.getColumnIndex("set")));
                    intent.putExtra("energy", cursor.getString(userCursor.getColumnIndex("energy")));
                    intent.putExtra("kat", cursor.getString(userCursor.getColumnIndex("kat")));
                    intent.putExtra("razr", cursor.getString(userCursor.getColumnIndex("pazr")));
                    intent.putExtra("ust", cursor.getString(userCursor.getColumnIndex("ust")));
                    /*intent.putExtra("balans", DatabaseHelper.COLUMN_BAL);*/
                    //state = objectList.onSaveInstanceState();
                    startActivity(intent);
                }
            });
 
            // если в текстовом поле есть текст, выполняем фильтрацию
            // данная проверка нужна при переходе от одной ориентации экрана к другой
            if(!objectFilter.getText().toString().isEmpty())
                userAdapter.getFilter().filter(objectFilter.getText().toString());
 
            // установка слушателя изменения текста
            objectFilter.addTextChangedListener(new TextWatcher() {
 
                public void afterTextChanged(Editable s) {
                }
 
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                }
                // при изменении текста выполняем фильтрацию
                public void onTextChanged(CharSequence s, int start, int before, int count) {
 
                    userAdapter.getFilter().filter(s.toString());
                }
            });
 
            // устанавливаем провайдер фильтрации
            userAdapter.setFilterQueryProvider(new FilterQueryProvider() {
                @Override
                public Cursor runQuery(CharSequence constraint) {
 
                    if (constraint == null || constraint.length() == 0) {
 
                        return sqlHelper.database.rawQuery("select * from " + DatabaseHelper.TABLE, null);
                    } else {
                        return sqlHelper.database.rawQuery("select * from " + DatabaseHelper.TABLE + " where " +
                                DatabaseHelper.COLUMN_NAME + " like ?", new String[]{"%" + constraint.toString() + "%"});
                    }
                }
            });
 
            //сохраняем положение ListView
            //Parcelable state = objectList.onSaveInstanceState();
 
            //обновляем ListView
            if (mListState != null) {
                objectList.onRestoreInstanceState(mListState);
                mListState = null;
            }
            objectList.setAdapter(userAdapter);
 
            //Восстанавливаем положение ListView
            //objectList.onRestoreInstanceState(state);
            //if(state != null) {
            //    objectList.onRestoreInstanceState(state);
            //}
            //userAdapter.notifyDataSetChanged();
 
        }
        catch (SQLException ex){}
    }
 
    @Override
    protected void onSaveInstanceState(Bundle state) {
        super.onSaveInstanceState(state);
        mListState = objectList.onSaveInstanceState();
        state.putParcelable(LIST_STATE, mListState);
    }
 
    /*@Override
    public void onPause() {
        state = objectList.onSaveInstanceState();
        super.onPause();
    }*/
 
    @Override
    public void onDestroy(){
        super.onDestroy();
        // Закрываем подключения
        sqlHelper.database.close();
        userCursor.close();
        //state = objectList.onSaveInstanceState();
    }
 
}
Подскажите, в чем загвоздка?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
17.04.2016, 01:19
Ответы с готовыми решениями:

При открытие activity одного приложения предлагает открыть activity другого
При открытие одного activity предлагает открыть activity другого. Package у них разный.

Как в Android Studio изменять объект одного Activity из другого Activity?
Есть два Activity, в одном кнопка и элемент editText. Во втором activity есть элемент TextView. Когда я в первом активити ввожу текст с...

Изменение layout-элементов одного activity из другого activity
Здравствуйте! Я хочу изменить размер или цвет текста TextView в одном activity из второго activity, каким образом мне можно это...

13
426 / 406 / 68
Регистрация: 06.10.2012
Сообщений: 1,748
17.04.2016, 11:57
gelios_oleg, привет!
Не стал разбираться в коде, делал когда-то такое, всё работало. И для активностей, и для фрагментов тоже можно придумать.
Если идти по простому варианту, то надо открывать одну активность из другой через startActivityForResult. По окончании ловить событие возврата через onActivityResult. Туда и обратно передавать позицию в списке. Можно было бы сохранять её в самой вызывающей активности, но она может уничтожиться.
Восстановление и получение позиции в списке делается двумя методами. Первый прокручивает к нужному месту, второй тоже не помню, как называется.
1
1 / 1 / 0
Регистрация: 01.02.2016
Сообщений: 13
17.04.2016, 23:35  [ТС]
Спасибо за совет, я глядел в сторону startActivityForResult, но юоюсь мне не совсем подходит, так как на ListView я возвращаюсь кнопкой Назад, то есть результат потеряется.

Добавлено через 5 часов 35 минут
Попробовал запихать в finish():
Java
1
2
3
4
5
6
7
    @Override
    public void finish() {
        Intent intent = new Intent();
        intent.putExtra("pos", pos);
        setResult(RESULT_OK, intent);
        super.finish();
    }
Но на выходе ничего не получаю:
Java
1
2
3
4
5
6
7
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (data == null) {return;}
        posBack = data.getIntExtra("pos", posBack);
        Log.i("!!!!!!!", "Возврат на ");
        Log.i("!!!!!!!", Integer.toString(posBack));
    }
Что-то я точно делаю неправильно. Да с listView ухожу в интент:
Java
1
2
3
final int REQUEST_CODE = 1;
 
startActivityForResult(intent, REQUEST_CODE);
0
426 / 406 / 68
Регистрация: 06.10.2012
Сообщений: 1,748
18.04.2016, 17:09
gelios_oleg, не за что!
Что-то я не увидел у вас корректного кода.
Если вы вызываете одну активность из другой, можно использовать startActivityForResult, она отрабатывает всегда (сложные случаи лишь для фрагментов и ещё есть проблемный момент для фотографирования).
Открываю первую попавшуюся ссылку (http://developer.alexanderklim... tivity.php).
Запуск:
Java
1
2
Intent intent = new Intent(MainActivity.this, ChooseActivity.class);
startActivityForResult(intent, CHOOSE_THIEF);
Константа CHOOSE_THIEF в данном случае определяет для onActivityResult, из какой активности мы вернёмся. Можете обозвать её как угодно и присвоить любое уникальное числовое значение. Например, CHOOSE_THIEF = 100.
Дальше требуется передать в intent все необходимые параметры.
Java
1
2
3
intent.putString("что-то", value1);
intent.putBoolean("признак", true);
intent.putLong("позиция", offset);
Теперь пропишите в ChooseActivity (вместо этого названия - ваше) обработку параметров, какие-то действия и возврат.
Java
1
2
3
4
5
Intent intent = getIntent();
String user = intent.getStringExtra("что-то");
boolean b = intent.getBooleanExtra("признак");
long offset = intent.getLongExtra("позиция");
// Дальнейшая работа.
Когда задумаете возвращаться, надо прописать следующее. Во многих руководствах предлагается вернуться по кнопке, но это ахинея, потому что пользователь может вернуться по кнопке "Назад". Надо переопределить событие onBackPressed().
Java
1
2
3
4
5
6
7
 @Override
    public void onBackPressed() {
            Intent intent = new Intent();
            intent.putExtra("позиция", offset);
            setResult(RESULT_OK, intent);
        super.onBackPressed();
    }
Теперь надо словить событие onActivityResult в вызывающей активности.
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
 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        super.onActivityResult(requestCode, resultCode, data);
 
        switch (requestCode)
        {
            case CHOOSE_THIEF:
                if (resultCode == RESULT_OK && data != null) {
                    if (data.hasExtra("позиция")) {
                       long offset = data.getLongExtra("позиция", -1);
                       // Тут прокрутите к нужной позиции.
                    }
                }
                break;
 
            case DEFECT_PHOTO_TAKE_REQUEST_CODE:
                if (resultCode == RESULT_OK) {
                }
                break;
 
            default:
                break;
        }
    }
Код не проверял, он может не работать, делайте сами.
0
2884 / 2296 / 769
Регистрация: 12.05.2014
Сообщений: 7,978
18.04.2016, 17:53
gelios_oleg, только что создал активити с листвью
заполнил его списком, на Fab повесил старт второй активити

листаю на какую угодно позицию в листе и нажимаю fab - открывается второе активити...нажимаю Back на клавиатуре, второе активити закрывается и я вижу первое активити и список как был так и остался на том месте куда я наскорлил - не сдвинулся ни на йоту

я не понял задачу или что?
0
Автор FAQ
Автор FAQ
 Аватар для REALIST07
644 / 199 / 21
Регистрация: 11.06.2010
Сообщений: 1,024
18.04.2016, 18:19
Ребят, для глобального хранения позиции подойдет наследник класса Application
0
2884 / 2296 / 769
Регистрация: 12.05.2014
Сообщений: 7,978
18.04.2016, 18:28
это и так понятно
хоть sharedpreference хоть Application
я к тому что позиция в листвью не сбрасывается когда активити возвращается из стека
0
426 / 406 / 68
Регистрация: 06.10.2012
Сообщений: 1,748
18.04.2016, 19:13
Цитата Сообщение от Паблито Посмотреть сообщение
и список как был так и остался на том месте куда я наскорлил - не сдвинулся ни на йоту
Это в простом случае, когда активность не пересоздаётся, а ListView не перезаполняется данными из БД.
0
2884 / 2296 / 769
Регистрация: 12.05.2014
Сообщений: 7,978
18.04.2016, 20:24
получилось запоминать-восстанавливать так

эти две переменные сохраняем как удобно - преференсы, класс приложения - куда угодно
Java
1
2
int pos; // первый видимый элемент списка
int offset; // для точного позиционирования, вдруг он виден не полностью
запоминаем позицию
Java
1
2
3
                    pos = lv.getFirstVisiblePosition();
                    View v = lv.getChildAt(0);
                    if (v != null) offset = v.getTop() - lv.getPaddingTop();
восстанавливаем
Java
1
        lv.setSelectionFromTop(pos, offset);
0
1 / 1 / 0
Регистрация: 01.02.2016
Сообщений: 13
19.04.2016, 01:12  [ТС]
Всем спасибо, проблему описал видимо некорректно. Была проблема с запоминаем позиции при нажатии на кнопку "назад" в тулбаре. Как всегда всё просто на самом деле, голова была забита основными задачами (не android, и не программирование) и не мог понять толком почему не получается вариант с
Java
1
2
3
4
5
6
//сохраняем положение ListView
            Parcelable state = objectList.onSaveInstanceState();
            //формируем список
            objectList.setAdapter(userAdapter);
            //восстанавливаем положение ListView при возврате с дочернего окна
            objectList.onRestoreInstanceState(state);
Соответственно не разобравшись толком стал прыгать от варианта к варианту, в которых толком тоже не разобрался. В общем методом наскока не получилось.
Решение элементарное (причем, что забавно, что в одном из активити программы уже применял ранее, но забыл про это):
В дочернем активити запускаю:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        //переопределяем действие кнопки назад на тубаре
        //для вызова onSaveInstanceState() (запоминание положение списка) в предыдущем окне
        switch (item.getItemId()) {
            case android.R.id.home:
                onBackPressed();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
 
 
    @Override
    public void onBackPressed(){
        super.onBackPressed();
    }
И всё хорошо
0
426 / 406 / 68
Регистрация: 06.10.2012
Сообщений: 1,748
19.04.2016, 09:31
gelios_oleg, тут у вас есть лишнее, но принцип правильный. Как раз недавно мне тоже это подсказали. Раньше, как и большинство авторов, писал туда finish().
1
1 / 1 / 0
Регистрация: 01.02.2016
Сообщений: 13
21.04.2016, 09:44  [ТС]
Мммм... А не подскажите, что лишнее? Я как бы не опытный программист, точнее сказать не программист, специальность смежная, а работа вообще несмежная просто решил написать для себя приложение, и разбираюсь по чуть-чуть, по урокам, книгам и гуглу. А хочется, чтобы выглядело красиво.
0
426 / 406 / 68
Регистрация: 06.10.2012
Сообщений: 1,748
21.04.2016, 09:59
Цитата Сообщение от gelios_oleg Посмотреть сообщение
А не подскажите, что лишнее?
Цитата Сообщение от gelios_oleg Посмотреть сообщение
@Override public void onBackPressed(){
super.onBackPressed();
}
Поскольку вы не переопределяете действия по обработке кнопки "Назад", то этот код лишний. Хорошо, что super.onBackPressed() не забыли, а то кнопка "Назад" перестала бы работать (на этом и основан принцип её отключения).
Цитата Сообщение от gelios_oleg Посмотреть сообщение
//восстанавливаем положение ListView при возврате с дочернего окна
objectList.onRestoreInstanceState(state) ;
Этот код мне пока не известен и я боюсь, что тут может быть проблема, если objectList = null, но тему не штудировал. Я обычно использую onSaveInstanceState. Но в данном случае это не требовалось, если есть onActivityResult.
1
1 / 1 / 0
Регистрация: 01.02.2016
Сообщений: 13
21.04.2016, 14:29  [ТС]
Цитата Сообщение от gelios_oleg Посмотреть сообщение
@Override public void onBackPressed(){
super.onBackPressed();
}
Поскольку вы не переопределяете действия по обработке кнопки "Назад", то этот код лишний. Хорошо, что super.onBackPressed() не забыли, а то кнопка "Назад" перестала бы работать (на этом и основан принцип её отключения).
Да, действительно забыл убрать, во время экспериментов появилось

Цитата Сообщение от gelios_oleg Посмотреть сообщение
//восстанавливаем положение ListView при возврате с дочернего окна
objectList.onRestoreInstanceState(state) ;
Этот код мне пока не известен и я боюсь, что тут может быть проблема, если objectList = null, но тему не штудировал. Я обычно использую onSaveInstanceState. Но в данном случае это не требовалось, если есть onActivityResult.
Позже, я поставил проверку на null.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
21.04.2016, 14:29
Помогаю со студенческими работами здесь

Из одного Activity получить значение другого Activity
Запускаю активити: public class MainActivity extends Activity { ... ... Intent intent = new Intent(getBaseContext(),...

Передача данных из ListView в другой Activity в ListView
Добрый день. Пытаюсь разобраться с передачей данных с ListView, но выходит что то непонятное, скриншоты приложения приложил. После...

Как правильно скролить ListView который находится внутри другого ListView?
Доброго! Впихнул один ListView во внутрль другого, получил интересный эффект... если жмакнуть по элементу верхнего ListView, то скролл...

Динамический интерфейс, восстановление Activity
Как восстановить переменную при возврате в активность.(варианты с записью в файл или БД пока не рассматриваются, интересен базовый...

Из ListView на новую Activity
Доброго времени суток! Я делал приложение в котором из &quot;главного меню&quot; осуществляется переход на новую Activity. В том Activity...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
Установка Qt Creator для C и C++: ставим среду, CMake и MinGW без фреймворка Qt
8Observer8 05.04.2026
Среду разработки Qt Creator можно установить без фреймворка Qt. Есть отдельный репозиторий для этой среды: https:/ / github. com/ qt-creator/ qt-creator, где можно скачать установщик, на вкладке Releases:. . .
AkelPad-скрипты, структуры, и немного лирики..
testuser2 05.04.2026
Такая программа, как AkelPad существует уже давно, и также давно существуют скрипты под нее. Тем не менее, прога живет, периодически что-то не спеша дополняется, улучшается. Что меня в первую очередь. . .
Отображение реквизитов в документе по условию и контроль их заполнения
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеСпецтехники", разработанного в конфигурации КА2. Данный документ берёт данные из другого нетипового документа. . .
Фото всей Земли с борта корабля Orion миссии Artemis II
kumehtar 04.04.2026
Это первое подобное фото сделанное человеком за 50 лет. Снимок называют новым вариантом легендарной фотографии «The Blue Marble» 1972 года, сделанной с борта корабля «Аполлон-17». Новое фото. . .
Вывод диалогового окна перед закрытием, если документ не проведён
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать программный контроль на предмет проведения документа. . .
Программный контроль заполнения реквизитов табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: 1. Реализовать контроль заполнения реквизита. . .
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru