Android - создайте ViewPager с динамически создаваемыми страницами (циркуляр) - PullRequest
0 голосов
/ 27 сентября 2019

Как я могу создать ViewPager, который содержит страницы, которые создаются динамически?Нет ограничений по количеству страниц.С самого начала пользователь может перемещаться (пролистывать) влево или вправо, чтобы перейти на предыдущую или следующую страницу.Таким образом, нет «страницы 0» (в списке).

Приложение может быть книгой.Это может быть приложение погоды (или данных), отображающее данные за предыдущие дни или прогноз погоды на несколько дней вперед.В случае книги, после перезапуска приложение может быть на странице 35. Когда пользователь переходит на предыдущую страницу, сразу же эта страница 34 может отображаться.ТАК - работа со списком фрагментов не работает.

ОБНОВЛЕНИЕ : я удалил исходный код из вопроса, потому что создал полное решение.Это в проекте Github.

1 Ответ

0 голосов
/ 28 сентября 2019

Решение сделать циркуляр ViewPager основано на предложениях сообщения портфеля и сообщения tobi_b .

Хороший пример можно найти в этот проект Github .Каждая страница (или фрагмент) генерируется полностью динамически.Навигация назад или вперед поддерживается (так круговая).Конечно, он имеет AndroidX в качестве базы.

Действие:

public class MainActivity extends FragmentActivity {
    static MainActivity mainActivity;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mainActivity = this;
        if (getSupportFragmentManager().findFragmentById(android.R.id.content) == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(android.R.id.content,
                            new PagerFragment()).commit();
        }
    }
}

PagerFragment:

public class PagerFragment extends Fragment {
    private static final int SET_ITEM_DELAY = 300;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View result=inflater.inflate(R.layout.pager, container, false);
        final ViewPager pager= result.findViewById(R.id.pager);
        pager.addOnPageChangeListener( new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            }
            @Override
            public void onPageSelected( final int position) {
                pager.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        handleSetCurrentItem(position);
                    }
                }, SET_ITEM_DELAY);
            }
            @Override
            public void onPageScrollStateChanged(int state) {
            }
            private void handleSetCurrentItem(final int position) {
                final int lastPosition = pager.getAdapter().getCount() - 1;
                if (position == 0) {
                    pager.setCurrentItem(lastPosition - 1, false);
                } else if (position == lastPosition) {
                    pager.setCurrentItem(1, false);
                }
            }
        });
        pager.setAdapter(buildAdapter());
        pager.setCurrentItem(1); // not 0 !!!
        return(result);
    }
    private PagerAdapter buildAdapter() {
        return(new SampleAdapter(getActivity(), getChildFragmentManager()));
    }
}

SamplerAdapter:

public class SampleAdapter extends FragmentStatePagerAdapter {
    private int numberOfPages = 10;
    Context ctxt = null;
    public SampleAdapter(Context ctxt, FragmentManager mgr) {
        super(mgr);
        this.ctxt = ctxt;
    }
    @Override
    public int getCount() {
        return (numberOfPages + 2);
    }

    @Override
    public Fragment getItem(final int position) {
        if (position == 0) {
            return (EditorFragment.newInstance(numberOfPages - 1));
        } else if (position == numberOfPages + 1) {
            return (EditorFragment.newInstance(0));
        } else {
            return (EditorFragment.newInstance(position - 1));
        }
    }
    @Override
    public String getPageTitle(int position) {
        return (EditorFragment.getTitle(ctxt, position));
    }
}

Файл макета:

<?xml version="1.0" encoding="utf-8"?>
<androidx.viewpager.widget.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
<!--    <androidx.viewpager.widget.PagerTitleStrip could be placed here -->
</androidx.viewpager.widget.ViewPager>

Динамический фрагмент:

public class EditorFragment extends Fragment {
    private static final String KEY_POSITION = "position";
    static EditorFragment newInstance(int position) {
        EditorFragment frag = new EditorFragment();
        Bundle args = new Bundle();
        args.putInt(KEY_POSITION, position);
        frag.setArguments(args);
        return (frag);
    }
    static String getTitle(Context ctxt, int position) {
        return (String.format(ctxt.getString(R.string.hint), position + 1));
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View result = inflater.inflate(R.layout.editor, container, false);
        EditText editor = (EditText) result.findViewById(R.id.editor);
        int position = getArguments().getInt(KEY_POSITION, -1);
        editor.setHint(getTitle(getActivity(), position));
        return (result);
    }
}

Он имеет очень простой файл макета:

<EditText xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/editor"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:inputType="textMultiLine"
    android:gravity="left|top" />

Это работает очень хорошо!

...