FragmentPagerAdapter มีอยู่เฉพาะใน Android.Support.V4.App (ไม่ใช่ Android.App)


163

ฉันไม่พบ find FragmentPagerAdapter ภายใน Android.App

ฉันไม่ต้องการใช้ Fragment จาก Android.Support.V4.App เนื่องจาก API เป้าหมายของฉันคือ 14 และสูงกว่า (Android 4.0 ขึ้นไป) ดังนั้นฉันต้องการเพียงแค่ใช้ธรรมดาของ Android.App.Fragments และมีชั้นเรียนที่เกี่ยวข้อง

ฉันพบเฉพาะภายใน Android.Support.V4.App แต่นี่ไม่พอสำหรับฉัน b / c ฉันพยายามใช้ Android.App.Fragment's (ไม่ใช่ Android.Support.V4.App.Fragment's) และมี คลาสที่เกี่ยวข้องภายใน Android.App (ไม่ใช่ Android.Support.V4.App) และรหัสของฉันจะไม่รวบรวมถ้าฉันได้รับเพจเจอร์ของฉันจาก FragmentPagerAdapter ถ้ามันมาจากห้องสมุดการสนับสนุนเพราะประเภทไม่ตรงกันระหว่าง Android.App และ Android.Support .V4.App

เช่นเดียวกับกรณีที่นี่ไม่สามารถส่งไปยัง android.app.Fragmentมีคลาส pager (PagerAdapter) "ปกติ" ที่ฉันควรใช้แทน FragmentPagerAdapter หรือบางอย่าง (เหมือนที่คุณได้รับจากกิจกรรมปกติไม่ใช่ 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);
            }
        }
    }
}

5
android.support.v13.app.FragmentPagerAdapterมีอยู่คนหนึ่งที่อยู่ใน ไม่แน่ใจว่าจะช่วยคุณได้หรือไม่ แต่ ...
PearsonArtPhoto

PearsonArtPhoto ไม่แน่ใจเนื่องจากไม่มี Android.Support.V13.View เนมสเปซ (ใน MonoDroid อยู่แล้ว) ฉันไม่ควรใช้ห้องสมุดสนับสนุนเลย แต่ฉันคิดว่ามันยังเป็นไปไม่ได้
samis

ดูเหมือนว่า ViewPager จะมีอยู่ในห้องสมุดสนับสนุนเท่านั้น ...
samis

developer.android.com/reference/android/support/v4/view/…ส่วนภาพรวมของชั้นได้สรุปสถานการณ์นี้ - "โปรดสังเกตว่าขณะนี้ชั้นเรียนนี้อยู่ระหว่างการออกแบบและพัฒนาในช่วงต้น API มีแนวโน้มที่จะเปลี่ยนแปลงในการปรับปรุงภายหลังของ ไลบรารีความเข้ากันได้ซึ่งต้องการการเปลี่ยนแปลงรหัสแหล่งที่มาของแอพเมื่อรวบรวมกับเวอร์ชั่นที่ใหม่กว่า "
samis

ข้อความที่ตัดตอนมาจาก docs developer.android.com/tools/extras/support-library.html "ไลบรารีการสนับสนุนสำหรับ v4 ให้การเข้าถึงคลาสต่างๆที่เปิดตัวพร้อมกับ Android 3.0 ขึ้นไปรวมถึงรุ่นที่มีการอัปเดตของคลาสที่มีอยู่และแม้แต่ API บางตัว ขณะนี้ยังไม่มีในแพลตฟอร์ม Android " อย่างไรก็ตามทำไมพวกเขาถึงทิ้งชิ้นส่วนสำคัญของ "API" ไว้ในไลบรารีการสนับสนุนโดยเฉพาะซึ่งมีที่เหลืออยู่นอกถ้ามัน บางทีการกำกับดูแล?
samis

คำตอบ:


202

มีสิ่งหนึ่งที่มีอยู่android.support.v13.app.FragmentPagerAdapterซึ่งควรทำในสิ่งที่คุณต้องการให้ทำ เป็น FragmentPagerAdapter สำหรับแฟรกเมนต์ที่ไม่สนับสนุน

การติดตั้ง Android Studio

โปรดเพิ่มการติดตาม Gradle

dependencies {
    compile 'com.android.support:support-v13:+'
}

8
มีระเบียบในแง่ที่ว่าคุณไม่สามารถใช้ชิ้นส่วนซ้อนกันและ getChildFragmentManager () ในการสนับสนุน lib 13 ได้
Yar

3
ใช้คอมไพล์ 'com.android.support:support-v13:21.0.+' สำหรับการสร้าง
gradle

android studio ของฉันไม่สามารถแก้ไขimport android.support.v13.app.FragmentPagerAdapter;ความคิดใด ๆ แน่นอนว่าได้เพิ่มคอมไพล์แล้ว 'com.android.support:support-v13:23.1.1' เพื่อไล่ระดับ
มูฮัมหมัด

1
support:support-v13มีความขัดแย้งกับsupport:designในกรณีของฉัน
Konstantin Konopko

4
แต่ตอนนี้มันเลิกใช้แล้วใน api 27 -> เพื่อใช้เวอร์ชัน v4 อีกครั้ง จากนั้นเราก็มีปัญหาอีกครั้งโดยไม่มีวิธีใช้ชิ้นส่วน lib สนับสนุนไม่มี
Morten Holmgaard

16

ใช่คุณเพียงแค่ต้องใช้ 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>

2
มีระเบียบในแง่ที่ว่าคุณไม่สามารถใช้ชิ้นส่วนซ้อนกันและ getChildFragmentManager () ในการสนับสนุน lib 13 ได้
Yar

2

เพิ่มการพึ่งพานี้ไปยังการพึ่งพา gradle:

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

และใช้android.support.v13.app.FragmentPagerAdapterเช่นนี้ (ฉันเพิ่งแก้ไขโครงการตัวอย่างเป็นทางการใน android studio: ไฟล์→ใหม่→โครงการใหม่→ถัดไป→ถัดไป→กิจกรรมแท็บ→ถัดไป→เสร็จสิ้น):

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

0

ตามปี 2019 กับ AndroidX

implementation 'androidx.legacy:legacy-support-v13:1.0.0'
implementation 'androidx.viewpager:viewpager:1.0.0'

-1

มีปัญหาเดียวกัน ทางออกของฉันคือการคัดลอกรหัสจาก 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;
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.