FragmentPagerAdapter n'existe que dans Android.Support.V4.App (et non Android.App)

163

Je ne trouve pas FragmentPagerAdapter dans Android.App.

Je ne souhaite pas utiliser les fragments d'Android.Support.V4.App, car mon API cible est de 14 et plus (Android 4.0 et plus). Donc, je veux simplement utiliser Android.App.Fragments, et les classes associées.

Je ne l'ai trouvé que dans Android.Support.V4.App, mais cela ne me suffit pas car j'essaie d'utiliser Android.App.Fragment (pas Android.Support.V4.App.Fragment's) et là classes associées dans Android.App (pas Android.Support.V4.App), et mon code ne sera pas compilé si je dérive mon pager de FragmentPagerAdapter s'il provient de la bibliothèque de support, en raison de l'incompatibilité de type qui en résulte entre Android.App et Android.Support .V4.App.

Tout comme dans le cas ici Ne peut pas être converti en android.app.Fragment , y a-t-il une classe de pager "normal" (PagerAdapter) que je devrais utiliser à la place de FragmentPagerAdapter ou quelque chose (tout comme vous dérivez de l'activité normale, et non de FragmentActivity, lorsque vous ciblez l'API 11 ou une version ultérieure).

Voici l'exemple de code avec lequel je travaille (c'est le fichier FragmentPagerSupport.cs dans la solution Support4.sln à partir des exemples MonoDroid trouvés à https://github.com/xamarin/monodroid-samples/tree/master/Support4 ).

J'ai commenté les lignes faisant référence à Android.Support.V4.App et les ai remplacées par du code faisant référence à Android.App. Il n'y a pas de FramePagerAdapter en dehors d'Android.Support.V4.App que je pourrais trouver, et j'en ai vraiment besoin).

Merci.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
//using Android.Support.V4.App;
//using Android.Support.V4.View;

namespace Support4
{
    [Activity (Label = "@string/fragment_pager_support")]
    [IntentFilter (new[]{Intent.ActionMain}, Categories = new[]{ "mono.support4demo.sample" })]
    //public class FragmentPagerSupport : FragmentActivity
        public class FragmentPagerSupport : Activity
    {
        const int NUM_ITEMS = 10;
        MyAdapter adapter;
        ViewPager pager;

        protected override void OnCreate (Bundle bundle)
        {
            base.OnCreate (bundle);

            SetContentView(Resource.Layout.fragment_pager);

            //adapter = new MyAdapter(SupportFragmentManager);
                        adapter = new MyAdapter(FragmentManager);

            pager = FindViewById<ViewPager>(Resource.Id.pager);
            pager.Adapter = adapter;

            var button = FindViewById<Button>(Resource.Id.goto_first);
            button.Click += (sender, e) => {
                pager.CurrentItem = 0;  
            };
            button = FindViewById<Button>(Resource.Id.goto_last);
            button.Click += (sender, e) => {
                pager.CurrentItem = NUM_ITEMS - 1;
            };
        }

                // ?????????????????????????????????????????????????
                // - where is FragmentPagerAdapter 
                // ?????????????????????????????????????????????????

        protected class MyAdapter : FragmentPagerAdapter 
        {
            public MyAdapter(FragmentManager fm) : base(fm)
            {
            }

            public override int Count {
                get {
                    return NUM_ITEMS;
                }
            }

            public override Fragment GetItem (int position)
            {
                return new ArrayListFragment(position);
            }


        }

        protected class ArrayListFragment : ListFragment
        {
            int num;

            public ArrayListFragment()
            {
            }

            public ArrayListFragment(int num)
            {
                var args = new Bundle();
                args.PutInt("num", num);
                Arguments = args;
            }

            public override void OnCreate (Bundle p0)
            {
                base.OnCreate (p0);

                num = Arguments != null ? Arguments.GetInt("num") : 1;
            }

            public override View OnCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
            {
                var v = inflater.Inflate(Resource.Layout.fragment_pager_list, container, false);
                var tv = v.FindViewById<TextView>(Resource.Id.text);
                tv.Text = "Fragment #" + num;
                return v;
            }

            public override void OnActivityCreated (Bundle p0)
            {
                base.OnActivityCreated (p0);

                ListAdapter = new ArrayAdapter<string>(Activity, Android.Resource.Layout.SimpleListItem1, Cheeses.cheeseStrings);
            }

            public override void OnListItemClick(ListView l, View v, int position, long id) {
                Console.WriteLine ( "Item clicked: " + id);
            }
        }
    }
}
Sam est
la source
5
Il y en a un qui est dedans android.support.v13.app.FragmentPagerAdapter. Je ne sais pas si cela vous aidera, mais ...
PearsonArtPhoto
PearsonArtPhoto Pas sûr car il n'y a pas d'espace de noms Android.Support.V13.View (dans MonoDroid de toute façon). Je préfère ne pas utiliser du tout la bibliothèque de support, mais je ne pense pas que ce soit encore possible.
samis
On dirait que ViewPager n'existe que dans la bibliothèque de support également ...
samis
developer.android.com/reference/android/support/v4/view/… La section Présentation de la classe résume assez bien cette situation difficile - "Notez que cette classe est actuellement en cours de conception et de développement. L'API sera probablement modifiée dans les mises à jour ultérieures du bibliothèque de compatibilité, nécessitant des modifications du code source des applications lorsqu'elles sont compilées avec la version la plus récente. "
samis
Un autre extrait de la documentation developer.android.com/tools/extras/support-library.html "La bibliothèque de support pour la v4 donne accès à plusieurs classes introduites avec Android 3.0 et au-delà, ainsi qu'à une version mise à jour des classes existantes, et même à certaines API qui n'existent pas actuellement sur la plate-forme Android ". Cependant, pourquoi laisseraient-ils jamais un morceau aussi important du Fragment "API" dans la bibliothèque de support exclusivement, où le reste existe à l'extérieur s'il le faisait. Peut-être un oubli?
samis

Réponses:

202

Il y en a un qui est android.support.v13.app.FragmentPagerAdapterdedans, qui devrait faire ce que vous voulez qu'il fasse. C'est un FragmentPagerAdapter pour les fragments non pris en charge.

Installation d'Android Studio

Veuillez ajouter les dépendances suivantes de Gradle

dependencies {
    compile 'com.android.support:support-v13:+'
}
PearsonArtPhoto
la source
8
Il y a un désordre dans le sens où vous ne pouvez pas utiliser de fragments imbriqués et getChildFragmentManager () dans la bibliothèque de support 13.
Yar
3
utilisez la compilation 'com.android.support:support-v13:21.0.+' pour la construction
gradle
mon studio android ne résout import android.support.v13.app.FragmentPagerAdapter;aucune idée? sûr ont déjà ajouté compile 'com.android.support:support-v13:23.1.1' à gradle
Muhammad Naderi
1
support:support-v13a un conflit avec support:designdans mon cas
Konstantin Konopko
4
Mais maintenant, il est obsolète dans l'api 27 -> d'utiliser à nouveau la version v4. Ensuite, nous avons le problème à nouveau, avec pas moyen d'utiliser le fragment de lib sans support
Morten Holmgaard
16

Ugh, il vous suffit d'utiliser le FragmentPagerAdapter de la bibliothèque de support V13

Android.Support.V13.App.FragmentPagerAdapter

Ensuite, toutes les autres classes liées à Fragment peuvent être utilisées à partir des bibliothèques / espaces de noms "normaux", à l'exception de ViewPager, mais ce n'est pas grave.


Voici un exemple d'exhaustivité (exemple "Support4" modifié de https://github.com/xamarin/monodroid-samples/ ):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;

using Java.Lang;

using Android.Support.V4.View;
using Fragment = Android.App.Fragment;

namespace Support4
{
    [Activity (Label = "@string/fragment_pager_support")]
    [IntentFilter (new[]{Intent.ActionMain}, Categories = new[]{ "mono.support4demo.sample" })]
    public class FragmentPagerSupport : Activity
    //public class FragmentPagerSupport : FragmentActivity
    {
        const int NUM_ITEMS = 4;

        protected MyAdapter _pagerAdapter;
        protected ViewPager _viewPager;

        protected override void OnCreate (Bundle bundle)
        {
            base.OnCreate (bundle);

            SetContentView(Resource.Layout.fragment_pager);

            List<Fragment> fragments = new List<Fragment>();

            // *** MonoDroid 4.2.7 letter case bug *** make's first letter lower.

            //string typeName = typeof(Fragment1).FullName;
            string typeName = "support4." + typeof(Fragment1).Name;

            fragments.Add(Fragment.Instantiate(this, typeName));
            fragments.Add(Fragment.Instantiate(this, typeName));
            fragments.Add(Fragment.Instantiate(this, typeName));
            fragments.Add(Fragment.Instantiate(this, typeName));

            //adapter = new MyAdapter(SupportFragmentManager);
            _pagerAdapter = new MyAdapter(FragmentManager, fragments);

            _viewPager = FindViewById<ViewPager>(Resource.Id.view_pager);
            _viewPager.Adapter = _pagerAdapter;
        }

        public override bool OnTouchEvent(MotionEvent e)
        {
            return base.OnTouchEvent(e);
        }

        protected class MyAdapter : Android.Support.V13.App.FragmentPagerAdapter
        {
            private List<Fragment> _fragments;

            public override Java.Lang.Object  InstantiateItem(View p0, int p1)
            {
                return base.InstantiateItem(p0, p1);
            }

            public MyAdapter(Android.App.FragmentManager fm)
                : base(fm)
            {

            }

            //public MyAdapter(Android.Support.V4.App.FragmentManager fm, List<Android.Support.V4.App.Fragment> fragments)
            //    : base(fm)
            public MyAdapter(FragmentManager fm, List<Fragment> fragments)
                : base(fm)
            {
                _fragments = fragments;
            }

            public override int Count {
                get {
                    return NUM_ITEMS;
                }
            }

            //public override Android.Support.V4.App.Fragment GetItem(int p0)
            public override Fragment GetItem(int p0)
            {
                return _fragments[p0];
            }

            public override float GetPageWidth(int p0)
            {
                //return base.GetPageWidth(p0);
                //base.GetPageWidth(p0);

                return (float)(0.5f);
            }
        }
    }

    //public class Fragment1 : Android.Support.V4.App.Fragment
    public class Fragment1 : Fragment
    {
        int num;

        private static int _colorIndex = 0;
        private static Android.Graphics.Color[] _colors = new[] { Android.Graphics.Color.Aqua, Android.Graphics.Color.DarkViolet,
        Android.Graphics.Color.Coral, Android.Graphics.Color.Bisque};

        public Fragment1()
        {
        }

        public Fragment1(int num)
        {
            var args = new Bundle();
            args.PutInt("num", num);
            Arguments = args;
        }

        public override void OnCreate(Bundle p0)
        {
            base.OnCreate(p0);

            num = Arguments != null ? Arguments.GetInt("num") : 1;
        }

        public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            View v = inflater.Inflate(Resource.Layout.aaaaa, container, false);

            TextView tv = v.FindViewById<TextView>(Resource.Id.text);
            tv.Text = "# " + _colorIndex;
            tv.SetBackgroundColor(_colors[_colorIndex++]);

            return v;
        }

        public override void OnActivityCreated(Bundle p0)
        {
            base.OnActivityCreated(p0);
        }
    }
}

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<!-- Top-level content view for the simple fragment sample. -->

<LinearLayout 
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="horizontal" android:padding="4dip"
  android:layout_width="match_parent" android:layout_height="match_parent">
  <!--android:gravity="center_horizontal"-->

  <android.support.v4.view.ViewPager
    android:id="@+id/view_pager"
    android:layout_width="700dip"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:background="#FFCCFFFF">

    <!--android:layout_width="match_parent"-->
  </android.support.v4.view.ViewPager>

</LinearLayout>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/screen_container"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

  <TextView android:id="@+id/text"
      android:layout_width="match_parent" android:layout_height="match_parent"
      android:gravity="center_vertical|center_horizontal"
      android:textAppearance="?android:attr/textAppearanceMedium"
      android:text="@string/hello_world"
      android:background="#FF335555"/>

</LinearLayout>
Sam est
la source
2
Il y a un désordre dans le sens où vous ne pouvez pas utiliser de fragments imbriqués et getChildFragmentManager () dans la bibliothèque de support 13.
Yar
2

Ajoutez cette dépendance aux dépendances gradle:

compile 'com.android.support:support-v13:+'

Et utilisez android.support.v13.app.FragmentPagerAdaptercomme ceci (j'ai simplement modifié le projet de démonstration officiel dans Android Studio: fichier → nouveau → nouveau projet → suivant → suivant → activité à onglets → suivant → terminer):

import android.app.Fragment;
import android.app.FragmentManager;
import android.support.v13.app.FragmentPagerAdapter;
import com.google.android.gms.maps.MapFragment;

/** A simple FragmentPagerAdapter that returns a MapFragment and a PreferenceFragment. */
public class MainActivityAdapter extends FragmentPagerAdapter {

    private MapFragment mapFragment;
    private PreferencesFragment preferencesFragment;

    public MainActivityAdapter(FragmentManager fm) {
        super(fm);
        mapFragment = MapFragment.newInstance();
        preferencesFragment = new PreferencesFragment();
    }

    @Override
    public int getCount() {
        return 2;
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return mapFragment;
            case 1:
                return preferencesFragment;
            default:
                return null;
        }
    }
}
madx
la source
0

À partir de 2019 avec AndroidX

implementation 'androidx.legacy:legacy-support-v13:1.0.0'
implementation 'androidx.viewpager:viewpager:1.0.0'
Vlad
la source
-1

Eu le même problème. Ma solution était de copier le code de android.support.v4.app.FragmentPagerAdapter, puis de changer la classe Fragment importée en android.app.Fragment. Ensuite, effectuez d'autres adaptations mineures pour supprimer toutes les erreurs. À ma grande surprise, cela fonctionne parfaitement. IMO, c'est plus simple que d'ajouter une bibliothèque de support dont vous n'avez pas vraiment besoin.

import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;

/**
 * PagerAdapter for ViewPager that is compatible with android.app.Fragment.
 */
abstract class FragmentPagerAdapter extends PagerAdapter {

    private final FragmentManager mFragmentManager;
    private FragmentTransaction mCurTransaction = null;
    private Fragment mCurrentPrimaryItem = null;

    /**
     * Returns a unique id for the fragment on the given position.
     * For example this can be the view id that is used on the page's fragment.
     * @param position The page index
     * @return An id that is unique with respect to the pages in the adapter.
     */
    abstract long getItemId(int position);

    /**
     * Returns the fragment for the given page index.
     * @param position The page index
     * @return The fragment
     */
    abstract Fragment getItem(int position);

    public FragmentPagerAdapter(FragmentManager fragmentManager) {
        super();
        mFragmentManager = fragmentManager;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }

        final long itemId = getItemId(position);

        // Do we already have this fragment?
        String name = makeFragmentName(container.getId(), itemId);
        Fragment fragment = mFragmentManager.findFragmentByTag(name);
        if (fragment != null) {
            mCurTransaction.attach(fragment);
        } else {
            fragment = getItem(position);
            mCurTransaction.add(container.getId(), fragment,
                    makeFragmentName(container.getId(), itemId));
        }
        if (fragment != mCurrentPrimaryItem) {
            fragment.setMenuVisibility(false);
        }

        return fragment;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }
        mCurTransaction.detach((Fragment) object);
    }

    @SuppressWarnings("ReferenceEquality")
    @Override
    public void setPrimaryItem(ViewGroup container, int position, Object object) {
        Fragment fragment = (Fragment)object;
        if (fragment != mCurrentPrimaryItem) {
            if (mCurrentPrimaryItem != null) {
                mCurrentPrimaryItem.setMenuVisibility(false);
            }
            if (fragment != null) {
                fragment.setMenuVisibility(true);
            }
            mCurrentPrimaryItem = fragment;
        }
    }

    @Override
    public void finishUpdate(ViewGroup container) {
        if (mCurTransaction != null) {
            mCurTransaction.commitAllowingStateLoss();
            mCurTransaction = null;
        }
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return ((Fragment)object).getView() == view;
    }

    @Override
    public Parcelable saveState() {
        return null;
    }

    @Override
    public void restoreState(Parcelable state, ClassLoader loader) {
    }

    private static String makeFragmentName(int viewId, long id) {
        return "android:switcher:" + viewId + ":" + id;
    }
}
mihca
la source