片段切换和生命周期

Fragments switching and lifecycle

我正在尝试在主 activity 的框架布局上实现带有片段的 NavigationDrawer。导航抽屉应该在我的 "main" 片段、GMAP 片段和其他片段之间切换。作为 "main" 片段,该片段也会在 activity 首次启动时添加(如您在代码中所见)。问题是当我替换项目点击的片段时,片段被破坏并且地图片段被重新创建。我更希望片段被创建一次并在我用占位符顶部的其他片段替换它时以某种方式保存它的状态

这是地图片段 :

public class Mapfragment extends Fragment
{
MapView mMapView;
private GoogleMap googleMap;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // inflate and return the layout
    View v = inflater.inflate(R.layout.activity_map_fragment, container,
            false);
    mMapView = (MapView) v.findViewById(R.id.mapView);
    mMapView.onCreate(savedInstanceState);

    mMapView.onResume();// needed to get the map to display immediately

    try {
        MapsInitializer.initialize(getActivity().getApplicationContext());
    } catch (Exception e) {
        e.printStackTrace();
    }
    Camera camera = UserDetails.getInstance().getCameras().get(0);

    googleMap = mMapView.getMap();
    // latitude and longitude
    double latitude = camera.getLatitude();
    double longitude = camera.getLongitude();

    // create marker
    MarkerOptions marker = new MarkerOptions().position(
            new LatLng(latitude, longitude)).title("Hello Maps");

    // Changing marker icon
    marker.icon(BitmapDescriptorFactory
            .defaultMarker(BitmapDescriptorFactory.HUE_ROSE));

    // adding marker
    googleMap.addMarker(marker);
    CameraPosition cameraPosition = new CameraPosition.Builder()
            .target(new LatLng(camera.getLatitude(), camera.getLongitude())).zoom(18).build();
    googleMap.animateCamera(CameraUpdateFactory
            .newCameraPosition(cameraPosition));

    // Perform any camera updates here
    return v;
}@Override
 public void onResume() {
super.onResume();
Log.d("Map fragment Resumed", "sdfsdf");
mMapView.onResume();
}

@Override
public void onPause() {
    super.onPause();
    Log.d("Map fragment paused","dsffs");
    mMapView.onPause();
}

@Override
public void onDestroy() {
    super.onDestroy();
    Log.d("Map fragment Destroyed", "sdfsdf");
    mMapView.onDestroy();
}

@Override
public void onLowMemory() {
    super.onLowMemory();
    mMapView.onLowMemory();
}

}

主要activity

public class Main_screen 扩展 AppCompatActivity 实现 NavigationView.OnNavigationItemSelectedListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main_screen);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    Fragment fragment  = new Mapfragment();




    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);
    View hView =  navigationView.getHeaderView(0);
    TextView username_header = (TextView)hView.findViewById(R.id.username_header);
    username_header.setText(UserDetails.getInstance().getUsername());
    ImageView img= (ImageView)hView.findViewById(R.id.imageView);
    img.setImageBitmap(UserDetails.getInstance().getImage());
            //adding main fragment upon Main screen activity Oncreate
    android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager.beginTransaction().add(R.id.frame_layout_placeholder,fragment).commit();





}

@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_screen, 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.
    android.support.v4.app.Fragment fragment = null;
    android.support.v4.app.FragmentTransaction fragmentManager = getSupportFragmentManager().beginTransaction();

    int id = item.getItemId();

    if (id == R.id.map_frag_item) {
        fragment  = new Mapfragment();
    } else if (id == R.id.nav_gallery) {
        fragment = new FragmentTwo();

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

    }

    fragmentManager.replace(R.id.frame_layout_placeholder, fragment).commit();
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}

正在 activity 的 OnCreate 添加主要 GMAP 片段,并在 OnItemSelected() 上替换服装。 非常感谢!

如果您的片段不应在每次单击菜单项时更新,您可以尝试将片段对象存储在地图中,并尝试在菜单项单击事件中检索它。但我不知道这是否是一个好习惯。

public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
android.support.v4.app.Fragment fragment = null;
android.support.v4.app.FragmentTransaction fragmentManager = getSupportFragmentManager().beginTransaction();

int id = item.getItemId();
if(myFragmentMap.contains(id) && myFragmentMap.get(new Integer(id))!=null){
     fragment=myFragmentMap.get(new Integer(id));
     return true;
}
if(myFragmentMap==null)myFragmentMap=new HashMap<>();
if (id == R.id.map_frag_item) {
    fragment  = new Mapfragment();
    myFragmentMap.put(id,fragment);
} 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) {

}

fragmentManager.replace(R.id.frame_layout_placeholder, fragment).commit();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}

正在声明 myFragmentMap;

您必须将其声明为 class 变量

public class MyFragment extends Fragment{
   static HashMap myFragmentMap;

   //onCreateView Method and the rest
}

看起来 onNavigationItemSelected你每次都在创建新片段。我想你想做的是:

  1. 首先检查您是否已经有片段。这可以使用 findFragmentByTag() 在片段管理器上。
  2. 如果returnsnull,那么你还没有创建片段,在 在这种情况下,您创建新片段然后添加一些 标记(您调用时将用于搜索它的标记 findFragmentByTag()下次。

  3. 如果它确实存在那么你可以用 你找到了一个。

创建片段时,在 onCreate 方法中,您可能还想调用 setRetainInstance(true)