使用动态页面创建 ViewPager(prev/next 页面查看器,循环,例如 Book 应用程序)
Create ViewPager with dynamic pages (prev/next page viewer, circular, e.g. Book app)
如何创建包含动态创建页面的 ViewPager?页数没有限制。从一开始,用户就可以向左或向右导航(滑动)以获取上一页或下一页。所以没有 'page 0' (在列表中)。
一个应用程序可以是一本书。它可以是一个天气(或数据)应用程序,显示前几天的数据或未来几天的天气预报。
在书柜中,重新启动应用程序后可能会显示在第 35 页。当用户导航到上一页时,会立即显示第 34 页。所以 - 使用片段列表不起作用。
更新:我从问题中删除了源代码,因为我已经创建了一个完整的解决方案。它在一个 give Github 项目中。
使ViewPager循环的解决方案是基于portfoliobuider's post and tobi_b's post的建议。
您可以在 this Github project 中找到一个很好的例子。每个页面(或片段)都是完全动态生成的。支持向后或向前导航(如此循环)。当然它有AndroidX作为基础。
Activity是:
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" />
效果很好!
如何创建包含动态创建页面的 ViewPager?页数没有限制。从一开始,用户就可以向左或向右导航(滑动)以获取上一页或下一页。所以没有 'page 0' (在列表中)。
一个应用程序可以是一本书。它可以是一个天气(或数据)应用程序,显示前几天的数据或未来几天的天气预报。 在书柜中,重新启动应用程序后可能会显示在第 35 页。当用户导航到上一页时,会立即显示第 34 页。所以 - 使用片段列表不起作用。
更新:我从问题中删除了源代码,因为我已经创建了一个完整的解决方案。它在一个 give Github 项目中。
使ViewPager循环的解决方案是基于portfoliobuider's post and tobi_b's post的建议。
您可以在 this Github project 中找到一个很好的例子。每个页面(或片段)都是完全动态生成的。支持向后或向前导航(如此循环)。当然它有AndroidX作为基础。
Activity是:
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" />
效果很好!