cre*_*not 5 java android android-configchanges android-fragments
呵呵,这是一个艰难的。至少,我是这么认为的……澄清一下:
搜索互联网后(使用谷歌),我没有找到我的问题的任何答案。
我发现的一切都是关于人们onClickListener为他们View的错误设置的。我想在我的情况下这是同样的问题,但没有其他问题与我的匹配。
这似乎是同样的问题......它没有答案。
我有三只Fragment的成立连同ViewPager我的AppCompatActivity。
viewPager = (ViewPager) findViewById(R.id.main_view_pager);
viewPager.setAdapter(new SectionsPagerAdapter(getSupportFragmentManager()));
Run Code Online (Sandbox Code Playgroud)
由SectionsPagerAdapter.
public class SectionsPagerAdapter extends FragmentPagerAdapter {
SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return MainTextHolder.newInstance(tabIndicatorOnClick);
case 1:
return PostWriter.newInstance(tabIndicatorOnClick);
case 2:
return TopPage.newInstance(tabIndicatorOnClick);
default:
return Error.newInstance();
}
}
@Override
public int getCount() {
return 3;
}
// ... more methods
}
Run Code Online (Sandbox Code Playgroud)
在每一个Fragment的我有一些内容外加一个自定义TabIndicator。
(以下xml文件是我View的指标文件)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<View
android:id="@+id/fragment_divider_one"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:tag="one" />
<View
android:id="@+id/fragment_divider_two"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:tag="two" />
<View
android:id="@+id/fragment_divider_three"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:tag="three" />
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
然后我在's方法中OnClickListener为每个View's (dividers)设置了一个。在已经在准备我的,我也实例化了我,这样我可以改变当前(/片)。FragmentonCreateView(LayoutInflater inflater, ViewGroup Bundle savedInstanceState)OnClickListenerActivityViewPagerItemFragment
private final View.OnClickListener tabIndicatorOnClick = new View.OnClickListener() {
@Override
public void onClick(View view) {
if (view.getTag().toString().equals("one"))
viewPager.setCurrentItem(0, true); // second argument for smooth transition
else if (view.getTag().toString().equals("two"))
viewPager.setCurrentItem(1, true);
else if (view.getTag().toString().equals("three"))
viewPager.setCurrentItem(2, true);
}
};
Run Code Online (Sandbox Code Playgroud)
我通过将其放入我的方法OnClickListener中将其传递给Fragment's newInstance(View.OnClickListener tabIndicatorOnClick)。
这是针对其中一个片段的。其他的都是一样的!
public static MainTextHolder newInstance(View.OnClickListener tabIndicatorOnClick) {
MainTextHolder fragment = new MainTextHolder();
Bundle args = new Bundle();
fragment.putIndicatorTabIndicatorOnClick(tabIndicatorOnClick);
fragment.setArguments(args);
fragment.setRetainInstance(true);
return fragment;
}
Run Code Online (Sandbox Code Playgroud)
我的putIndicatorTabIndicatorOnClick(View.OnClickListener tabIndicatorOnClick)方法是 a Voidin an Interface。它只适用OnClickListener于Class( Fragment)。
@Override
public void putIndicatorTabIndicatorOnClick(View.OnClickListener tabIndicatorOnClick) {
this.tabIndicatorOnClick = tabIndicatorOnClick;
}
Run Code Online (Sandbox Code Playgroud)
是的,它确实。它工作得很好......直到ConfigurationChange发生。就我而言,我通过更改方向对其进行了测试。
之后发生的事情ConfigurationChange是一切正常。的OnClickListener被施加到所有 View的在所有 Fragment的,但在tabIndicatorOnClick OnClickListener是一个空对象引用在第二和第三Fragment。
所以在PostWriter和TopPage中,无论出于何种原因,都没有真正的OnClickListeneron View。但它变得更好:在MainTextHolder Fragment的tabIndicatorOnClick不是null object reference,但它不会改变ViewPager的Item了。它运行代码,但不滚动Tab.
当开启“不保留活动” IND开发人员选项设备和退出应用,所有OnClickListener的都是null object references。甚至那些在MainTextHolder.
之后,ConfigurationChange将OnClickListener被传递到我的第一次Fragment,但没有正常工作,并在剩余Fragment的它甚至不是通过/年null object reference。
可以通过销毁Activity然后重新加载来复制该问题。
......我不知道出了什么问题。我希望我的问题结构正确。
最小SDK版本:14
目标SDK版本:25
我已经有一个SpringIndicator我ViewPager。这没有功能,OnClickListener所以我添加了我自己的具有所需功能的“叠加”指标OnClick。我也喜欢它的外观,但如果您能给我一个更好的解决方案TabIndicator,我也很乐意将其作为答案。
我遇到了xml :onClick多次将方法放入属性的解决方案,但为此我需要OnClickListener为每个都创建相同的方法,Fragment这不是真正的好方法,它也不能解决我的问题,而是一种解决方法。- 我需要将 传入ViewPagermyFragment然后调用该方法xml,正如我所说,这只是另一种方式,而不是我喜欢的方式。另外我不知道它是否有效。我很可能会测试它。
其他OnClickListener的在Fragment仍然正常工作。所以正如我所说的,问题在于OnClickListener它本身无法正常工作/成为null object reference.
首先,写得很好,详细描述了问题。StackOverflow 上的很多提问者都可以借鉴这个问题阐明问题的能力。
这个错误似乎来自于没有考虑片段生命周期的变化。在 ViewPager 内部,Fragments 将经历各种状态,包括暂时离开屏幕时隐藏和显示,如果离开屏幕且系统释放内存则暂停和恢复,如果 Android 系统决定保存实例状态则最终创建和销毁您的活动(例如配置更改)。在后一种情况下,Android 将尝试从 ViewPager 中保存的实例状态恢复 Fragments 的状态。由于您的片段无法保存View.OnClickedListener它们在参数中传递的内容,因此它们null在恢复时最终会得到一个指针,这会导致您的错误。
要修复该错误,我建议您不要将View.OnClickedListener作为参数传递给 Fragments。相反,OnClickListener通过 Activity 中的公共方法将 暴露给 Fragment,并让 Fragments 在其onResume(). View.OnClickedListener这样您就可以保证片段在处于恢复状态时都会有一个引用。所以你onResume()可能看起来像这样:
@Override
public void onResume() {
OnClickListener onClickListener = ((MyActivity) getActivity).getOnClickListener();
putIndicatorTabIndicatorOnClick(onClickListener);
Run Code Online (Sandbox Code Playgroud)
}
既然你已经在 中设置了它onResume(),你应该在 中删除它onPause():
@Override
public void onPause() {
//set the onClickListener to null to free up the resource
}
Run Code Online (Sandbox Code Playgroud)
使用onResume()和onPause()像这样从侦听器中释放资源是开发人员指南中推荐的方法。
当然,您必须确保您的 Activity 也通过检查保存的状态onCreate(Bundle savedInstanceState)并适当地恢复它来处理其自己的生命周期。
请注意,可以通过多种方式触发保存实例状态和恢复:
您将能够使用其中一种方法来确定是否正确处理了 Activity 和 Fragment 的生命周期。
| 归档时间: |
|
| 查看次数: |
632 次 |
| 最近记录: |