通过TabLayout / ViewPager具有片段的可重用布局

问题描述 投票:0回答:1

我正在尝试重新创建旧应用,因为我完全丢失了项目文件。我可以通过apk反编译获得一些XML UI文件,但是现在我陷入了一个相当复杂的情况。我正在尝试通过TabLayoutViewPager创建动态片段。我记得上次做同样的事情时,没有为此创建一堆布局文件,而恢复的UI文件支持了我的想法。

无论如何,现在我正在使用一个base_layout_file,该文件包含我的TabLayout和ViewPager,然后在我的片段的每个实例中加载一个包含RecyclerView的单个布局文件,以在每个片段中显示一些数据。

我记得使用此代码来生成多个选项卡及其布局,它们工作正常,但现在不起作用。它可以替换每个RecyclerView中的所有数据,并且最多仅显示一个RecylerView与数据,而其他所有为空,这可能是因为它们具有相同的ID。但是它过去没有发生过,所以我不确定如何从这里继续。

如果我无法将相同的UI重复用于多个片段,那么可重复使用的UI在这里是什么意思。我确定我为每个数据收集都创建了一个新的片段。

代码如下:

var viewPager = FindViewById<ViewPager>(Resource.Id.main_tabs_viewpager);
var tabLayout = FindViewById<TabLayout>(Resource.Id.main_tabs_header);
tabLayout.TabMode = TabLayout.ModeScrollable;
tabLayout.SetupWithViewPager(viewPager);
var data = await Web.GetSchedule(); // a Dictionary<type> here
var tabsAdapter = new PageTabsAdapter(SupportFragmentManager);
viewPager.Adapter = tabsAdapter;
if (data != null)
{
    foreach (var item in data)
}
tabsAdapter.AddTab(new TitleFragment() { Title = item.Key, Fragmnet = new MainTabs(DataEnum.MainTabsType.Schedule, item.Value) });

Tabs_Adapter:

// TABS ADAPTER

    public class TitleFragment
    {
        public string Title { get; set; }
        public Fragment MyFragment { get; set; }
    }


    private List<TitleFragment> Fragments { get; set; }

        public PageTabsAdapter(FragmentManager manager) : base(manager/*, BehaviorResumeOnlyCurrentFragment*/)
        {
            Fragments = new List<TitleFragment>();
        }

        public override int Count => Fragments == null ? 0 : Fragments.Count;

        public override Fragment GetItem(int position)
        {
            return Fragments[position].MyFragment;
        }

        public override ICharSequence GetPageTitleFormatted(int position)
        {
            return new Java.Lang.String(Fragments[position].Title);
        }

        public bool AddTab(TitleFragment fragment)
        {
            if (Fragments == null || fragment == null) return false;

            Fragments.Add(fragment);
            NotifyDataSetChanged();
            return true;
        }

片段类(重新创建其实例):

// Fragment Class
        public MainTabs(DataEnum.MainTabsType tabType)
        {
            this.tabType = tabType;
        }

        public MainTabs(DataEnum.MainTabsType tabType, List<CalenderScheduleList> items) : this(tabType)
        {
            this.items = items;
        }

        public override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            // Create your fragment here
        }

        public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            if (inflater == null) throw new ArgumentNullException(nameof(inflater));
            // Use this to return your custom view for this Fragment
            if (tabType == DataEnum.MainTabsType.TVSchedule)
            {
                return inflater.Inflate(Resource.Layout.tv_schedule_list, container, false);
            }
            return null;
        }

        public override void OnViewCreated(View view, Bundle savedInstanceState)
        {
            base.OnViewCreated(view, savedInstanceState);
            if (tabType == DataEnum.MainTabsType.TVSchedule)
            {
                recyclerView = Activity.FindViewById<RecyclerView>(Resource.Id.schedule_rv);
                emptyView = Activity.FindViewById<TextView>(Resource.Id.schedule_emptytext);
                emptyView.Visibility = ViewStates.Gone;
            }
            LoadDataForType();
        }

        private void LoadDataForType()
        {
            switch (tabType)
            {
                case DataEnum.MainTabsType.Schedule:
                    var scheduleAdapter = new EpisodesAdapter<CalenderScheduleList>(items, tabType, emptyView);
                    recyclerView.SetAdapter(scheduleAdapter);
                    scheduleAdapter.ItemClick += delegate
                    {
                        Toast.MakeText(Activity, "Item clicked", ToastLength.Short).Show();
                    };
                    break;

                default:
                    break;
            }

        }

布局文件:

// main_tabs
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:id="@+id/tabParent"
    android:background="@android:color/transparent"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">
    <android.support.design.widget.TabLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:minHeight="?actionBarSize"
        android:id="@+id/main_tabs_header"
        android:elevation="@dimen/tabs_elevation"
        android:background="@color/colorPrimary"
        app:tabIndicatorColor="@color/colorPrimaryDark"
        app:tabMode="fixed"
        app:tabGravity="fill"
        app:tabTextAppearance="@android:style/TextAppearance.Widget.TabWidget" />
    <android.support.v4.view.ViewPager
        android:id="@+id/main_tabs_viewpager"
        android:background="#00000000"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />
</LinearLayout>


// base_layout

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <include
       layout="@layout/main_toolbar"/>

    <include
        layout="@layout/main_tabs"/>

    <ProgressBar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/schedule_loading"
        android:indeterminate="true"
        />
</android.support.design.widget.CoordinatorLayout>


// recycler_view

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/schedule_rv"
        android:clipToPadding="false"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/empty_data_view"
        android:id="@+id/schedule_emptytext"
        style="@style/TextAppearance.AppCompat.Title"
        android:textAlignment="center"
        android:layout_centerVertical="true"/>
</RelativeLayout>

[请帮助我了解我在做什么错?我尝试搜索此特定问题,但尚未找到任何有用的信息。我正在使用支持库,并且还尝试了具有相同结果的新AndroidX库。我正在将Visual Studio 2019社区版与Xamarin用于Android。

编辑:添加了更多信息

编辑:问题GIF

请注意,当选择新选项卡但该选项卡中没有数据时,数据会发生更改。

enter image description here

android-layout android-fragments xamarin.android
1个回答
0
投票

上述情况的问题在这里是双重的:

[如果您看上面的代码,您会发现我在Fragment类的OnCreateView函数中返回了夸大的布局(到目前为止很好),然后我通过父级在OnViewCreated函数中找到了自己的视图Activity从Android的角度来看这是错误的,您不应该这样做。我很难学到它。

事实证明,您应该通过展开的视图找到您的视图,并可能在OnCreateView函数中找到它们,并且现在我更改了代码,一切都按预期工作。

因此OnCreateView中的上述代码如下:

var view = LayoutInflater.Inflate(Resource.Layout.your_xml, container, false);
recyclerView = view.FindViewById<RecyclerView>(Resource.Id.main_popular_shows_rv);
emptyView = view.FindViewById<TextView>(Resource.Id.main_popular_shows_emptytext);
loadingView = view.FindViewById<ProgressBar>(Resource.Id.main_popular_shows_loading);
return view;

我希望它对整个过程有所帮助。


0
投票

上述情况的问题在这里是双重的:

[如果您看上面的代码,您会发现我正在Fragment类的OnCreateView函数中返回一个夸大的布局(到目前为止很好),然后我通过父级在OnViewCreated函数中找到了自己的视图Activity从Android的角度来看这是错误的,您不应该这样做。我很难学到它。

事实证明,您应该通过展开的视图找到您的视图,并可能在OnCreateView函数中找到它们,并且现在我更改了代码,一切都按预期工作。

因此OnCreateView中的上面的代码如下:

var view = LayoutInflater.Inflate(Resource.Layout.your_xml, container, false);
recyclerView = view.FindViewById<RecyclerView>(Resource.Id.main_popular_shows_rv);
emptyView = view.FindViewById<TextView>(Resource.Id.main_popular_shows_emptytext);
loadingView = view.FindViewById<ProgressBar>(Resource.Id.main_popular_shows_loading);
return view;

我希望它能对整个过程有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.