IllegalStateException:Fragment null必须是要从实例状态正确重新创建的公共静态类

时间:2016-09-16 13:41:59

标签: java android android-fragments

我有以下问题在谷歌地图的地图中显示一个片段,我需要在Android API 24上工作,就像之前的版本一样工作。 错误在Fragment MapRestaurante的行中:
getFmMain().getSupportFragmentManager().beginTransaction().add(R.id.activitymap, mMapFragment).commit()

如果我使用该行,同样的问题:

getChildFragmentManager().beginTransaction().add(R.id.activitymap, mMapFragment).commit();

Android监视器

> FATAL EXCEPTION: main
Process: com.jungle, PID: 4356
java.lang.IllegalStateException: Fragment null must be a public static class to be  properly recreated from instance state.
  at     android.support.v4.app.BackStackRecord.doAddOp(BackStackRecord.java:435)
  at android.support.v4.app.BackStackRecord.add(BackStackRecord.java:420)
  at com.jungle.MapRestaurant.onCreateView(MapRestaurant.java:72)
  at android.support.v4.app.Fragment.performCreateView(Fragment.java:2080)
  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1108)
  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1290)
  at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:801)
  at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:1638)
  at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:679)
  at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:166)
  at android.support.v4.view.ViewPager.populate(ViewPager.java:1240)
  at android.support.v4.view.ViewPager.populate(ViewPager.java:1088)
  at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:542)
  at com.jungle.MainActivity.Setup(MainActivity.java:167)
  at com.jungle.MainActivity.access$000(MainActivity.java:34)
  at com.jungle.MainActivity$1.onClick(MainActivity.java:61)
  at android.view.View.performClick(View.java:4756)
  at android.view.View$PerformClick.run(View.java:19749)
  at android.os.Handler.handleCallback(Handler.java:739)
  at android.os.Handler.dispatchMessage(Handler.java:95)
  at android.os.Looper.loop(Looper.java:135)
  at android.app.ActivityThread.main(ActivityThread.java:5221)
  at java.lang.reflect.Method.invoke(Native Method)
  at java.lang.reflect.Method.invoke(Method.java:372)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

Clase MainActivity

public class MainActivity extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener {

private ViewPager viewPager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    viewPager = (ViewPager) super.findViewById(R.id.viewpager);

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.setDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);

    Button btnRestaurant = (Button) findViewById(R.id.btnRestaurant);
    btnRestaurant.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            Setup(1);
        }
    });
}

@Override
public void onBackPressed() {
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    } else {
        super.onBackPressed();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.
    int id = item.getItemId();

    if (id == R.id.nav_camera) {
        // Handle the camera action
    } else if (id == R.id.nav_gallery) {

    } else if (id == R.id.nav_slideshow) {

    } else if (id == R.id.nav_manage) {

    } else if (id == R.id.nav_share) {

    } else if (id == R.id.nav_send) {

    }

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}


public void maphotel(View v){
    //Intent intent = new Intent(this,MapRestaurant.class);
    //startActivity(intent);
    Setup(2);
}
public void mapthingsdo(View v){
    //Intent intent = new Intent(this,MapRestaurant.class);
    //startActivity(intent);
    Setup(3);
}

public FrameLayout getFrameContainer(){
   FrameLayout fm = (FrameLayout) findViewById(R.id.fragment_container);
    return fm;
 }
private void Setup(int id){
    ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
    switch (id){
        case 1:
            if(adapter.getmFragmentTitleList().size() > 0) {
                adapter.getmFragmentTitleList().clear();
            }

            adapter.addFragment(new MapRestaurant(this), null);
            adapter.notifyDataSetChanged();

            break;
        case 2:
            if(adapter.getmFragmentTitleList().size() > 0) {
                adapter.getmFragmentTitleList().clear();
            }
            adapter.addFragment(new MapHotel(this), null);
            adapter.notifyDataSetChanged();
            break;
        case 3:
            if(adapter.getmFragmentTitleList().size() > 0) {
                adapter.getmFragmentTitleList().clear();
            }
            adapter.addFragment(new MapThingstodo(this), null);
            adapter.notifyDataSetChanged();
            break;
    }

     viewPager.setAdapter(adapter);
 }


//Clase para visualizar los fragmentos y los tabs en el viewpager
class ViewPagerAdapter extends FragmentStatePagerAdapter {
    private List<Fragment> mFragmentList = new ArrayList<>();
    private  List<String> mFragmentTitleList = new ArrayList<>();

    public List<String> getmFragmentTitleList() {
        return mFragmentTitleList;
    }

    public List<Fragment> getmFragmentList() {
        return mFragmentList;
    }

    public ViewPagerAdapter(FragmentManager manager) {
        super(manager);

    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    public void addFragment(Fragment fragment, String title) {

        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);

    }

    @Override
    public CharSequence getPageTitle(int position) {

        return mFragmentTitleList.get(position);
    }

    //this is called when notifyDataSetChanged() is called
    @Override
    public int getItemPosition(Object object) {
        // refresh all fragments when data set changed
        return   POSITION_NONE;
    }


    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        if (position >= getCount()) {
            FragmentManager manager = ((Fragment) object).getFragmentManager();
            FragmentTransaction trans = manager.beginTransaction();
            trans.remove((Fragment) object);
            trans.commit();

        }

    }

}

}

Fragment MapRestaturant

public class MapRestaurant extends Fragment implements OnMapReadyCallback {

private GoogleMap mMap;
private SupportMapFragment mMapFragment;
static Context contexto;
private MainActivity fmMain;
@SuppressLint("ValidFragment")
public MapRestaurant(MainActivity fmMain) {
    this.fmMain = fmMain;
}

public MainActivity getFmMain() {
    return fmMain;
}

public void setFmMain(MainActivity fmMain) {
    this.fmMain = fmMain;
}

@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_maps, container, false);
mMapFragment = new SupportMapFragment() {
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);

        }
    };
contexto = v.getContext();
mMapFragment.getMapAsync(this);
//getChildFragmentManager().beginTransaction().add(R.id.activitymap, mMapFragment).commit();
 getFmMain().getSupportFragmentManager().beginTransaction().add(R.id.activitymap, mMapFragment).commit();//aqui es donde me tira el error

 return  v;
}

@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (ContextCompat.checkSelfPermission(contexto, Manifest.permission.ACCESS_COARSE_LOCATION)== PackageManager.PERMISSION_GRANTED) {
        mMap.setMyLocationEnabled(true);
    }

    mMap.addMarker(new MarkerOptions().position(new LatLng( -25.598303, -54.575627)).title("Angelo Resto Bar Restaurant")).setIcon(BitmapDescriptorFactory.fromResource(R.drawable.restaurant));
    mMap.addMarker(new MarkerOptions().position(new LatLng(  -25.598265, -54.575681)).title("Restaurante II Frantello")).setIcon(BitmapDescriptorFactory.fromResource(R.drawable.restaurant));
    mMap.addMarker(new MarkerOptions().position(new LatLng( -25.598806, -54.575069)).title("La Tata Restaurante")).setIcon(BitmapDescriptorFactory.fromResource(R.drawable.restaurant));
    mMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(-25.598806, -54.575069)));
    mMap.moveCamera(CameraUpdateFactory.zoomTo(9));
    mMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
        @Override
        public void onInfoWindowClick(Marker marker) {
            NotifPopUp firstFragment = new NotifPopUp();
            fmMain.getSupportFragmentManager().beginTransaction().add(getFmMain().getFrameContainer().getId(), firstFragment).commit();

        }
    });
    }
}

感谢!!!

1 个答案:

答案 0 :(得分:4)

  1. 摆脱:

    @SuppressLint("ValidFragment")
    public MapRestaurant(MainActivity fmMain) {
        this.fmMain = fmMain;
    }
    
    public MainActivity getFmMain() {
       return fmMain;
    }
    
    public void setFmMain(MainActivity fmMain) {
         this.fmMain = fmMain;
    }
    
  2. Android为您保留该引用。使用getActivity()检索托管Activity。同样的事情也适用于contexto = v.getContext();

    1. 更改

      getFmMain().getSupportFragmentManager()
      
    2. getFragmentManager()。如果您确实从支持库导入Fragment,则在Fragment的子类getFragmentManager()中,返回FragmentManager的支持版本。不需要魔法