在片段中的ConfigurationChange之后,onClickListener无法正常工作

时间:2017-01-08 00:34:29

标签: java android android-fragments android-configchanges

简介

嗯,这是一个强硬的。至少,这么认为...... 澄清事情:

  

在搜索互联网(使用Google)后,我没有找到任何问题的答案。

我发现的一切都是关于为onClickListener错误设置View的人。我想在我的情况下这是同样的问题,但没有其他问题与我的相符。

This似乎是同样的问题......它没有答案。

设置

我在Fragment中设置了三个ViewPagerAppCompatActivity

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文件是我的指标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>

然后我为OnClickListener View方法中的每个Fragment(分隔符)设置了onCreateView(LayoutInflater inflater, ViewGroup Bundle savedInstanceState)OnClickListener已在我Activity中准备ViewPager,我也会实例化Item,以便我可以更改当前的Fragment 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

我将Fragment传递给我的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; } 传递给putIndicatorTabIndicatorOnClick(View.OnClickListener tabIndicatorOnClick)

  

这是针对其中一个片段的。它与其他人完全相同!

Void

我的Interface方法是OnClickListener中的Class。它只是将Fragment应用于@Override public void putIndicatorTabIndicatorOnClick(View.OnClickListener tabIndicatorOnClick) { this.tabIndicatorOnClick = tabIndicatorOnClick; } ConfigurationChange)。

ConfigurationChange

是否有效

是的, 。它工作得很好......直到OnClickListener发生。在我的情况下,我使用更改方向来测试它。

问题

View之后发生的事情是一切正常。 Fragment已应用于所有 tabIndicatorOnClick中的所有 OnClickListener Fragment OnClickListener是第二个和第三个View中的空对象引用

所以在 PostWriter TopPage 中,MainTextHolder上的Fragment甚至还不是tabIndicatorOnClick永恒的理由。但它变得更好:在null object reference ViewPager Item不是Tab,但它不会更改OnClickListener&#39; s {{1不再了。它运行代码,但不会滚动null object references

开启&#34;不要保留设备的活动&#34; ind 开发人员选项并离开应用,所有{{1} } {是MainTextHolder。即使是那些ConfigurationChange

摘要

OnClickListener Fragment传递到我的第一个Fragment之后,但它无法正常工作且剩余的null object reference&#39} 它甚至没有通过/ Activity

可以通过销毁ViewPager然后重新加载来复制问题

最后......

......我不知道出了什么问题。我希望我能正确地构建我的问题。

可能感兴趣

  

minSdkVersion 14

     

targetSdkVersion 25

我的OnClickListener已经有SpringIndicator了。这不包含OnClick,因此我添加了自己的&#34;重叠&#34; 指标,这些指标具有所需的TabIndicator功能。我也喜欢它的外观,但如果你能为我xml提供更好的解决方案,我也很乐意将其作为答案。

我遇到了将该方法多次放入:onClick OnClickListener属性的解决方案,但为此,我需要为每个Fragment创建相同的ViewPager这不是真正的好方法,它也不是解决我的问题,而是解决它的方法。 - 我需要将Fragment传递给我的xml,然后从OnClickListener调用该方法,正如我所说,这只是另一种方式,而不是我喜欢的方式做到这一点。我也不知道它是否有效。我很可能会测试它。

Fragment中的其他OnClickListener仍可正常使用。正如我所说,问题在于null object reference本身无法正常工作/成为{{1}}。

1 个答案:

答案 0 :(得分:2)

首先,编写详细的问题描述做得很好。 StackOverflow上的许多提问者都可以从这个问题的能力中学习表达问题。

这个错误似乎来自于不考虑Fragment生命周期的变化。在ViewPager中,Fragments将通过各种状态,包括隐藏和显示在临时屏幕外时,如果它们在屏幕外并且系统释放内存,则暂停和恢复,如果Android系统决定保存实例状态,则最终创建和销毁您的活动(例如来自配置更改)。在后一种情况下,Android将尝试从ViewPager中保存的实例状态恢复Fragments的状态。由于你的Fragments没有办法保存它们在参数中传递的View.OnClickedListener,因此当它们被恢复时会导致null指针,这会导致你的错误。

要修复错误,我建议您不要将View.OnClickedListener作为参数传递给Fragments。相反,通过您的Activity中的公共方法将OnClickListener公开给您的片段,并让片段自己在onResume()中获取。这样,您可以保证片段在处于恢复状态时将引用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也处理自己的生命周期。

请注意,可以通过多种方式触发保存实例状态和恢复:

  1. 配置状态更改(例如旋转手机并导致活动以横向而非人像显示
  2. 设备内存不足(例如,如果最近的应用中有大量活动)
  3. 启用开发人员选项/不要保留活动并使用主页将您的应用程序放入最近的应用程序中,然后导航回您的应用程序。
  4. 您将能够使用这些方法之一来确定您是否正确处理了活动和碎片的生命周期。