FragmentPagerAdapter Hanya Ada Di Android.Support.V4.App (dan bukan Android.App)

163

Saya tidak dapat menemukan menemukan FragmentPagerAdapter di dalam Android.App.

Saya tidak ingin menggunakan Fragmen dari Android.Support.V4.App, karena API target saya adalah 14 dan lebih tinggi (Android 4.0 dan lebih tinggi). Jadi, saya hanya ingin menggunakan Android.App.Fragments polos, dan ada kelas terkait.

Saya hanya menemukannya di Android.Support.V4.App, tapi ini tidak cukup untuk saya b / c Saya mencoba menggunakan Android.App.Fragment (bukan Android.Support.V4.App.Fragment's) dan ada kelas terkait dalam Android.App (bukan Android.Support.V4.App), dan kode saya tidak dapat dikompilasi jika saya memperoleh pager dari FragmentPagerAdapter jika berasal dari pustaka Dukungan, karena jenis ketidakcocokan yang dihasilkan antara Android.App dan Android.Support .V4.App.

Seperti halnya case di sini Tidak dapat dilemparkan ke android.app.Fragment , apakah ada pager "normal" (PagerAdapter) yang harus saya gunakan di tempat FragmentPagerAdapter atau sesuatu (seperti Anda berasal dari Aktivitas normal, dan bukan FragmentActivity, saat menargetkan API 11 atau lebih tinggi).

Ini adalah contoh kode yang saya kerjakan (file FragmentPagerSupport.cs dalam solusi Support4.sln dari contoh MonoDroid yang ditemukan di https://github.com/xamarin/monodroid-samples/tree/master/Support4 ).

Saya telah mengomentari baris yang mereferensikan Android.Support.V4.App dan menggantinya dengan kode yang merujuk Android.App. Tidak ada FramePagerAdapter di luar Android.Support.V4.App yang bisa saya temukan, dan saya sangat membutuhkannya).

Terima kasih.

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 adalah
sumber
5
Ada satu yang ada di android.support.v13.app.FragmentPagerAdapter. Tidak yakin apakah itu akan membantu Anda, tapi ...
PearsonArtPhoto
PearsonArtPhoto Tidak yakin karena tidak ada namespace Android.Support.V13.View (di MonoDroid toh). Saya lebih suka tidak menggunakan perpustakaan dukungan sama sekali, tapi saya belum berpikir itu mungkin.
samis
Sepertinya ViewPager hanya ada di perpustakaan dukungan juga ...
samis
developer.android.com/reference/android/support/v4/view/... Bagian Ikhtisar Kelas meringkas banyak kesulitan ini - "Perhatikan kelas ini saat ini sedang dalam desain dan pengembangan awal. API kemungkinan akan berubah di pembaruan nanti dari perpustakaan kompatibilitas, membutuhkan perubahan pada kode sumber aplikasi ketika mereka dikompilasi dengan versi yang lebih baru. "
samis
Kutipan lain dari pengembang docs.android.com/tools/extras/support-library.html "Pustaka dukungan untuk v4 menyediakan akses ke beberapa kelas yang diperkenalkan dengan Android 3.0 dan selanjutnya, ditambah beberapa versi terbaru dari kelas yang ada, dan bahkan beberapa API yang saat ini tidak ada di platform Android ". Namun, mengapa mereka pernah meninggalkan bagian penting dari "API" Fragmen di perpustakaan dukungan secara eksklusif, di mana sisanya ada di luar jika itu. Mungkin kekhilafan?
samis

Jawaban:

202

Ada satu yang ada di dalam android.support.v13.app.FragmentPagerAdapter, yang harus melakukan apa yang Anda inginkan. Ini adalah FragmentPagerAdapter untuk fragmen yang tidak mendukung.

Instalasi Android Studio

Silakan tambahkan ikuti dependensi Gradle

dependencies {
    compile 'com.android.support:support-v13:+'
}
PearsonArtPhoto
sumber
8
Ada kekacauan dalam arti bahwa Anda tidak dapat menggunakan fragmen bersarang dan getChildFragmentManager () di lib dukungan 13.
Yar
3
gunakan kompilasi 'com.android.support:support-v13:21.0.+' untuk build
gradle
studio android saya tidak menyelesaikan import android.support.v13.app.FragmentPagerAdapter;ide? yakin telah menambahkan kompilasi 'com.android.support:support-v13:23.1.1' ke gradle
Muhammad Naderi
1
support:support-v13memiliki konflik dengan support:designdalam kasus saya
Konstantin Konopko
4
Tapi sekarang sudah usang dalam api 27 -> untuk menggunakan versi v4 lagi. Maka kita memiliki masalah lagi, dengan tidak cara untuk menggunakan dukungan lib Fragment
Morten Holmgaard
16

Ugh, Anda hanya perlu menggunakan FragmentPagerAdapter dari perpustakaan dukungan V13

Android.Support.V13.App.FragmentPagerAdapter

Kemudian semua kelas terkait Fragmen lainnya dapat digunakan dari pustaka / ruang nama "normal", dengan pengecualian ViewPager, tapi itu bukan masalah besar.


Berikut ini contoh untuk kelengkapan (contoh "Support4" yang dimodifikasi dari 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 adalah
sumber
2
Ada kekacauan dalam arti bahwa Anda tidak dapat menggunakan fragmen bersarang dan getChildFragmentManager () di lib dukungan 13.
Yar
2

Tambahkan dependecy ini ke dependensi gradle:

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

Dan gunakan android.support.v13.app.FragmentPagerAdapterseperti ini (saya hanya memodifikasi proyek demo resmi di android studio: file → baru → proyek baru → berikutnya → berikutnya → aktivitas tab → berikutnya → selesai):

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

Per 2019 dengan AndroidX

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

Punya masalah yang sama. Solusi saya adalah menyalin kode dari android.support.v4.app.FragmentPagerAdapter, lalu ubah kelas Fragment yang diimpor ke android.app.Fragment. Setelah itu lakukan adaptasi kecil lainnya untuk menghapus semua kesalahan. Yang mengejutkan saya ini bekerja dengan sempurna. IMO ini lebih sederhana daripada menambahkan pustaka dukungan yang sebenarnya tidak Anda butuhkan.

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
sumber