Форум программистов, компьютерный форум, киберфорум
Программирование Android
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/9: Рейтинг темы: голосов - 9, средняя оценка - 4.67
2 / 1 / 1
Регистрация: 27.01.2018
Сообщений: 39

Реализация динамических вкладок в связке TabLayout + ViewPager + FragmentPagerAdapter

04.07.2019, 22:56. Показов 2042. Ответов 5

Студворк — интернет-сервис помощи студентам
Здравствуйте!

Реализовываю многодокументный многовкладочный интерфейс в своём приложении. Хотелось бы нормализовать поведение вкладок и всей связки TabLayout + ViewPager + FragmentPagerAdapter. Добавление и удаление вкладок ей-богу работает. Однако при удалении и добавлении вкладок их содержимое пересоздаётся. Как реализовать это нормально и что я не так делаю?

ПРЕДУПРЕЖДЕНИЕ: некоторые части из исходного кода я вырезал (связанные с Toolbar, Menu)

MainActivity.java
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
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
 
public class MainActivity extends AppCompatActivity {
 
    ViewPager viewPager;
    TabLayout tabLayout;
    PageFragmentAdapter pageAdapter;
 
    int lastTabID = 0;
    int currentTabID = 0;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        pageAdapter = new PageFragmentAdapter(getSupportFragmentManager(), MainActivity.this);
 
        viewPager = (ViewPager)findViewById(R.id.mainViewPager);
        viewPager.setAdapter(pageAdapter);
        tabLayout = (TabLayout)findViewById(R.id.mainTabSlider);
        tabLayout.setupWithViewPager(viewPager);
 
        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { // здесь жалуется, что это типа устаревший метод. Использую API 27 с совместимостью с API 21
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                lastTabID = currentTabID;
                int tabID = tab.getPosition();
                currentTabID = tabID;
            }
 
            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
 
            }
 
            @Override
            public void onTabReselected(TabLayout.Tab tab) {
 
            }
        });
 
        newTab();
    }
 
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }
 
    public void newTab() {
        pageAdapter.newTab();
        viewPager.setAdapter(pageAdapter);
        viewPager.setCurrentItem(pageAdapter.getCount()-1, false);
    }
 
    private void removeTab() {
        if ((pageAdapter.getCount() == 1) || (pageAdapter.getCount() == 0)) {
            finish();
        } else {
            if (lastTabID >= pageAdapter.getCount()-1) {
                lastTabID = pageAdapter.getCount()-2;
            } else if (lastTabID <= -1) {
                lastTabID = 0;
            }
            int removingTabID = currentTabID;
            viewPager.setCurrentItem(lastTabID, false);
            pageAdapter.removeTab(removingTabID);
            viewPager.setAdapter(pageAdapter);
        }
    }
}
PageFragmentAdapter.java
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
import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import java.util.*;
 
 
public class PageFragmentAdapter extends FragmentPagerAdapter {
    private int pageCount = 0;
    ArrayList<String> titles;
 
    private Context context;
 
    public PageFragmentAdapter(FragmentManager fm, Context context) {
        super(fm);
        this.context = context;
 
        titles = new ArrayList<>();
    }
 
    @Override public int getCount() {
        return pageCount;
    }
 
    @Override public Fragment getItem(int position) {
        return PageFragment.newInstance(position + 1);
    }
 
    @Override public CharSequence getPageTitle(int position) {
        return titles.get(position);
    }
 
 
    public void newTab() {
        pageCount++;
        titles.add("Новая");
    }
 
    public void removeTab(int position) {
        pageCount--;
        titles.remove(position);
    }
 
}
PageFragment.java
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
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.TextView;
 
public class PageFragment extends Fragment {
    public static final String ARG_PAGE = "ARG_PAGE";
 
    private int mPage;
 
    public static PageFragment newInstance(int page) {
        Bundle args = new Bundle();
        args.putInt(ARG_PAGE, page);
        PageFragment fragment = new PageFragment();
        fragment.setArguments(args);
        return fragment;
    }
 
    @Override public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mPage = getArguments().getInt(ARG_PAGE);
        }
    }
 
    @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                                       Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.page, container, false);
        WebView webView = (WebView) view;
        webView.loadData("СТРАНИЦА " + mPage, "text/html", "UTF-8"); // вот здесь задаются номера и при закрытии вкладок по идее номера долны оставаться, а не пересоздаваться
        return view;
    }
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
04.07.2019, 22:56
Ответы с готовыми решениями:

ViewPager, FragmentPagerAdapter непонятное поведение
Добрый день, подскажите пожалуйста, есть ViewPager с 4 табами, все нормально загружается и отображается, но когда например начинаю...

Как заставить работать ViewPager + TabLayout в ScrollView?
Здравствуйте. Столкнулся с проблемой - ViewPager напрочь отказывается отображаться в ScrollView. При этом вне ScrollView всё работает как...

Обновление данных в ViewPager при перелистывании вкладок
Есть две вкладки (смотри картинку). На первой нажимаем кнопку плюс - пишем имя - сохраняю item. Теперь, при перелистывании этот Item...

5
2 / 1 / 1
Регистрация: 27.01.2018
Сообщений: 39
04.07.2019, 23:20  [ТС]
Дополнительно (чтобы было наглядно видно проблему) выкладываю скриншоты с моими действиями:







0
93 / 66 / 27
Регистрация: 23.06.2019
Сообщений: 477
06.07.2019, 05:23
Цитата Сообщение от iner7 Посмотреть сообщение
Однако при удалении и добавлении вкладок их содержимое пересоздаётся. Как реализовать это нормально и что я не так делаю?
Вы ничего не создаете. Создает фрагметны адаптер при листании страницы туда-сюда. Причем заранее. Так сказать с кэшированием. А Вы только увеличиваете или уменьшаете количество страниц.
И эта штука "Страница 1" , вот эта цыфра - это позиция страницы для пэйджера. От 1 до pageCount. Причем она обноваляется по мере листания фрагментов.

Добавлено через 4 минуты
Я тоже с этим пэйджером играюсь.
Листаю от первого к второму и обратно. Фрагмент 1 не создается. Берется из кэша.
Листают до четвертого от обратно. И Фрагмент 1 создается, когда дохожу до второго.
Когда он убивается не заморачивался. Все данные, которые надо отобразить в неубиваемых ВьюМоделях.
Созданием заморачивался только потому, что переводил на data binding c обозревателей.
0
2 / 1 / 1
Регистрация: 27.01.2018
Сообщений: 39
07.07.2019, 11:23  [ТС]
Цитата Сообщение от vs2019 Посмотреть сообщение
Я тоже с этим пэйджером играюсь.
Вот я подумал и вспомнил (ведь этот TabLayout я ранее не использовал, а вкладки реализовывал встроенными средствами ActionBar): я ведь все View хранил в ArrayList из java.util, а когда было переключение меж вкладок, я просто-напросто задавал соответствующий View в контейнере. И тут я решил перейти с Eclipse ADT на Android SDK и встретил много для себя нового и интересного. В том числе и TabLayout, и ViewPager.
И вот интересно: можно ли использовать TabLayout без привязки к ViewPager?
0
93 / 66 / 27
Регистрация: 23.06.2019
Сообщений: 477
07.07.2019, 15:46
Чем ViewPager не устраивает? Классная штука.

А так, можете кнопочки в ряд(или как угодно) установить и вызывать по нажатию нужный фрагмент.
Только как с свайпом быть? Что бы пальчиком, как странички листались.

Добавлено через 1 минуту
Вот тут про современные методы навигации в приложениях:
https://developer.android.com/guide/navigation/

Множество способов сделать одно и тоже. Выбирайте на вкус и цвет.
0
2 / 1 / 1
Регистрация: 27.01.2018
Сообщений: 39
08.07.2019, 23:22  [ТС]
Цитата Сообщение от vs2019 Посмотреть сообщение
Чем ViewPager не устраивает?
Ну, может он и удобен в плане того, что можно несколько страниц хранить. НО это пересоздавание страниц и вот такой вот свайпинг влево-вправо меня не очень устраивает. Я пишу на самом деле браузер и страницы могут прокручиваться и горизонтально. И эта опция в браузерах, я думаю, не нужна совершенно.
Цитата Сообщение от vs2019 Посмотреть сообщение
Только как с свайпом быть? Что бы пальчиком, как странички листались.
Вы имеете в виду пролистывание вкладок? Если Вы про это, то можно эти кнопки вложить в ScrollView.
Цитата Сообщение от vs2019 Посмотреть сообщение
Вот тут про современные методы навигации в приложениях:
Спасибо, конечно за ссылку, только если бы это было всё на русском (у меня другой язык в школе)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
08.07.2019, 23:22
Помогаю со студенческими работами здесь

Создание динамических вкладок в собственном браузере
Разрабатываю свой Web-браузер с динамически-создаваемыми вкладками. Код брала с C++. При переносе на Delphi возникают ошибки. И еще...

Создание динамических вкладок в PageConrol для TWebBrowser
Объясните, пожалуйста, табы создаются, но сёрфинг происходит только на первой, даже, если выбрана другая вкладка. Все исходники лежат в...

Классы. Реализация создание вкладок в TabPage
Здравствуйте имеется класс: public class ListUrlsToOpen { public List&lt;string&gt; listurlstoopen; private string...

Реализация динамического списка динамических стеков
не знаю как выдолнить работу &quot;реализация динамического списка динамических стеков&quot;. нужно позарез,а как делать не знаю (((( помогите...

Реализация матрицы с помощью динамических массивов
Всем привет) У меня есть проблема вот в этом задаче: Реализовать 2 базовых и 1 производный классы. В базовых классах описать...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Первый деплой
lagorue 16.01.2026
Не спеша развернул своё 1ое приложение в kubernetes. А дальше мне интересно создать 1фронтэнд приложения и 2 бэкэнд приложения развернуть 2 деплоя в кубере получится 2 сервиса и что-бы они. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит токи на L и напряжения на C в установ. режимах до и. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru