在片段类成员成为仅次于Home键preSS零等待 [英] Class members in Fragment become null after Home button press and wait

查看:205
本文介绍了在片段类成员成为仅次于Home键preSS零等待的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题说明

应用程序,我写了3个片段。主要片段活动有一个搜索框搜索按钮时,I $上的搜索按钮下方的功能被称为P $ PSS:

<$p$p><$c$c>Fragments.values()[tabControl.getCurrentItem()].getFragment().search(tv.getText().toString(), MainActivity.this.getApplicationContext());

一切正常,好吧,直到我preSS HOME键等待30分钟,然后重新启动应用程序,之后我美元的对 FragmentYellowPages 片段应用程序崩溃p $ PSS搜索按钮行

  lvYellowPages.setVisibility(View.VISIBLE);
 

lvYellowPages 在这种情况下是空的,但在日志中我可以看到 onCreateView 函数被调用。能否请你帮我,我可以与大家分享我的code。


FragmentPagerAdapter

 公共类FragmentAdapter扩展FragmentPagerAdapter {

    片段[] mFragments;

    公共FragmentAdapter(FragmentManager FM){
        超(FM);

        mFragments = Fragments.values​​();
    }

    公共枚举片段{

        收藏夹(App.getStringByResId(R.string.favorites),新FragmentFavorites()),
        分类(App.getStringByResId(R.string.categories),新FragmentCategories()),
        黄页(App.getStringByResId(R.string.yellow_pages),新FragmentYellowPages());

        片段(字符串名称,BaseListFragment片段){
            this.mTitle =称号;
            this.mFragment =片段;
        }

        字符串mTitle;
        BaseListFragment mFragment;

        公共字符串的getTitle(){
            返回mTitle;
        }

        公共BaseListFragment getFragment(){
            返回mFragment;
        }
    };

    @覆盖
    公共CharSequence的getPageTitle(INT位置){
        返回mFragments [位置] .getTitle();
    }

    @覆盖
    公共片段的getItem(INT位置){
        返回mFragments [位置] .getFragment();
    }

    @覆盖
    公众诠释getCount将(){
        返回mFragments.length;
    }
};
 


列表片段

 公共类FragmentYellowPages扩展BaseListFragment {

    最终静态字符串变量= FragmentYellowPages.class.getSimpleName();

    ListView控件lvYellowPages;
    TextView的tvInfo;
    SimpleCursorAdapter scAdapter;

    @覆盖
    公共查看onCreateView(LayoutInflater充气,容器的ViewGroup,捆绑savedInstanceState){

        查看yellowPagesView = inflater.inflate(R.layout.fragment_yellow_pages,集装箱,假);

        Log.i(TAG,onCreateView());

        tvInfo =(TextView中)yellowPagesView.findViewById(R.id.tvYellowPagesInfo);
        lvYellowPages =(ListView控件)yellowPagesView.findViewById(android.R.id.list);

        返回yellowPagesView;

    }

    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);

        Log.i(TAG的onCreate());

        setRetainInstance(真正的);

    }

    @覆盖
    公共无效onActivityCreated(包savedInstanceState){
        super.onActivityCreated(savedInstanceState);

        Log.i(TAG,onActivityCreated());
    }


    @覆盖
    公共无效onResume(){
        super.onResume();

        Log.i(TAG,onResume());
    }

    无效updateAdapterOnSearch(最后弦乐TTS,最后弦乐朗){
        Log.i(TAG,的String.Format(updateAdapterOnSearch(%S,%S),TTS,郎));

        / *显示黄页列表视图和隐藏信息的文本视图。 * /
        lvYellowPages.setVisibility(View.VISIBLE);
        tvInfo.setVisibility(View.GONE);
        / *一些code .... * /
    }

    @覆盖
    公共无效搜索(最后弦乐TTS,最终上下文语境){
        Log.i(TAG,的String.Format(搜索(%S),TTS));

        / *如果用户搜索的文本。 * /
        如果(TTS =空&安培;!&安培;!tts.length()= 0){
            updateAdapterOnSearch(TTS,郎);
        }
    }

};
 

片段布局

 &LT; RelativeLayout的的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    的xmlns:工具=htt​​p://schemas.android.com/tool​​s
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent
    机器人:后台=#ffffc8
    机器人:标签=FRAGMENT_YELLOW_PAGES_TAG&GT;

    &LT; ListView的机器人:ID =@机器人:ID /列表
              机器人:layout_width =match_parent
              机器人:layout_height =WRAP_CONTENT
              机器人:能见度=水涨船高
              机器人:后台=#ffffc8/&GT;

    &LT; TextView的机器人:ID =@ + ID / tvYellowPagesInfo
              机器人:layout_width =WRAP_CONTENT
              机器人:layout_height =WRAP_CONTENT
              机器人:layout_centerHorizo​​ntal =真
              机器人:layout_centerVertical =真
              机器人:重力=中心
              机器人:填充=5DP
              机器人:文本=@字符串/ no_companies_were_found
              机器人:能见度=水涨船高/&GT;

&LT; / RelativeLayout的&GT;
 

解决方案

这是很难找出确切的问题,但我几乎可以肯定它与你建立适配器的方式 ViewPager

  

一切正常,好吧,直到我preSS HOME键等待30分钟   并重新启动应用程序,之后我preSS搜索的按钮   FragmentYellowPages片段应用程序崩溃

由于活动在后台(显然杀死)正在添加回到前台时,它会创建其内容。此时 ViewPager 将重建其内容,但它的适配器不会叫的getItem(),因为它拥有所有的数据重新创建previous片段就可以拥有。所以,你最终有两个版本的片段,那些目前在 ViewPager (让你看到的 onCreateView()被调用)和那些在枚举。从这些片段枚举不依赖于活动等整个回调栈不是为他们跑,所以 onCreateView()将不会被调用,这将使你的 lvYellowPages 的ListView

顺便说一句,这是我第一次看到一个适配器的片段被建在一个枚举,我建议你避免这种情况。

解决方案是不引用的 ViewPager 之外的片段。使的getItem()方法返回一个片段例如,如果你需要访问这些片段有办法做到这一点不存储 ViewPager 的片段列表/枚举等(计算器上快速搜索会显示出这个问题):

  @覆盖
公共片段的getItem(INT位置){
    开关(位置){
    情况下0:
       返回新FragmentFavorites();
    情况1:
       返回新FragmentCategories();
    案例2:
       返回新FragmentYellowPages();
    }
    返回null;
}

@覆盖
公众诠释getCount将(){
    返回3;
}
 

另外:

  setRetainInstance(真正的);
 

我不会用这个。这是没有意义的保留使用的片段 ViewPager (因为我不认为你刨去移动它在其他地方),也将不保您从活动被杀害的背景。

Problem Description

Application which I'm writing has 3 Fragments. Main Fragment Activity has a Search Box with Search button when I press on a Search button the function below is called:

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

Everything works Okay until I press HOME button wait for 30 minutes and relaunch application, after I press Search button in FragmentYellowPages Fragment application crashes on the lines

lvYellowPages.setVisibility(View.VISIBLE);

as lvYellowPages in this case is null, but In a logs I can see that onCreateView function is called. Can you please help me, I can share my code with you.


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;
    }
};


List Fragment

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);
        }
    }

};

Fragment Layout

<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>

解决方案

It's hard to pinpoint the exact problem but I'm almost sure it has to do with the way you built the adapter for the ViewPager.

Everything works Okay until I press HOME button wait for 30 minutes and relaunch application, after I press Search button in FragmentYellowPages Fragment application crashes

As the Activity is in the background(and apparently killed) it will recreate its content when comming back to the foreground. At this point the ViewPager will rebuild its content, but its adapter will not call getItem() as it has all the data to recreate the previous fragments on it own. So you'll end up with two fragment version, the ones currently visible in the ViewPager(so you see the onCreateView() being called) and those that are in the enum. Those fragments from the enum aren't tied to the Activity and so the entire callbacks stack isn't run for them, so onCreateView() will not be called, which will make your lvYellowPages ListView null.

Btw, this is the first time I've seen the fragments of an adapter being built in a enum and I recommend that you avoid this.

The solution is to not reference the fragments of the ViewPager outside. Make the getItem() method return a Fragment instance and if you need to access those fragment there are ways to do it without storing the ViewPager's fragment in lists/enums etc(a quick search on stackoverflow should show you a question about this):

@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;
}

Also:

setRetainInstance(true);

I wouldn't use this. It doesn't make sense to retain a fragment used by a ViewPager(as I don't think you're planing to move it somewhere else) and it will also not protect you from the activity being killed in the background.

这篇关于在片段类成员成为仅次于Home键preSS零等待的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆