如何在改变android的方向时保留Fragment的内容?

时间:2017-08-19 12:10:30

标签: android android-fragments

我正在使用导航抽屉布局,并在侧面菜单中有2个项目。我在导航时使用片段为每个项目显示。

让我们考虑Fragment1& Fragment2。当我从Fragment2自动旋转屏幕时,它会破坏片段并显示Fragment1的内容。

使用youTube教程很少,我尝试使用onSaveInstanceState。但我无法找到正确的解决方案。

JavaHomeActivity.java // Fragment1

public class JavaHomeActivity extends Fragment{

// created for save state in orientation change
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if(savedInstanceState==null)
    {

    }
    else{
        savedInstanceState.getString("home_text");
    }
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    getActivity().setTitle("Home");
}


// created for save state in orientation change
@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putString("home_text", String.valueOf(R.id.nav_home));
}


@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    return inflater.inflate(R.layout.java_home_layout,container,false);
} 
}

JavaBasicActivity // Fragment2

public class JavaBasicActivity extends Fragment{
TextView text;
String data;
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    getActivity().setTitle("Java Basics");
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putString("basic_text", String.valueOf(R.id.nav_basics));
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view= inflater.inflate(R.layout.java_basic_layout,container,false);
    if(savedInstanceState==null)
    {

    }
    else{
        data=savedInstanceState.getString("basic_text");
        TextView myText= (TextView) view.findViewById(R.id.basicText);
        myText.setText(data);
    }
    return view;
}
}

Fragment1的XML

 <TextView
    android:id="@+id/homeText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"

    android:layout_gravity="start"
    android:padding="15dp"
    android:text="@string/java_home_content"
    android:textAlignment="textStart"
    android:textColor="@color/text_color" />

Fragment2的XML

<TextView
    android:id="@+id/basicText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"


    android:layout_gravity="start"
    android:drawableBottom="@drawable/jvm_arc"
    android:padding="15dp"
    android:text="@string/java_basic_content"
    android:textAlignment="textStart"


    android:textColor="@color/text_color" />

JavaMainPageActivity.java //导航抽屉活动

public class JavaMainPageActivity extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_java_main_page);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        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);
        displaySelectedScreen(R.id.nav_home);

}

@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.java_main_page, 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);
}

private void displaySelectedScreen(int id){
    Fragment fragment= null;
    switch(id)
    {
        case R.id.nav_home:
            fragment= new JavaHomeActivity();
            break;
        case R.id.nav_basics:
            fragment= new JavaBasicActivity();
            break;
    }
    if(fragment!=null)
    {
        FragmentTransaction ft= getSupportFragmentManager().beginTransaction();
        ft.replace(R.id.content_main, fragment);
        ft.commit();
    }

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

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

任何人都可以帮助我吗?我在哪里做错误,我必须改变以获得解决方案。?

2 个答案:

答案 0 :(得分:1)

您正在onCreatedisplaySelectedScreen(R.id.nav_home);添加片段,即使在方向更改后也会执行此操作。

因此,这会覆盖实际系统重新创建的Fragment。

onCreate中更改此代码:

if (savedInstanceState == null) {
    displaySelectedScreen(R.id.nav_home);
}

答案 1 :(得分:0)

这是您的解决方案。

你的片段看起来像这样:

public class Fragment1 extends Fragment {

    private View mView;

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

    }

    // created for save state in orientation change
    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("Fragment1", "My First Fragment");
    }


    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mView = inflater.inflate(R.layout.fragment_1, container, false);

        return mView;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        TextView mText = (TextView) mView.findViewById(R.id.text);
        if (savedInstanceState == null) {
        } else {
            String saved = savedInstanceState.getString("Fragment1");
            mText.setText(saved);
        }
    }
}

你的活动应该是这样的:

public class MainActivity extends AppCompatActivity {
    private Fragment mCurrentFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (savedInstanceState != null) {
            //Restore the fragment's instance
            mCurrentFragment = getSupportFragmentManager().getFragment(savedInstanceState, "Fragment1");
        } else {
            mCurrentFragment = new Fragment1();
            addFragment(mCurrentFragment);
        }


    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        getSupportFragmentManager().putFragment(outState, "Fragment1", mCurrentFragment);
    }

    public void addFragment(Fragment fragment) {

        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        if (mCurrentFragment != null) {
            Fragment f = getSupportFragmentManager().findFragmentByTag(mCurrentFragment.getClass().getName());
            if (f != null) {
                fragmentTransaction.remove(f);
            }
        }
        fragmentTransaction.add(R.id.fragment, fragment, fragment.getClass().getName());
        fragmentTransaction.commit();
        mCurrentFragment = fragment;
    }

}

由于已经说过活动会重新创建,您需要在活动中保存片段的状态,就像上面的代码一样。 希望它能帮到你,让你更清楚。