Hoe een fragment toe te voegen in een viewpager met behulp van genesteld fragment (Android 4.2)

Ik heb een ViewPagermet drie Fragments, elk toont elk een List(of Grid).

In de nieuwe Android API level 17(Jelly Bean 4.2), een van de functies is geneste fragmenten . De nieuwe functionaliteitsomschrijving zegt:

Als u ViewPager gebruikt om fragmenten te maken die naar links en rechts vegen
Consumeer een meerderheid van de schermruimte, je kunt nu fragmenten invoegen
in elke fragmentpagina.

Dus, als ik het goed begrijp, nu kan ik een ViewPagermaken met Fragments(met bijvoorbeeld een knop binnen bijvoorbeeld) binnen, en wanneer de gebruiker op de knop op de knop drukt Fragmentzonder los de ViewPagermet behulp van deze nieuwe functie.

Ik heb mijn ochtend uitgegeven om deze verschillende manieren te implementeren, maar ik kan het niet laten werken … Kan iemand een eenvoudig voorbeeld toevoegen van hoe dit te implementeren?

PS: Ik ben alleen geïnteresseerd om op deze manier te doen, met getChildFragmentManagerom te leren hoe werkt.


Antwoord 1, Autoriteit 100%

Aangenomen dat u de juiste XML-lay-outs hebt gemaakt. Het is nu heel eenvoudig om fragmenten in een viewpager weer te geven die wordt gehost door een ander fragment.

Het volgende is een ouderfragment dat kinderfragmenten weergeeft:

class ParentViewPagerFragment : Fragment() {
  override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    val root = inflater.inflate(R.layout.fragment_parent_viewpager, container, false)
    val viewPager = root.findViewById(R.id.viewPager) as ViewPager
    // Important: Must use the child FragmentManager or you will see side effects.
    viewPager.adapter = MyAdapter(childFragmentManager)
    val tabStrip = root.findViewById<TabLayout>(R.id.pagerTabStrip)
    tabStrip.setupWithViewPager(viewPager)
    return root
  }
  class MyAdapter internal constructor(fm: FragmentManager) : FragmentPagerAdapter(fm) {
    override fun getCount(): Int = 4
    override fun getItem(position: Int): Fragment {
      val args = Bundle().apply { putInt(ChildFragment.POSITION_KEY, position) }
      return ChildFragment.newInstance(args)
    }
    override fun getPageTitle(position: Int): CharSequence = "Tab $position"
  }
  companion object {
    val TAG: String = ParentViewPagerFragment::class.java.name
  }
}

Het is belangrijk om fragment.getchildfragmentmanager () te gebruiken bij het instantiëren van de fragmentpageradapter. Merk ook op dat u Fragment.SetRetainInstance () op de kinderfragmenten niet kunt gebruiken of u krijgt een uitzondering. De invoer werd weggelaten voor beknoptheid.

Broncode is te vinden op: https://github.com / Marcors / genest-fragmenten


Antwoord 2, Autoriteit 12%

bewerken:
Als u alle inhoud van een pagina in een ViewPagerwilt vervangen, kunt u nog steeds geneste fragmenten gebruiken, maar sommige wijzigingen zijn nodig. Controleer het onderstaande monster (de FragmentActivity, instellen van de ViewPageren de PagerAdapterzijn hetzelfde als het vorige fragment van de code):

// this will act as a fragment container, representing one page in the ViewPager
public static class WrapperFragment extends Fragment implements
        ReplaceListener {
    public static WrapperFragment newInstance(int position) {
        WrapperFragment wp = new WrapperFragment();
        Bundle args = new Bundle();
        args.putInt("position", position);
        wp.setArguments(args);
        return wp;
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        FrameLayout fl = new FrameLayout(getActivity());
        fl.setId(10000);
        if (getChildFragmentManager().findFragmentByTag("initialTag") == null) {
            InitialInnerFragment iif = new InitialInnerFragment();
            Bundle args = new Bundle();
            args.putInt("position", getArguments().getInt("position"));
            iif.setArguments(args);
            getChildFragmentManager().beginTransaction()
                    .add(10000, iif, "initialTag").commit();
        }
        return fl;
    }
    // required because it seems the getChildFragmentManager only "sees"
    // containers in the View of the parent Fragment.   
    @Override
    public void onReplace(Bundle args) {
        if (getChildFragmentManager().findFragmentByTag("afterTag") == null) {
            InnerFragment iif = new InnerFragment();
            iif.setArguments(args);
            getChildFragmentManager().beginTransaction()
                    .replace(10000, iif, "afterTag").addToBackStack(null)
                    .commit();
        }
    }
}
// the fragment that would initially be in the wrapper fragment
public static class InitialInnerFragment extends Fragment {
    private ReplaceListener mListener;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        mListener = (ReplaceListener) this.getParentFragment();
        LinearLayout ll = new LinearLayout(getActivity());
        Button b = new Button(getActivity());
        b.setGravity(Gravity.CENTER_HORIZONTAL);
        b.setText("Frame " + getArguments().getInt("position"));
        b.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Bundle args = new Bundle();
                args.putInt("positionInner",
                        getArguments().getInt("position"));
                if (mListener != null) {
                    mListener.onReplace(args);
                }
            }
        });
        ll.setOrientation(LinearLayout.VERTICAL);
        ll.addView(b, new LinearLayout.LayoutParams(250,
                LinearLayout.LayoutParams.WRAP_CONTENT));
        return ll;
    }
}
public static class InnerFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        TextView tv = new TextView(getActivity());
        tv.setText("InnerFragment in the outher Fragment with position "
                + getArguments().getInt("positionInner"));
        return tv;
    }
}
public interface ReplaceListener {
    void onReplace(Bundle args);
}

In een oogopslag werkt het, maar er kunnen problemen optreden omdat ik het niet al te vaak heb getest.

Kan iemand een eenvoudig voorbeeld laten zien van hoe dit te doen?

Het gebruik van geneste fragmenten lijkt vrij eenvoudig, totdat Commonsware met een meer uitgewerkt voorbeeld komt, kun je de onderstaande code proberen:

public class NestedFragments extends FragmentActivity {
    @Override
    protected void onCreate(Bundle arg0) {
        super.onCreate(arg0);
        ViewPager vp = new ViewPager(this);
        vp.setId(5000);
        vp.setAdapter(new MyAdapter(getSupportFragmentManager()));
        setContentView(vp);
    }
    private static class MyAdapter extends FragmentPagerAdapter {
        public MyAdapter(FragmentManager fm) {
            super(fm);
        }
        @Override
        public Fragment getItem(int position) {
            return WrapperFragment.newInstance(position);
        }
        @Override
        public int getCount() {
            return 8;
        }
    }
    public static class WrapperFragment extends Fragment {
        public static WrapperFragment newInstance(int position) {
            WrapperFragment wp = new WrapperFragment();
            Bundle args = new Bundle();
            args.putInt("position", position);
            wp.setArguments(args);
            return wp;
        }
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            LinearLayout ll = new LinearLayout(getActivity());
            FrameLayout innerFragContainer = new FrameLayout(getActivity());
            innerFragContainer.setId(1111);
            Button b = new Button(getActivity());
            b.setText("Frame " + getArguments().getInt("position"));
            b.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    InnerFragment innerFragment = new InnerFragment();
                    Bundle args = new Bundle();
                    args.putInt("positionInner",
                            getArguments().getInt("position"));
                    innerFragment.setArguments(args);
                    FragmentTransaction transaction = getChildFragmentManager()
                            .beginTransaction();
                    transaction.add(1111, innerFragment).commit();
                }
            });
            ll.setOrientation(LinearLayout.VERTICAL);
            ll.addView(b, new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT));
            ll.addView(innerFragContainer, new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.MATCH_PARENT));
            return ll;
        }
    }
    public static class InnerFragment extends Fragment {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            TextView tv = new TextView(getActivity());
            tv.setText("InnerFragment in the outher Fragment with position "
                    + getArguments().getInt("positionInner"));
            return tv;
        }
    }
}

Ik was lui en maakte alles in code, maar ik weet zeker dat het kan werken met opgeblazen XML-lay-outs.


Antwoord 3, autoriteit 6%

Ik heb een ViewPager gemaakt met 3 elementen en 2 subelementen voor index 2 en 3 en hier wat ik wilde doen..

Ik heb dit geïmplementeerd met behulp van eerdere vragen en antwoorden van StackOverFlow en hier is de link.

ViewPagerChildFragments


Antwoord 4

Gebruik navigatiecomponent eenvoudig in uw app! kopieer dan deze code in je luisteraar:

findNavController().navigate('Your action Id)
  • Uw actie-ID die IDE automatisch voor u heeft gemaakt.

Other episodes