我有一个正常工作的FragmentPagerAdapter,但我想知道的是,如果FragmentPagerAdapter在最后一个视图上,我如何才能让它循环回到第一个视图并继续正常运行
这是我正在使用的示例代码
public class FragmentPager extends FragmentActivity {
MyAdapter mAdapter;
ViewPager mPager;
static final int NUM_ITEMS = 5;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mAdapter = new MyAdapter(getSupportFragmentManager());
mPager = (ViewPager)findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
}
public static class MyAdapter extends FragmentPagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
@Override
public int getCount() {
return NUM_ITEMS;
}
@Override
public Fragment getItem(int position) {
return MyFragment.newInstance(position);
}
}
public static class MyFragment extends ListFragment{
int mNum;
/**
* Create a new instance of CountingFragment, providing "num"
* as an argument.
*/
static MyFragment newInstance(int num) {
MyFragment f = new MyFragment();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
/**
* When creating, retrieve this instance's number from its arguments.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNum = getArguments() != null ? getArguments().getInt("num") : 1;
}
/**
* The Fragment's UI is just a simple text view showing its
* instance number.
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_pager_list, container, false);
View tv = v.findViewById(R.id.text);
((TextView)tv).setText("Fragment #" + mNum);
return v;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, new String[] {"test1","test2","test3","test4","Test5"}));
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
Log.i("FragmentList", "Item clicked: " + id);
}
}
}基本上,当它到达末尾时,我如何让它像显示任何其他片段一样显示第一个片段?
即。A->B、B->C、C->A和反向A->C、C->B、B->A
发布于 2012-11-03 07:17:31
这是我的解决方案,我有"n“个屏幕(在本例中是5个),因为我想回到列表末尾的第一个屏幕,所以我”添加另一个屏幕“,这只是最后一个屏幕的精确副本,也是反向的。基本上我现在有"n“个屏幕+2 (在本例中是7个)。屏幕是这样设置的:copy of C、A、B、C、copy of A,然后我设置一个手势监听器来观察某些页面上的滑动。
如果在列表的末尾(“A的副本”),我检测到向左滑动页面,我将移动到> a certain number of pixels A,并继续以正常的页面旋转方式向后滑动。
向相反方向滑动也是如此。
问题
当从一个结束页面移动到模拟循环时,它确实会变得有点慢,因为ViewPager加载了您当前所在页面之前和之后的页面,但由于您位于页面列表的末尾或开头,因此它不会像通常那样加载下一个页面,因为从技术上讲,没有下一个页面。只有在每个列表行都有复杂的自定义视图时,才会发生这种情况
您不能将它与用于页面滚动的动画一起使用,因为它看起来不是无缝的,并且当您从复制的页面移动到实际页面时(即A到A的副本),它将具有动画效果。
此外,它似乎有时会卡住在页面的末尾,我不知道为什么
这是我的完整演示应用程序,基于android开发人员站点上的viewpager示例
public class FragmentPager extends FragmentActivity{
MyAdapter mAdapter;
public static ViewPager mPager;
static int currentPage = 1;
static final int NUM_ITEMS = 7;
public static View vContainer;
float dxInitial=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mAdapter = new MyAdapter(getSupportFragmentManager());
mPager = (ViewPager)findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
mPager.setCurrentItem(1,false);
mPager.setOnTouchListener(new OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN){
dxInitial=event.getX();
Log.d("INITIAL X", String.valueOf(dxInitial));
}else if(event.getAction() == MotionEvent.ACTION_MOVE){
if(event.getX() - dxInitial > 100 && currentPage==1){
mPager.setCurrentItem(6,false);
}else if(dxInitial - event.getX() > 100 && currentPage==5){
mPager.setCurrentItem(0,false);
}else if(dxInitial - event.getX() > 50 && currentPage==6){
mPager.setCurrentItem(1,false);
}else if(event.getX() - dxInitial > 50 && currentPage==0){
mPager.setCurrentItem(5,false);
}
}
/*if(Math.abs(dx) > Math.abs(dy)) {
if(dx>75){ directiion = "right";
}else if{
direction = "left";
}
} else {
if(dy>0) direction = "down";
else direction = "up";
}*/
return false;
}
});
mPager.setOnPageChangeListener(new OnPageChangeListener(){
@Override
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub
if(state == ViewPager.SCROLL_STATE_IDLE){
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int arg0) {
currentPage=arg0;
}
});
}
public static class MyAdapter extends FragmentPagerAdapter{
public MyAdapter(FragmentManager fm) {
super(fm);
}
@Override
public int getCount() {
return NUM_ITEMS;
}
@Override
public Fragment getItem(int position) {
return MyFragment.newInstance(position);
}
@Override
public Object instantiateItem(View container, int position) {
vContainer=container;
return super.instantiateItem(container, position);
}
}
public static class MyFragment extends ListFragment{
int mNum;
/**
* Create a new instance of CountingFragment, providing "num"
* as an argument.
*/
static MyFragment newInstance(int num) {
MyFragment f = new MyFragment();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
/**
* When creating, retrieve this instance's number from its arguments.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNum = getArguments() != null ? getArguments().getInt("num") : 1;
}
/**
* The Fragment's UI is just a simple text view showing its
* instance number.
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_pager_list, container, false);
View tv = v.findViewById(R.id.text);
if(mNum == 6){
mNum=1;
}else if(mNum==7){
mNum=5;
}else if(mNum==0){
mNum=5;
}
((TextView)tv).setText("Fragment #" + mNum);
return v;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, new String[] {"test1","test2","test3","test4","Test5"}));
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
Log.i("FragmentList", "Item clicked: " + id);
}
}
}发布于 2012-10-09 01:01:10
这是一个相当不错的技巧,但对我来说,它工作得很好:
@Override
public int getCount() {
return NUM_ITEMS * 1000;
}这将使您的页面“循环”1000x不要忘记在getItem上使用%操作,如下所示
@Override
public Fragment getItem(int position) {
position = position % 1000;
return MyFragment.newInstance(position);
}发布于 2020-06-18 03:31:44
我根据tyczj的回答做了一个Kotlin解决方案,它处理在适配器创建后加载carousel项的时间(例如,从服务器加载项),也不会获取触摸侦听器,而是等待ViewPager2的空闲状态。在我的例子中,我有一个用户配置文件的旋转木马。
根据tycjz的回答,如果我们有一组A B C D项,那么ViewPager2函数以C A B C D A结尾,但是我们从ViewPager2 @ position 1而不是0开始,所以它以A结尾。
inner class UserProfileSlidePagerAdapter(fa: FragmentActivity) : FragmentStateAdapter(fa) {
var profileToJumpTo: Int? = null
override fun getItemCount(): Int {
if (userIdsForLocalUsers.size > 0) {
return userIdsForLocalUsers.size + 2
}
return userIdsForLocalUsers.size
}
override fun createFragment(position: Int): Fragment {
var positionToUse = position - 1
if (position > userIdsForLocalUsers.size)
{
positionToUse = 0
}
if (positionToUse < 0)
{
positionToUse = userIdsForLocalUsers.size - 1
}
val userId = userIdsForLocalUsers[positionToUse]
this@ProfileViewModel.availableUserProfilesHash[userId].let {userProfile ->
return CarouselUserProfileFragment.newInstance(userProfile!!)
}
}
}如下所示,在管理了PageAdapter的"off by 1“定位问题之后,您可以确定当ViewPager2 onPageSelected事件发生时,您是在循环的开始还是结束,然后选择当页面处于onPageScrollStateChanged的空闲状态时跳转到哪个页面。所以在ViewPager2所在的Fragment中:
this.profiles_view_pager.registerOnPageChangeCallback(object: ViewPager2.OnPageChangeCallback() {
override fun onPageScrollStateChanged(state: Int) {
if (state == ViewPager2.SCROLL_STATE_IDLE) {
val adapter = this@CarouselFragment.profiles_view_pager.adapter as ProfileViewModel.UserProfileSlidePagerAdapter
val profileToJumpTo = adapter.profileToJumpTo
profileToJumpTo?.let {
this@CarouselFragment.profiles_view_pager.setCurrentItem(profileToJumpTo, false)
adapter.profileToJumpTo = null
}
}
super.onPageScrollStateChanged(state)
}
override fun onPageSelected(position: Int) {
val adapter = this@CarouselFragment.profiles_view_pager.adapter as ProfileViewModel.UserProfileSlidePagerAdapter
adapter.itemCount.let { itemCount ->
if (position == 0) {
adapter.profileToJumpTo = itemCount - 2
}
if (position == itemCount - 1) {
adapter.profileToJumpTo = 1
}
}
super.onPageSelected(position)
}
})我还可以通过LiveData将当前项设置为"+1“。
this.profileViewModel.loadUserProfilesResult.observe(viewLifecycleOwner, Observer {
this.profiles_view_pager.setCurrentItem(1, false)
})https://stackoverflow.com/questions/10247117
复制相似问题