【问题标题】:Fragment getActivity is null after on onActivityCreated with viewPager在 onActivityCreated 使用 viewPager 之后,片段 getActivity 为空
【发布时间】:2017-04-14 22:56:38
【问题描述】:

我有一个带有 5 个片段的 viewpager 的 tabLayout,我不知道为什么,但是在第五个片段中,当我使用 getActivity() 时,即使在 onActivityCreated 之后它返回 null,而在其他片段中,我在 onCreateView 中使用它并且它可以工作很好。

我的第五个片段:

public  class SettingsFragment extends Fragment {

private static final String ARG_SECTION_NUMBER = "section_number";
private TextView name,losed_bg,winned_bg,played_bg;
private DatabaseReference mdatabase;
private FirebaseAuth mAuth;
private CircleImageView userpic;
private static final int CAMERA=0,GALLERY=1;
private Typeface font;
private Button logout;
private ProgressBar loading;
private ImageView edit_image;
private EditText edit_text;
private AlertDialog.Builder getImageFrom;

public SettingsFragment() {
}

public static SettingsFragment newInstance(int sectionNumber) {
    SettingsFragment fragment = new SettingsFragment();
    Bundle args = new Bundle();
    args.putInt(ARG_SECTION_NUMBER, sectionNumber);
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    mdatabase= FirebaseDatabase.getInstance().getReference().child("USERS").child(mAuth.getCurrentUser().getUid());

    mdatabase.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            name.setText(dataSnapshot.child("name").getValue(String.class));

            if(dataSnapshot.hasChild("losed")){

                   //CRASH String spannable = getActivity().getString(R.string.settings_losed)+" "+String.valueOf(dataSnapshot.child("losed").getValue(Integer.class));
                    losed_bg.setText(spannable);
            }
            else{

                    String spannable =getActivity().getString(R.string.settings_losed)+" "+String.valueOf(0);
                    losed_bg.setText(spannable);

            }

            if(dataSnapshot.hasChild("winned")){
                    String spannable = getActivity().getString(R.string.settings_winned)+" "+String.valueOf(dataSnapshot.child("winned").getValue(Integer.class));
                    winned_bg.setText(spannable);

            }
            else{
                    String spannable = getActivity().getString(R.string.settings_winned) + " " + String.valueOf(0);
                    winned_bg.setText(spannable);

            }

            if(dataSnapshot.hasChild("played")){
                    String spannable = getActivity().getString(R.string.settings_played) + " " + String.valueOf(dataSnapshot.child("played").getValue(Integer.class));
                    played_bg.setText(spannable);

            }
            else{
                    String spannable = getActivity().getString(R.string.settings_played) + " " + String.valueOf(0);
                    played_bg.setText(spannable);

            }
            if(dataSnapshot.child("profile_pic").getValue(String.class)!=null) {

                getImage();
            }
            else{
                loading.setVisibility(View.INVISIBLE);
                userpic.setVisibility(View.VISIBLE);
                userpic.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        getImageFrom.show();

                    }
                });
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

}

}

我来了

java.lang.IllegalStateException: Fragment SettingsFragment{3ee8ade} not attached to Activity

以及我设置 tabLayout 的活动

 public class SectionsPagerAdapter extends FragmentPagerAdapter {

    public SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {

        // getItem is called to instantiate the fragment for the given page.
        // Return a PlaceholderFragment (defined as a static inner class below).
        switch (position){
            case 0:
                return MainFragment.newInstance(0);
            case 1:
                return GamesFragment.newInstance(0);
            case 2:
                return OfflineFragment.newInstance(0);
            case 3:
                return FactoryFragment.newInstance(0);
            case 4:
                return SettingsFragment.newInstance(0);
        }

        return MainFragment.newInstance(position + 1);
    }

    @Override
    public int getCount() {

        return 5;
    }

    @Override
    public CharSequence getPageTitle(int position) {

        return null;
    }
}

mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
                // Set up the ViewPager with the sections adapter.
                mViewPager = (ViewPager) findViewById(R.id.container);
                mViewPager.setAdapter(mSectionsPagerAdapter);
                tabLayout = (TabLayout) findViewById(R.id.tabs);
                tabLayout.setupWithViewPager(mViewPager);

                for (int i = 0; i < tabLayout.getTabCount(); i++) {
                    switch (i){
                        case 0:
                            View view1 = getLayoutInflater().inflate(R.layout.tab_icon_view, null);
                            view1.findViewById(R.id.icon).setBackgroundResource(R.drawable.ic_home_white_48dp);
                            tabLayout.getTabAt(i).setCustomView(view1);
                            break;
                        case 3:
                            View view2 = getLayoutInflater().inflate(R.layout.tab_icon_view, null);
                            view2.findViewById(R.id.icon).setBackgroundResource(R.drawable.factory);
                            tabLayout.getTabAt(i).setCustomView(view2);
                            break;
                        case 1:
                            View view3 = getLayoutInflater().inflate(R.layout.tab_icon_view, null);
                            view3.findViewById(R.id.icon).setBackgroundResource(R.drawable.games_icon);
                            tabLayout.getTabAt(i).setCustomView(view3);
                            break;
                        case 2:
                            View view5 = getLayoutInflater().inflate(R.layout.tab_icon_view, null);
                            view5.findViewById(R.id.icon).setBackgroundResource(R.drawable.nointernet);
                            tabLayout.getTabAt(i).setCustomView(view5);
                            break;
                        case 4:
                            View view4 = getLayoutInflater().inflate(R.layout.tab_icon_view, null);
                            view4.findViewById(R.id.icon).setBackgroundResource(R.drawable.ic_account_circle_white_48dp);
                            tabLayout.getTabAt(i).setCustomView(view4);
                            break;

                    }

                }

【问题讨论】:

  • 哪一行导致 NPE?
  • 第一个用getActivity获取字符串的
  • 改变这个 - return MainFragment.newInstance(position + 1);至此 - 返回 MainFragment.newInstance(position);
  • 请显示导致错误的确切代码而不是描述它。
  • 看代码,说错误的注释

标签: android android-viewpager android-tablayout


【解决方案1】:

将添加侦听器到数据库的代码 (addValueEventListener) 移动到片段的 OnAttach 方法中。根据您使用 ViewPager 的方式,FragmentPagerAdapter 可能会决定“回收”您的片段。因此,当片段与 Activity (OnDetach) 分离时,删除数据库侦听器非常重要。

似乎数据库是一个单例,所以监听器可能会超过你的片段甚至活动。可能会导致一些内存泄漏。所以请记住删除监听器以确保安全。

【讨论】:

  • 谢谢,问题是 ValueEventListener,我在覆盖 onAttach 之前尝试过,但它没有用,因为我没有使用 addListenerForSingleValueEvent。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-15
  • 2013-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-27
  • 2015-05-30
相关资源
最近更新 更多