java – onClickListener在片段中的ConfigurationChange之后无法正常工作(正确)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – onClickListener在片段中的ConfigurationChange之后无法正常工作(正确),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含6293字,纯文字阅读大概需要9分钟。
内容图文
![java – onClickListener在片段中的ConfigurationChange之后无法正常工作(正确)](/upload/InfoBanner/zyjiaocheng/781/61e9e21d63334330bfa81c98ee8766dd.jpg)
介绍
嗯,这是一个艰难的.至少,我想是这样的……
澄清事情:
I did not find any answers to my question after searching the internet (using Google).
我发现的一切都是关于人们为他们的View错误设置onClickListener的.我想在我的情况下这是同样的问题,但没有其他问题与我的相符.
This似乎是同样的问题……它没有答案.
建立
我在AppCompatActivity中设置了三个Fragment和一个ViewPager.
viewPager = (ViewPager) findViewById(R.id.main_view_pager);
viewPager.setAdapter(new SectionsPagerAdapter(getSupportFragmentManager()));
由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
}
在每个Fragment中我都有一些内容和一个自定义的TabIndicator.
(以下xml文件是指针的视图)
<?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>
然后我在Fragment的onCreateView(LayoutInflater inflater,ViewGroup Bundle savedInstanceState)方法中为每个View(分隔符)设置了一个OnClickListener. OnClickListener已经在我的Activity中准备好了,我还实例化了我的ViewPager,以便我可以更改当前的Item(Fragment / tab).
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);
}
};
我通过将OnClickListener放入我的newInstance(View.OnClickListener tabIndicatorOnClick)方法将其传递给Fragment.
This is for one of the fragments. It is identical for the others!
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;
}
我的putIndicatorTabIndicatorOnClick(View.OnClickListener tabIndicatorOnClick)方法是一个接口中的Void.它只是将OnClickListener应用于Class(Fragment).
@Override
public void putIndicatorTabIndicatorOnClick(View.OnClickListener tabIndicatorOnClick) {
this.tabIndicatorOnClick = tabIndicatorOnClick;
}
它有用吗
是的,它确实.它工作得很好……直到ConfigurationChange发生.在我的情况下,我通过改变方向测试它.
问题
在ConfigurationChange之后会发生一切正常的事情. OnClickListener应用于所有Fragment中的所有View,但tabIndicatorOnClick OnClickListener是第二个和第三个片段中的空对象引用.
所以在PostWriter和TopPage中,View上的OnClickListener甚至没有任何理由.但它变得更好:在MainTextHolder片段中,tabIndicatorOnClick不是空对象引用,但它不再更改ViewPager的Item.它运行代码,但不会滚动Tab.
当打开“不要保持活动”对设备的开发者选项并离开应用程序时,所有OnClickListener都是空对象引用.甚至是MainTextHolder中的那些.
摘要
在ConfigurationChange之后,OnClickListener被传递到我的第一个Fragment中,但是它没有正常工作,并且在剩余的Fragment中它甚至没有传递/ null对象引用.
可以通过销毁Activity然后重新加载来复制该问题.
到底…
……我不知道出了什么问题.我希望我能正确地构建我的问题.
可能有意义
minSdkVersion: 14
targetSdkVersion: 25
我的ViewPager上已有SpringIndicator.这没有OnClickListener,所以我添加了自己的“重叠”指标,它们具有所需的OnClick功能.我也喜欢它的外观,但如果你能为我的TabIndicator提供更好的解决方案,我也很乐意将它作为答案.
我遇到了将方法多次放入xml:onClick属性的解决方案,但为此,我需要为每个Fragment创建相同的OnClickListener,这不是很好的方式,它也没有解决我的问题,但是绕过它. – 我需要将ViewPager传递给我的Fragment,然后从xml调用该方法,正如我所说,这只是另一种方式,而不是我喜欢的方式.我也不知道它是否有效.我很可能会测试它.
片段中的其他OnClickListener仍然可以正常工作.所以正如我所说,问题在于OnClickListener本身不能正常工作/是一个空对象引用.
解决方法:
首先,为编写问题的详细描述做得很好. StackOverflow上的许多提问者都可以从这个问题的能力中学习表达问题.
这个错误似乎来自于不考虑Fragment生命周期的变化.在ViewPager中,Fragments将通过各种状态,包括隐藏和显示在临时屏幕外时,如果它们在屏幕外并且系统释放内存,则暂停和恢复,如果Android系统决定保存实例状态,则最终创建和销毁您的活动(例如来自配置更改).在后一种情况下,Android将尝试从ViewPager中保存的实例状态恢复Fragments的状态.由于您的Fragments无法保存View.OnClickedListener,因此它们在参数中传递,它们在恢复时最终会返回一个空指针,这会导致您的错误.
要修复错误,我建议您不要将View.OnClickedListener作为参数传递给Fragments.相反,通过Activity中的公共方法将OnClickListener暴露给Fragments,让Fragments在onResume()中自己获取它.这样,您可以保证Fragments在处于恢复状态时将具有对View.OnClickedListener的引用.所以你的onResume()可能看起来像这样:
@Override
public void onResume() {
OnClickListener onClickListener = ((MyActivity) getActivity).getOnClickListener();
putIndicatorTabIndicatorOnClick(onClickListener);
}
由于您已在onResume()中设置它,因此应在onPause()中将其删除:
@Override
public void onPause() {
//set the onClickListener to null to free up the resource
}
使用像这样的onResume()和onPause()来从监听器中释放资源是开发人员指南中推荐的方法.
当然,您必须通过检查onCreate(Bundle savedInstanceState)中的已保存状态并相应地恢复它来确保您的Activity也处理自己的生命周期.
请注意,可以通过多种方式触发保存实例状态和恢复:
>配置状态更改(例如旋转手机并使活动以横向而非纵向显示
>设备内存不足(例如,如果最近的应用程序中有大量活动)
>打开开发者选项/不要保留活动并使用home将应用程序放在最近的应用程序中,然后导航回应用程序.
您将能够使用这些方法之一来确定您是否正确处理了活动和碎片的生命周期.
内容总结
以上是互联网集市为您收集整理的java – onClickListener在片段中的ConfigurationChange之后无法正常工作(正确)全部内容,希望文章能够帮你解决java – onClickListener在片段中的ConfigurationChange之后无法正常工作(正确)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。