FragmentPagerAdapter solo existe en Android.Support.V4.App (y no en Android.App)

163

No puedo encontrar FragmentPagerAdapter en Android.App.

No quiero usar Fragment's de Android.Support.V4.App, ya que mi API objetivo es 14 y superior (Android 4.0 y superior). Entonces, solo quiero usar Android.App.Fragments y sus clases asociadas.

Solo lo he encontrado en Android.Support.V4.App, pero esto no es suficiente para mí porque estoy tratando de usar Android.App.Fragment's (no Android.Support.V4.App.Fragment's) y allí clases relacionadas dentro de Android.App (no Android.Support.V4.App), y mi código no se compilará si obtengo mi localizador de FragmentPagerAdapter si es de la biblioteca Support, debido a la falta de coincidencia de tipos resultante entre Android.App y Android.Support .V4.App.

Al igual que con el caso aquí, no se puede enviar a android.app.Fragment , ¿hay una clase de buscapersonas "normal" (PagerAdapter) que debería usar en lugar de FragmentPagerAdapter o algo así (como se deriva de la actividad normal y no de FragmentActivity, cuando se dirige a API 11 o superior).

Aquí está el código de muestra con el que estoy trabajando (es el archivo FragmentPagerSupport.cs dentro de la solución Support4.sln de los ejemplos de MonoDroid que se encuentran en https://github.com/xamarin/monodroid-samples/tree/master/Support4 ).

He comentado las líneas que hacen referencia a Android.Support.V4.App y las he reemplazado con un código que hace referencia a Android.App. No hay FramePagerAdapter fuera de Android.Support.V4.App que pude encontrar, y realmente lo necesito).

Gracias.

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 es
fuente
55
Hay uno que está adentro android.support.v13.app.FragmentPagerAdapter. No estoy seguro si eso te ayudará, pero ...
PearsonArtPhoto
PearsonArtPhoto No estoy seguro ya que no hay Android.Support.V13.Ver espacio de nombres (en MonoDroid de todos modos). Prefiero no usar la biblioteca de soporte en absoluto, pero no creo que sea posible todavía.
samis
Parece que ViewPager también existe solo en la biblioteca de soporte ...
samis
developer.android.com/reference/android/support/v4/view/… La sección Descripción general de la clase resume bastante bien esta situación: "Tenga en cuenta que esta clase se encuentra actualmente en diseño y desarrollo tempranos. La API probablemente cambiará en actualizaciones posteriores de la biblioteca de compatibilidad, que requiere cambios en el código fuente de las aplicaciones cuando se compilan con la versión más reciente ".
samis
Otro extracto de los documentos developer.android.com/tools/extras/support-library.html "La biblioteca de soporte para v4 proporciona acceso a varias clases introducidas con Android 3.0 y versiones posteriores, además de algunas versiones actualizadas de las clases existentes e incluso algunas API que actualmente no existen en la plataforma Android ". Sin embargo, ¿por qué alguna vez dejarían una pieza tan importante de la "API" del Fragmento en la biblioteca de soporte exclusivamente, donde el resto existe fuera si es así? Tal vez un descuido?
samis

Respuestas:

202

Hay uno que está dentro android.support.v13.app.FragmentPagerAdapter, que debe hacer lo que quieres que haga. Es un FragmentPagerAdapter para fragmentos que no son compatibles.

Instalación de Android Studio

Agregue las siguientes dependencias de Gradle

dependencies {
    compile 'com.android.support:support-v13:+'
}
PearsonArtPhoto
fuente
8
Hay un desorden en el sentido de que no puedes usar fragmentos anidados y getChildFragmentManager () en la biblioteca de soporte 13.
Yar
3
use la compilación 'com.android.support:support-v13:21.0.+' para la construcción de
gradle
Mi estudio de Android no resuelve import android.support.v13.app.FragmentPagerAdapter;ninguna idea? seguro ya ha agregado compilar 'com.android.support:support-v13:23.1.1' a gradle
Muhammad Naderi
1
support:support-v13tiene conflicto con support:designen mi caso
Konstantin KONOPKO
44
Pero ahora está en desuso en la api 27 -> volver a usar la versión v4. Luego tenemos el problema nuevamente, sin forma de usar el Fragmento de lib de ninguna compatibilidad
Morten Holmgaard
16

Ugh, solo necesitas usar el FragmentPagerAdapter de la biblioteca de soporte V13

Android.Support.V13.App.FragmentPagerAdapter

Entonces, todas las demás clases relacionadas con Fragment pueden usarse desde las bibliotecas / espacios de nombres "normales", con la excepción de ViewPager, pero eso no es gran cosa.


Aquí hay una muestra de integridad (ejemplo "Support4" modificado 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 es
fuente
2
Hay un desorden en el sentido de que no puedes usar fragmentos anidados y getChildFragmentManager () en la biblioteca de soporte 13.
Yar
2

Agregue esta dependencia a las dependencias de gradle:

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

Y use de android.support.v13.app.FragmentPagerAdapteresta manera (simplemente modifiqué el proyecto de demostración oficial en Android Studio: archivo → nuevo → nuevo proyecto → siguiente → siguiente → actividad con pestañas → siguiente → finalizar):

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
fuente
0

Según 2019 con AndroidX

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

Tuve el mismo problema. Mi solución fue copiar el código de android.support.v4.app.FragmentPagerAdapter, luego cambiar la clase Fragment importada a android.app.Fragment. Luego haga otras adaptaciones menores para eliminar todos los errores. Para mi sorpresa, funciona perfectamente. En mi opinión, esto es más simple que agregar una biblioteca de soporte que realmente no necesita.

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
fuente