- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
尝试将片段动态添加到Android ViewPager中的不同页面。
动态地将片段添加到片段列表的末尾可以很好地工作,但是尝试将其添加到下一个插槽(当前可见页面之后的看不见的页面)。我尝试将其添加到片段的数组列表中,并使用notifyDataSetChanged,并尝试在将每个片段设置为上一个项目之后在每个片段上使用set。
编辑:更新的代码
class MainPagerAdapter extends FragmentPagerAdapter {
public MainPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public PageFragment getItem(int position) {
return PageFragment.newInstance(Datamart.getInstance().getURLs().get(position));
}
@Override
public int getCount() {
return Datamart.getInstance().getURLs().size();
}
@Override
public int getItemPosition(Object object) {
PageFragment pageFragment = (PageFragment) object;
for ( int i = 0; i < getCount(); i++ ) {
if ( pageFragment.getURL().equals( Datamart.getInstance().getURLs().get(i) ) ) {
return i;
}
}
return POSITION_NONE;
}
}
public class Datamart {
static Datamart instance;
private ArrayList<String> URLs;
private MainPagerAdapter mainPagerAdapter;
private ViewPager viewPager;
public Datamart() {
URLs = new ArrayList<>();
}
public static Datamart getInstance() {
if (instance == null) {
instance = new Datamart();
}
return instance;
}
public MainPagerAdapter getMainPagerAdapter() {
return mainPagerAdapter;
}
public void setMainPagerAdapter(MainPagerAdapter mainPagerAdapter) {
this.mainPagerAdapter = mainPagerAdapter;
}
public ViewPager getViewPager() {
return viewPager;
}
public void setViewPager(ViewPager viewPager) {
this.viewPager = viewPager;
}
public void addToEnd( String URL ) {
URLs.add(URL);
mainPagerAdapter.notifyDataSetChanged();
}
public void addNext( String URL ) {
URLs.add(viewPager.getCurrentItem() + 1, URL);
mainPagerAdapter.notifyDataSetChanged();
}
public ArrayList<String> getURLs() {
return URLs;
}
public void setURLs(ArrayList<String> URLs) {
this.URLs = URLs;
}
}
最佳答案
ViewPager
尽最大努力尝试跟踪所有片段的去向,但由于将片段插入中间而没有告知,您感到困惑。
让我们做一个例子。假设您有两页,那么您将显示第一页,第二页是右侧的屏幕外页。您第一页有fragment0
,第二页有fragment1
。
首先,请记住,由于ViewPager
正在左右管理屏幕外页面,因此它已经认为知道第二个页面片段是什么,即fragment1
。
在现有页面片段之间插入片段时,ViewPager
不会立即询问您第二个位置的片段,而是要询问第二个位置的片段是否已更改。
这是getItemPosition()
的来源。您没有在getItemPosition()
中实现FragmentPagerAdapter
,所以getItemPosition()
的默认行为是返回POSITION_UNCHANGED
。 (如您所见,这就是为什么在末尾添加片段不会导致错误的原因。)
因此,当您调用notifyDataSetChanged()
时,ViewPager
调用了getCount()
并看到有两个页面,而不是两个页面。然后,它为第0页和第1页(它知道的页面)调用getItemPosition()
,并且您的默认实现告诉它什么都没有改变。
但是确实发生了变化,您在两个现有页面的中间插入了一个页面/片段。 ViewPager
询问您第二页是否更改,并且您的getItemPosition()
应该返回了2
而不是POSITION_UNCHANGED
。
现在,由于您的getCount()
返回了3
而不是2
,因此ViewPager
知道末尾有一个新页面,它不知道,因此它调用getItem()
来获取新片段。
这是发生错误的地方。您的getItem()
方法在第3页返回了fragment1
,并且ViewPager
阻塞了,因为您将它已经知道的片段交给了它。具体来说,它将片段的标签用于一些内部管理。它在页面的容器ID和项目位置(页面编号)之外创建标签。因此,在任何给定时间,它都期望(a)标签为空,或者(b)标签将与根据容器ID和商品位置已经计算出的值相同。这些条件都不是正确的,所以这就是抛出IllegalStateException
的原因。
那么如何解决这个问题?
您实现一个做正确的事情的getItemPosition()
。调用getItemPosition()
时,将扫描片段列表,找到匹配的片段时,将返回片段的索引。如果删除了一个片段,使得列表中没有匹配的片段,则返回POSITION_NONE
告诉ViewPager
应该删除该页面。 ViewPager
然后将调用您的getItem()
方法以获取新页面。这样,ViewPager
可以始终与适配器保持同步。
编写FragmentPagerAdapter
时,我什至不使用模型中的片段。如果我正在编写您的适配器,那么我将只有一个URL列表,因为看起来每个页面/片段都有其自己的唯一URL。
我还将在fragment类上实现一个getUrl()
方法,以获取用于创建该fragment的URL。
因此,对于getItemPosition()
,我将在传入的片段上调用getUrl()
,然后在适配器的列表中搜索该URL。然后,我将返回列表中URL的索引,如果不存在,则返回POSITION_NONE
。
然后在getItem()
中,我将使用传入的列表位置处的URL实例化一个新片段。我的规则是,直到ViewPager
通过调用getItem()
专门请求它之前,我才不会实例化一个片段。
这样,只有ViewPager
会访问这些片段,而我不会遇到这些类型的问题。
另外,在ViewPager
调用startUpdate()
到调用finishUpdate()
的时间之间,请勿对适配器模型进行任何更改。这就是ViewPager
告诉适配器它在确定所有页面片段的去向的“关键部分”中的方式。PagerAdapter
可以忍受。在getCount()
,getItemPosition()
和getItem()
方法中放入一些调试日志,以便您了解ViewPager
如何使用适配器管理其页面。
关于java - 接下来在已经运行的Android ViewPager中插入新的Fragment,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30282516/
我有一个模型,我想为其检索下一条记录和上一条记录。我想通过模型上的 named_scope 来执行此操作,并且还将要返回的下一个/上一个记录的 X 数作为参数传入。 例如,假设我有 5 条记录: 记录
我有以下数据框: print(df) day month year quantity 6 04 2018 10 8
我在这个网站上看到过这样的问题;但他们只是提供生日数据而不提供计数例如:mysql query to get birthdays for next 10 days SQL Select Upcomin
我有以下数据框: print(dd) dt_op quantity product_code 20/01/18 1 613 21/01/18 8
Julia 中的迭代可以通过实现具有 3 个函数的迭代接口(interface)来为新定义的类型实现:start , next , done 我在这些函数的末尾没有看到感叹号,所以根据我对 julia
我正在阅读 clojure 中关于 rest 与 next 的解释。据我了解,它分解为 next 评估/实现序列的尾部,知道它是否应该返回nil,而rest总是返回序列,所以它更懒。 但是,我不明白的
早上好 我有以下数据框: a = [1,2,3,4,5,6] b = pd.DataFrame({'a': a}) 我想创建一个列,对“a”列的下“n”行求和,包括 a 的现值;我试过: n =
编写一个可以迭代任何可迭代对象的通用函数,返回现在,下一对。 def now_nxt(iterable): iterator = iter(iterable) nxt = iterat
我正在尝试显示接下来 5 分钟的剩余时间(捕捉到当前时间的完整 5 分钟,例如 15:05、15:10..) 我能够在下一个小时(而不是分钟)的剩余时间内实现相同的目标: function sec
我想捕获用户在接下来的 2 小时内执行的步数。 这就是我要说的。 Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.H
我有一个如下所示的 DataFrame: ds y 0 2017-02-07 0.154941 1 2017-02-08 0.110595 2
我想通过集合分析计算过去 2 个值的总和 + 当前值 + 接下来的 2 个值。 无论是否使用集合分析,它都按预期工作。无论有无集分析 ( "{}" ),它都按预期工作。但是当缩放时,图形的值会相应地发
我有一个大数据集,低于训练和测试数据集 train_data是从2016-01-29到2017-12-31 head(train_data) date Date_t
另一个“如何删除上一个、下一个、完成按钮”-您可能会想的问题。实际上不是。我对此进行了相当深入的研究,并尝试了不同的方法,但似乎没有任何方法或解决方案能真正做到这一点。下面提到和显示的所有解决方法(就
我是一名优秀的程序员,十分优秀!