FragmentPagerAdapter existe apenas no Android.Support.V4.App (e não no Android.App)

163

Não consigo encontrar o FragmentPagerAdapter no Android.App.

Não quero usar os fragmentos do Android.Support.V4.App, pois minha API de destino é 14 e superior (Android 4.0 e superior). Então, eu quero apenas usar simples Android.App.Fragments, e não há classes associadas.

Eu só o encontrei no Android.Support.V4.App, mas isso não é suficiente para mim porque eu estou tentando usar o Android.App.Fragment (não o Android.Support.V4.App.Fragment) e lá classes relacionadas no Android.App (não Android.Support.V4.App), e meu código não será compilado se eu derivar meu pager de FragmentPagerAdapter se for da biblioteca de Suporte, devido à incompatibilidade de tipo resultante entre Android.App e Android.Support .V4.App.

Assim como no caso aqui, não pode ser convertido para android.app.Fragment , existe uma classe pager "normal" (PagerAdapter) que eu deveria estar usando no lugar do FragmentPagerAdapter ou algo assim (assim como você deriva da Activity normal e não FragmentActivity, ao segmentar a API 11 ou superior).

Aqui está o código de exemplo com o qual estou trabalhando (é o arquivo FragmentPagerSupport.cs na solução Support4.sln dos exemplos do MonoDroid encontrados em https://github.com/xamarin/monodroid-samples/tree/master/Support4 ).

Comentei as linhas que referenciavam o Android.Support.V4.App e as substitui pelo código que faz referência ao Android.App. Não há nenhum FramePagerAdapter fora do Android.Support.V4.App que eu possa encontrar e realmente preciso dele).

Obrigado.

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 é
fonte
5
Há um que está em android.support.v13.app.FragmentPagerAdapter. Não tenho certeza se isso vai ajudá-lo, mas ...
Pearsonartphoto
PearsonArtPhoto Não tenho certeza, pois não há espaço para nome Android.Support.V13.View (no MonoDroid de qualquer maneira). Prefiro não usar a biblioteca de suporte, mas acho que ainda não é possível.
samis
Parece que o ViewPager existe apenas na biblioteca de suporte também ...
samis
developer.android.com/reference/android/support/v4/view/… A seção Visão geral da classe resume muito bem essa situação - "Observe que essa classe está atualmente em design e desenvolvimento iniciais. A API provavelmente mudará nas atualizações posteriores do biblioteca de compatibilidade, exigindo alterações no código-fonte dos aplicativos quando eles são compilados na versão mais recente ".
samis
Outro trecho dos documentos developer.android.com/tools/extras/support-library.html "A biblioteca de suporte da v4 fornece acesso a várias classes introduzidas no Android 3.0 e posterior, além de uma versão atualizada das classes existentes e até mesmo algumas APIs. que atualmente não existem na plataforma Android ". No entanto, por que eles deixariam uma parte tão importante da "API" do fragmento na biblioteca de suporte exclusivamente, onde o restante dela existe fora, se existir. Talvez um descuido?
samis 23/11/12

Respostas:

202

Há um que está dentro android.support.v13.app.FragmentPagerAdapter, que deve fazer o que você quer que ele faça. É um FragmentPagerAdapter para fragmentos sem suporte.

Instalação do Android Studio

Por favor, siga as dependências Gradle

dependencies {
    compile 'com.android.support:support-v13:+'
}
PearsonArtPhoto
fonte
8
Há uma confusão em um sentido que você não pode usar fragmentos aninhados e getChildFragmentManager () no apoio lib 13.
Yar
3
use compile 'com.android.support:support-v13:21.0.+' para gradle build
cV2
meu estúdio android não resolve import android.support.v13.app.FragmentPagerAdapter;nenhuma idéia? com certeza já adicionou a compilação 'com.android.support:support-v13:23.1.1' para gradle
Muhammad Naderi
1
support:support-v13está em conflito com support:designno meu caso
Konstantin Konopko 3/16/16
4
Mas agora está obsoleto na api 27 -> para usar a versão v4 novamente. Em seguida, temos o problema de novo, com não maneira de usar a nenhum apoio lib Fragmento
Morten Holmgaard
16

Ugh, você só precisa usar o FragmentPagerAdapter da biblioteca de suporte da V13

Android.Support.V13.App.FragmentPagerAdapter

Todas as outras classes relacionadas ao Fragmento podem ser usadas nas bibliotecas / espaços de nome "normais", com exceção do ViewPager, mas isso não é grande coisa.


Aqui está um exemplo de integridade (exemplo "Support4" modificado em 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 é
fonte
2
Há uma confusão em um sentido que você não pode usar fragmentos aninhados e getChildFragmentManager () no apoio lib 13.
Yar
2

Adicione essa dependência às dependências gradle:

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

E use android.support.v13.app.FragmentPagerAdapterassim (simplesmente modifiquei o projeto de demonstração oficial no android studio: arquivo → novo → novo projeto → próximo → próximo → atividade com guias → próximo → terminar):

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

De acordo com 2019 com AndroidX

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

Teve o mesmo problema. Minha solução foi copiar o código do android.support.v4.app.FragmentPagerAdapter e, em seguida, alterar a classe Fragment importada para android.app.Fragment. Depois, faça outras pequenas adaptações para remover todos os erros. Para minha surpresa, funciona perfeitamente. Na IMO, isso é mais simples do que adicionar uma biblioteca de suporte que você realmente não precisa.

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
fonte