按下“主页”按钮并等待后,Fragment中的类成员变为空 - java

问题描述
我正在编写的应用程序具有3个片段。当我按下“搜索”按钮时,“主要片段活动”有一个带有“搜索”按钮的“搜索框”,以下功能称为:

Fragments.values()[tabControl.getCurrentItem()].getFragment().search(tv.getText().toString(), MainActivity.this.getApplicationContext());

一切正常,直到我按HOME按钮等待30分钟并重新启动应用程序,之后按FragmentYellowPages中的Search按钮。

lvYellowPages.setVisibility(View.VISIBLE);

因为在这种情况下lvYellowPages为null,但是在日志中我可以看到onCreateView函数已被调用。您能帮我吗,我可以与您分享代码。

FragmentPagerAdapter

public class FragmentAdapter extends FragmentPagerAdapter {

    Fragments[] mFragments;

    public FragmentAdapter(FragmentManager fm) {
        super(fm);
    
        mFragments = Fragments.values();
    }

    public enum Fragments {
    
        Favorites(App.getStringByResId(R.string.favorites), new FragmentFavorites()),
        Categories(App.getStringByResId(R.string.categories), new FragmentCategories()),
        YellowPages(App.getStringByResId(R.string.yellow_pages), new FragmentYellowPages());
    
        Fragments(String title, BaseListFragment fragment) {
            this.mTitle = title;
            this.mFragment = fragment;
        }
        
        String mTitle;
        BaseListFragment mFragment;
    
        public String getTitle() {
            return mTitle;
        }
            
        public BaseListFragment getFragment() {
            return mFragment;
        }
    };

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragments[position].getTitle();
    }

    @Override
    public Fragment getItem(int position) {
        return mFragments[position].getFragment();
    }

    @Override
    public int getCount() {
        return mFragments.length;
    }
};

清单片段

public class FragmentYellowPages extends BaseListFragment {

    final static String TAG = FragmentYellowPages.class.getSimpleName();

    ListView lvYellowPages;
    TextView tvInfo;
    SimpleCursorAdapter scAdapter;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    
        View yellowPagesView = inflater.inflate(R.layout.fragment_yellow_pages, container, false);
    
        Log.i(TAG, "onCreateView( )");
    
        tvInfo = (TextView) yellowPagesView.findViewById(R.id.tvYellowPagesInfo);
        lvYellowPages = (ListView) yellowPagesView.findViewById(android.R.id.list);
    
        return yellowPagesView;
    
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        Log.i(TAG, "onCreate( )");
    
        setRetainInstance(true);

    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    
        Log.i(TAG, "onActivityCreated( )"); 
    }


    @Override
    public void onResume() {    
        super.onResume();
    
        Log.i(TAG, "onResume( )");      
    }

    void updateAdapterOnSearch(final String tts, final String lang) {
        Log.i(TAG, String.format("updateAdapterOnSearch(%s, %s)", tts, lang));
    
        /* Show "Yellow Pages" list view and hide Info text view. */
        lvYellowPages.setVisibility(View.VISIBLE);
        tvInfo.setVisibility(View.GONE);
        /* Some code .... */
    }

    @Override
    public void search(final String tts, final Context context) {
        Log.i(TAG, String.format("search(%s)", tts));
    
        /* If user search for the text. */ 
        if (tts != null && tts.length() != 0) {
            updateAdapterOnSearch(tts, lang);
        }
    }

};

片段布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffc8"
    android:tag="FRAGMENT_YELLOW_PAGES_TAG" >

    <ListView android:id="@android:id/list"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:visibility="gone"
              android:background="#ffffc8"/>

    <TextView android:id="@+id/tvYellowPagesInfo"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_centerHorizontal="true"
              android:layout_centerVertical="true"
              android:gravity="center"
              android:padding="5dp"
              android:text="@string/no_companies_were_found"
              android:visibility="gone"/>

</RelativeLayout>

参考方案

很难找出确切的问题,但是我几乎可以肯定,这与您为ViewPager构建适配器的方式有关。

一切正常,直到我按HOME按钮等待30分钟
并在重新启动应用程序后,按
FragmentYellowPages片段应用程序崩溃

由于Activity位于后台(并且显然已被杀死),因此当返回到前台时,它将重新创建其内容。此时,ViewPager将重建其内容,但是其适配器将不会调用getItem(),因为它具有所有数据来自行重建先前的片段。因此,您将获得两个片段版本,一个是ViewPager中当前可见的片段(因此您会看到onCreateView()被调用),另一个是enum中的片段。这些来自enum的片段没有绑定到Activity,因此不会为它们运行整个回调堆栈,因此不会调用onCreateView(),这将使您的lvYellowPages ListView null

顺便说一句,这是我第一次看到在enum中构建的适配器的片段,我建议您避免这种情况。

解决的办法是不在外部引用ViewPager的片段。使getItem()方法返回一个Fragment实例,并且如果您需要访问这些片段,则有一些方法可以将ViewPager的片段存储在列表/枚举中(快速搜索stackoverflow会显示一个与此相关的问题):

@Override
public Fragment getItem(int position) {
    switch (position) {
    case 0:
       return new FragmentFavorites();
    case 1:
       return new FragmentCategories();
    case 2:
       return new FragmentYellowPages();
    }
    return null;
}

@Override
public int getCount() {
    return 3;
}

也:

setRetainInstance(true);

我不会用这个。保留ViewPager使用的片段是没有意义的(因为我不认为您打算将其移动到其他位置),并且也不会保护您免受活动在后台被杀死的困扰。

Android:如何为wrap_content设置高度动画? - java

我需要使用ValueAnimator来使用户拖动特定视图时出现自定义“放置字段”。 (我想将字段从gone, height = 0更改为visible, height = wrap_content)。我已经尝试过以下问题的解决方案:How to animate to wrap_content?当我在单个TextView上使用它时,答案就起作用了,但是当我尝试…

为什么我的应用在启动时总是崩溃-Android - java

刚刚遵循了有关如何制作按钮和活动的youtube指南。我按照他的代码减小字体大小,并且在启动时一直崩溃。有人知道为什么吗?public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { su…

android-android studio模拟器中的SSL问题,在手机上可以正常工作 - java

我有一个可以通过https调用网络服务的应用程序。当我在手机上运行apk时,效果很好。但是,在模拟器中,所有通过POST的SSL请求均失败,并显示以下信息: 读取错误:ssl = 0xb402be00:SSL库失败,通常是一个协议 错误 错误:100c50bf:SSL例程:ssl3_read_bytes:NO_RENEGOTIATION(外部/无聊的sl /…

纵向模式下带有图标和文字的ActionBar - java

无论尝试如何,我似乎都无法在操作栏中的菜单项上以肖像模式工作时获得图像和文本。我什至试图强迫android纵向我的XML: <item android:id="@+id/menu_save" android:icon="@drawable/content" android:orderInCategory=…

不需要选择回收站查看项目 - java

viewHolder.optiontxt1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { viewHolder.optiontxt1.setCompoundDrawablesWithIntrinsicBounds(R.dra…