FragmentPagerAdapter는 Android.Support.V4.App에만 있고 Android.App에는 없습니다.


163

Android.App에서 FragmentPagerAdapter를 찾을 수 없습니다.

대상 API가 14 이상 (Android 4.0 이상)이므로 Android.Support.V4.App의 Fragment를 사용하고 싶지 않습니다. 그래서 나는 평범한 Android.App.Fragments와 관련 클래스를 사용하고 싶습니다.

나는 Android.Support.V4.App 내에서만 발견했지만 이것이 안드로이드에 적합하지 않습니다 .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로 캐스트 할 수없는 것처럼 FragmentPagerAdapter 대신 사용해야하는 "정상"페이저 (PagerAdapter) 클래스가 있습니까 (FragmentActivity가 아닌 일반 활동에서 파생 된 것처럼) API 11 이상을 타겟팅 할 때).

여기 내가 작업하고있는 샘플 코드가 있습니다 ( https://github.com/xamarin/monodroid-samples/tree/master/Support4에 있는 MonoDroid 예제의 Support4.sln 솔루션에있는 FragmentPagerSupport.cs 파일 ).

Android.Support.V4.App을 참조하는 행을 주석 처리하고 Android.App을 참조하는 코드로 대체했습니다. Android.Support.V4.App 외부에 내가 찾을 수있는 FramePagerAdapter가 없으며 실제로 필요합니다).

감사.

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 (어쨌든 MonoDroid에) Android.Support.V13.View 네임 스페이스가 없기 때문에 확실하지 않습니다. 오히려 지원 라이브러리를 전혀 사용하지 않지만 아직 가능한 것으로는 생각하지 않습니다.
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입니다.

안드로이드 스튜디오 설치

다음 Gradle 종속성을 추가하십시오

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

8
지원 라이브러리 13에서 중첩 조각과 getChildFragmentManager ()를 사용할 수 없다는 의미에서 혼란이 있습니다.
Yar

3
gradle 빌드에 컴파일 'com.android.support:support-v13:21.0.+'사용
cV2

내 안드로이드 스튜디오는 import android.support.v13.app.FragmentPagerAdapter;어떤 아이디어도 해결하지 못 합니까? gradle에 컴파일 'com.android.support:support-v13:23.1.1'을 이미 추가했습니다
Muhammad Naderi

1
support:support-v13support:design내 경우에 충돌이 발생했습니다
Konstantin Konopko

4
그러나 이제는 API 27->에서 v4 버전을 다시 사용하기 위해 더 이상 사용되지 않습니다. 그런 다음 우리는 조각 LIB 없음 지원을 사용하지 않는 방법을 다시 문제가
모르 텐 Holmgaard

16

어쨌든 V13 지원 라이브러리의 FragmentPagerAdapter를 사용해야합니다.

Android.Support.V13.App.FragmentPagerAdapter

그런 다음 ViewPager를 제외하고 다른 모든 Fragment 관련 클래스를 "일반"라이브러리 / 네임 스페이스에서 사용할 수 있지만 큰 문제는 아닙니다.


다음은 완전성에 대한 샘플입니다 ( https://github.com/xamarin/monodroid-samples/ 에서 수정 된 "Support4"예제 ).

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
지원 라이브러리 13에서 중첩 조각과 getChildFragmentManager ()를 사용할 수 없다는 의미에서 혼란이 있습니다.
Yar

2

이 의존성을 gradle 의존성에 추가하십시오.

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

그리고 android.support.v13.app.FragmentPagerAdapter이와 같이 사용 하십시오 (안드로이드 스튜디오에서 공식 데모 프로젝트를 간단하게 수정했습니다 : 파일 → 새 → 새 프로젝트 → 다음 → 다음 → 탭 활동 → 다음 → 완료) :

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

AndroidX에서 2019 년 기준

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.