使用ChildFragmentManager替换片段只是将第二个片段放在第一个片段上

时间:2015-11-05 13:07:52

标签: android xml android-fragments

我想制作带有标签的应用,并且在每个标签中我想要有多个片段。我有一个MainActivity:

import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
    private CarouselFragment carouselFragment;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (savedInstanceState == null){
            initScreen();
        }else {
            carouselFragment = (CarouselFragment) getSupportFragmentManager().getFragments().get(0);
        }
    }
    private void initScreen() {
        carouselFragment = new CarouselFragment();
        Log.v("manager", "init " + getSupportFragmentManager().toString());
        final FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.container, carouselFragment)
                .commit();
        Log.v("manager", "init " + getSupportFragmentManager().toString());
    }
    @Override
    public void onBackPressed() {
        if (!carouselFragment.onBackPressed()) {
            super.onBackPressed();
        } else {
        }
    }
}

CarouselFragment类:

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class CarouselFragment extends Fragment {
    protected ViewPager pager;
    private ViewPagerAdapter adapter;
    public CarouselFragment() {
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_carousel, container, false);
        pager = (ViewPager) rootView.findViewById(R.id.vp_pages);
        return rootView;
    }
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Log.v("manager", "carousel " + getChildFragmentManager().toString());
        adapter = new ViewPagerAdapter(getResources(), getChildFragmentManager());
        pager.setAdapter(adapter);
        Log.v("manager", "carousel " + getChildFragmentManager().toString());
    }
    public boolean onBackPressed() {
        OnBackPressListener currentFragment = (OnBackPressListener) adapter.getRegisteredFragment(pager.getCurrentItem());
        if (currentFragment != null) {
            return currentFragment.onBackPressed();
        }
        return false;
    }
}

及其xml布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.v4.view.ViewPager
        android:id="@+id/vp_pages"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />
</LinearLayout>

ViewPagerAdapter类:

import android.content.res.Resources;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.util.SparseArray;
import android.view.ViewGroup;
public class ViewPagerAdapter extends FragmentPagerAdapter {
    private final Resources resources;
    SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
    public ViewPagerAdapter(final Resources resources, FragmentManager fm) {
        super(fm);
        this.resources = resources;
    }
    @Override
    public Fragment getItem(int position) {
        final Fragment result;
        switch (position) {
            case 0:
                result = new A1Fragment();
                break;
            case 1:
                result = new B1Fragment();
                break;
            case 2:
                result = new C1Fragment();
                break;
            default:
                result = null;
                break;
        }
        return result;
    }
    @Override
    public int getCount() {
        return 3;
    }
    @Override
    public CharSequence getPageTitle(final int position) {
        switch (position) {
            case 0:
                return "a";
            case 1:
                return "b";
            case 2:
                return "c";
            default:
                return null;
        }
    }
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Fragment fragment = (Fragment) super.instantiateItem(container, position);
        registeredFragments.put(position, fragment);
        return fragment;
    }
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        registeredFragments.remove(position);
        super.destroyItem(container, position, object);
    }
    public Fragment getRegisteredFragment(int position) {
        return registeredFragments.get(position);
    }
}

A1Fragment类:

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class A1Fragment extends RootFragment {
    public A1Fragment() {
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_a1, container, false);
        rootView.findViewById(R.id.next_button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                enterNextFragment();
            }
        });
        return rootView;
    }
    private void enterNextFragment() {
        A2Fragment a2Fragment = new A2Fragment();
        FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
        transaction.addToBackStack(null);
        transaction.replace(R.id.fragment_mainLayout, a2Fragment).commit();
    }
}

它的xml:

<FrameLayout 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"
    tools:context=".frags.A1Fragment"
    android:background="@android:color/white"
    android:id="@+id/fragment_mainLayout">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="a1"
        android:textAppearance="?android:textAppearanceLarge"
        android:textSize="36sp"/>
    <Button
        android:id="@+id/next_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Next fragment"/>
</FrameLayout>

A2Fragment类:

import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class A2Fragment extends RootFragment {
    public A2Fragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_a2, container, false);
        rootView.findViewById(R.id.next_button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                enterNextFragment();
            }
        });
        return rootView;
    }

    private void enterNextFragment() {
        A3Fragment a3Fragment = new A3Fragment();
        FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
        transaction.addToBackStack(null);
        transaction.replace(R.id.fragment_mainLayout, a3Fragment).commit();
    }
}

它的xml:

<FrameLayout 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"
    tools:context=".frags.A2Fragment"
    android:background="@android:color/white"
    android:id="@+id/fragment_mainLayout">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="a2"
        android:textAppearance="?android:textAppearanceLarge"
        android:textSize="36sp"/>
    <Button
        android:id="@+id/next_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal|bottom"
        android:text="Next fragment"/>
</FrameLayout>

问题在于,当我用第二个片段替换第一个片段时,第一个片段不会消失。第二个出现在第一个上面。

2 个答案:

答案 0 :(得分:1)

我建议您使用Android设备监视器查看视图层次结构。

此外,为了简化您的代码,您可以:
1)直接在XML中包含CarouselFragment
2)使用FrameLayout包含ViewPager并设置为ViewPager高度MATCH_PARENT

答案 1 :(得分:0)

您好,您可以将背景颜色设置为第二个片段布局,以便第一个不会出现