FragmentPagerAdapter istnieje tylko w Android.Support.V4.App (a nie Android.App)

163

Nie mogę znaleźć FragmentPagerAdapter w Android.App.

Nie chcę używać fragmentów z Android.Support.V4.App, ponieważ mój docelowy interfejs API to 14 lub nowszy (Android 4.0 i nowsze). Chcę więc po prostu użyć zwykłego Android.App.Fragments i skojarzonych z nimi klas.

Znalazłem go tylko w Android.Support.V4.App, ale to mi nie wystarcza b / c Próbuję użyć Android.App.Fragment (nie Android.Support.V4.App.Fragment) i tam pokrewne klasy w Android.App (nie Android.Support.V4.App), a mój kod nie zostanie skompilowany, jeśli wyprowadzę mój pager z FragmentPagerAdapter, jeśli pochodzi z biblioteki Support, z powodu wynikowych niezgodności typów między Android.App i Android.Support .V4.App.

Tak jak w przypadku tutaj Nie można przesłać do android.app.Fragment , czy istnieje "normalna" klasa pagera (PagerAdapter), której powinienem używać zamiast FragmentPagerAdapter czy coś (tak jak wyprowadzasz z normalnej Activity, a nie FragmentActivity, w przypadku kierowania na interfejs API 11 lub nowszy).

Oto przykładowy kod, z którym pracuję (jest to plik FragmentPagerSupport.cs w rozwiązaniu Support4.sln z przykładów MonoDroid znalezionych na https://github.com/xamarin/monodroid-samples/tree/master/Support4 ).

Skomentowałem wiersze odnoszące się do Android.Support.V4.App i zastąpiłem je kodem, który odwołuje się do Android.App. Nie ma FramePagerAdapter poza Android.Support.V4.App, który mógłbym znaleźć i naprawdę go potrzebuję).

Dzięki.

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 jest
źródło
5
Jest taki, który jest w środku android.support.v13.app.FragmentPagerAdapter. Nie jestem pewien, czy to ci pomoże, ale ...
PearsonArtPhoto
PearsonArtPhoto Nie jestem pewien, ponieważ nie ma przestrzeni nazw Android.Support.V13.View (w MonoDroid i tak). Wolałbym w ogóle nie korzystać z biblioteki wsparcia, ale nie sądzę, że jest to jeszcze możliwe.
samis
Wygląda na to, że ViewPager istnieje tylko w bibliotece wsparcia ...
samis
developer.android.com/reference/android/support/v4/view/… Sekcja Przegląd klasy w dużym stopniu podsumowuje ten problem - „Uwaga: ta klasa jest obecnie na wczesnym etapie projektowania i opracowywania. API prawdopodobnie ulegnie zmianie w późniejszych aktualizacjach Biblioteka zgodności, wymagająca zmian w kodzie źródłowym aplikacji, gdy są one kompilowane względem nowszej wersji ”.
samis
Kolejny fragment z dokumentacji developer.android.com/tools/extras/support-library.html „Biblioteka pomocy technicznej dla wersji 4 zapewnia dostęp do kilku klas wprowadzonych w Androidzie 3.0 i nowszych, a także do niektórych zaktualizowanych wersji istniejących klas, a nawet niektórych interfejsów API które obecnie nie istnieją na platformie Android ”. Jednak dlaczego mieliby kiedykolwiek pozostawić tak ważny fragment „API” fragmentu wyłącznie w bibliotece pomocniczej, gdzie pozostała część istnieje na zewnątrz, jeśli tak jest. Może przeoczenie?
samis

Odpowiedzi:

202

Jest taki android.support.v13.app.FragmentPagerAdapter, który powinien zrobić to, co chcesz. Jest to FragmentPagerAdapter dla fragmentów nieobsługujących.

Instalacja Android Studio

Dodaj następujące zależności Gradle

dependencies {
    compile 'com.android.support:support-v13:+'
}
PearsonArtPhoto
źródło
8
Jest bałagan w tym sensie, że nie można używać zagnieżdżonych fragmentów i getChildFragmentManager () w bibliotece pomocy technicznej 13.
Yar
3
użyj kompilacji „com.android.support:support-v13:21.0.+” dla kompilacji
Gradle
moje studio android nie rozwiązuje import android.support.v13.app.FragmentPagerAdapter;żadnego pomysłu? pewnie dodałem już kompilację „com.android.support:support-v13:23.1.1” do gradle
Muhammad Naderi
1
support:support-v13ma konflikt z support:designw moim przypadku
Konstantin Konopko
4
Ale teraz jest przestarzały w api 27 ->, aby ponownie używać wersji v4. Potem znowu mamy problem, bez możliwości użycia fragmentu none support lib
Morten Holmgaard
16

Ugh, wystarczy użyć FragmentPagerAdapter z biblioteki obsługi V13

Android.Support.V13.App.FragmentPagerAdapter

Wtedy wszystkie inne klasy związane z fragmentami mogą być używane z "normalnych" bibliotek / przestrzeni nazw, z wyjątkiem ViewPager, ale to nic wielkiego.


Oto próbka kompletności (zmodyfikowany przykład „Support4” z 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 jest
źródło
2
Jest bałagan w tym sensie, że nie można używać zagnieżdżonych fragmentów i getChildFragmentManager () w bibliotece pomocy technicznej 13.
Yar
2

Dodaj tę zależność do zależności gradle:

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

I używaj w android.support.v13.app.FragmentPagerAdapterten sposób (po prostu zmodyfikowałem oficjalny projekt demonstracyjny w android studio: plik → nowy → nowy projekt → następny → następny → aktywność z zakładkami → następny → koniec):

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
źródło
0

Zgodnie z 2019 z AndroidX

implementation 'androidx.legacy:legacy-support-v13:1.0.0'
implementation 'androidx.viewpager:viewpager:1.0.0'
Vlad
źródło
-1

Miałem ten sam problem. Moim rozwiązaniem było skopiowanie kodu z android.support.v4.app.FragmentPagerAdapter, a następnie zmiana zaimportowanej klasy Fragment na android.app.Fragment. Następnie wykonaj inne drobne poprawki, aby usunąć wszystkie błędy. Ku mojemu zdziwieniu działa idealnie. IMO jest to prostsze niż dodanie biblioteki obsługi, której tak naprawdę nie potrzebujesz.

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
źródło