FragmentPagerAdapter существует только в Android.Support.V4.App (а не в Android.App)

Я не могу найти FragmentPagerAdapter в Android.App.

Я не хочу использовать фрагмент из Android.Support.V4.App, так как мой целевой API 14 и выше (Android 4.0 и выше). Итак, я хочу просто использовать Android.App.Fragments и связанные с ними классы.

Я нашел его только в Android.Support.V4.App, но этого мне недостаточно, потому что я пытаюсь использовать Android.App.Fragment (не Android.Support.V4.App.Fragment), и там связанные классы в Android.App (не Android.Support.V4.App), и мой код не будет компилироваться, если я получу свой пейджер из FragmentPagerAdapter, если он из библиотеки поддержки, из-за несоответствия типов между Android.App и Android.Support .V4.Прил.

Как и в случае здесь Невозможно преобразовать в android.app.Fragment, есть ли "обычный" класс пейджера (PagerAdapter), который я должен использовать вместо FragmentPagerAdapter или чего-то подобного (точно так же, как вы получаете от обычной Activity, а не от FragmentActivity при нацеливании на API 11 или выше).

Вот пример кода, с которым я работаю (это файл FragmentPagerSupport.cs в решении Support4.sln из примеров MonoDroid, найденных по адресу https://github.com/xamarin/monodroid-samples/tree/master/Support4).

Я закомментировал строки, ссылающиеся на Android.Support.V4.App, и заменил их кодом, ссылающимся на Android.App. Нет никакого FramePagerAdapter за пределами Android.Support.V4.App, который я мог бы найти, и он мне действительно нужен).

Спасибо.

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);
            }
        }
    }
}

person samis    schedule 21.11.2012    source источник
comment
Есть один, который находится в android.support.v13.app.FragmentPagerAdapter. Не уверен, что это поможет вам, но...   -  person PearsonArtPhoto    schedule 22.11.2012
comment
PearsonArtPhoto Не уверен, поскольку нет пространства имен Android.Support.V13.View (во всяком случае, в MonoDroid). Я бы предпочел вообще не использовать библиотеку поддержки, но пока не думаю, что это возможно.   -  person samis    schedule 23.11.2012
comment
Похоже, ViewPager существует только в библиотеке поддержки...   -  person samis    schedule 23.11.2012
comment
developer.android.com/reference/android/support/v4/ view/ Раздел «Обзор класса» в значительной степени подводит итог этому затруднительному положению — обратите внимание, что этот класс в настоящее время находится на ранней стадии проектирования и разработки. API, скорее всего, изменится в более поздних обновлениях библиотеки совместимости, что потребует внесения изменений в исходный код приложений при их компиляции для более новой версии.   -  person samis    schedule 23.11.2012
comment
Еще одна выдержка из документации developer.android.com/tools/extras/support-library. .html Библиотека поддержки для версии 4 предоставляет доступ к нескольким классам, представленным в Android 3.0 и более поздних версиях, а также к некоторым обновленным версиям существующих классов и даже к некоторым API, которых в настоящее время нет на платформе Android. Однако с чего бы им вообще оставлять такую ​​важную часть Fragment API исключительно в библиотеке поддержки, тогда как остальная часть существует вне ее. Может оплошность?   -  person samis    schedule 23.11.2012
comment
@PearsonArtPhoto Да, это было то, что действительно исправило это. Спасибо, что предложили это.   -  person samis    schedule 03.12.2012
comment
@SamusArin Да. Если ваш minSdk больше 11, вы должны использовать android.support.v13.   -  person Dinesh    schedule 26.02.2013


Ответы (5)


Один из них находится в android.support.v13.app.FragmentPagerAdapter и должен делать то, что вы хотите. делать. Это FragmentPagerAdapter для неподдерживаемых фрагментов.

Установка Android Studio

Пожалуйста, добавьте следующие зависимости Gradle

dependencies {
    compile 'com.android.support:support-v13:+'
}
person PearsonArtPhoto    schedule 21.11.2012
comment
Беспорядок в том смысле, что вы не можете использовать вложенные фрагменты и getChildFragmentManager() в библиотеке поддержки 13. - person Yar; 13.08.2014
comment
используйте компиляцию «com.android.support:support-v13:21.0.+» для сборки gradle - person cV2; 14.02.2015
comment
моя студия Android не разрешает import android.support.v13.app.FragmentPagerAdapter; есть идеи? наверняка уже добавили компиляцию 'com.android.support:support-v13:23.1.1' в gradle - person Muhammad Naderi; 17.11.2015
comment
support:support-v13 конфликтует с support:design в моем случае - person Konstantin Konopko; 03.06.2016
comment
к вашему сведению: в настоящее время v13 включает все зависимости v4, поэтому с точки зрения сохранения зависимостей нет никакой выгоды. - person Patrick Favre; 02.01.2017
comment
Но теперь в API 27 не рекомендуется снова использовать версию v4. Затем у нас снова возникает проблема, поскольку нет возможности использовать фрагмент lib без поддержки. - person Morten Holmgaard; 05.04.2018

Тьфу, тебе просто нужно использовать FragmentPagerAdapter из библиотеки поддержки V13

Android.Support.V13.App.FragmentPagerAdapter

Затем все другие классы, связанные с фрагментами, можно использовать из «обычных» библиотек/пространств имен, за исключением ViewPager, но это не имеет большого значения.


Вот пример для полноты (модифицированный пример «Support4» из 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>
person samis    schedule 26.11.2012
comment
Беспорядок в том смысле, что вы не можете использовать вложенные фрагменты и getChildFragmentManager() в библиотеке поддержки 13. - person Yar; 13.08.2014

Добавьте эту зависимость к зависимостям gradle:

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

И используйте android.support.v13.app.FragmentPagerAdapter вот так (я просто изменил официальный демонстрационный проект в студии Android: файл → новый → новый проект → следующий → следующий → действие с вкладками → следующий → закончить):

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;
        }
    }
}
person madx    schedule 25.09.2016

По состоянию на 2019 год с AndroidX

implementation 'androidx.legacy:legacy-support-v13:1.0.0'
implementation 'androidx.viewpager:viewpager:1.0.0'
person Vlad    schedule 14.09.2019

Была такая же проблема. Мое решение состояло в том, чтобы скопировать код из android.support.v4.app.FragmentPagerAdapter, а затем изменить импортированный класс Fragment на android.app.Fragment. После этого сделайте другие мелкие доработки, чтобы удалить все ошибки. К моему удивлению, он работает идеально. IMO это проще, чем добавление библиотеки поддержки, которая вам на самом деле не нужна.

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;
    }
}
person mihca    schedule 20.09.2018