我正在尝试设计一些与此设计非常相似的东西材料设计网站 https://material.google.com/components/cards.html#cards-content.
所以基本上,我有一个 CardView 列表,每个 CardView 都有多个视图,用户可以在它们之间滑动。 (图中第一张卡片)
我首先实现了一个包含 CardView 的简单 recyclerview,对于每个 CardView,我实现了一个 FragmentStatePagerAdapter,其中包含用户可以滑动的多个片段,并且它可以工作(有点)。
我面临的问题与这个问题非常相似ViewPager中使用FragmentPagerAdapter的Fragment第二次查看时为空白 https://stackoverflow.com/questions/7746652/fragment-is-blank-the-second-time-it-is-viewed片段要么无法加载,要么在您上下滚动时消失。我已经尝试了人们建议的所有可能的修复方法,但仍然无法使其发挥作用。
我想知道是否有更好的方法。
这是我的代码(C# - Xamarin)
using System;
using Android.Support.V7.Widget;
using System.Collections.Generic;
using Android.Views;
using Android.Widget;
using System.Security.Cryptography;
using Android.Support.V4.View;
using Android.Support.V4.App;
using Android.Runtime;
using Android.OS;
using Android.Content;
using Android.App;
using Android.Support.V7.App;
using JavaString = Java.Lang.String;
using Android.Util;
using Android.Animation;
using System.ComponentModel.Design.Serialization;
namespace Answers.PortalAppXamarin.Droid
{
public enum MyTestAdapterItemType {
Type1,
Type2,
Type3
};
public class MyTestDataObj
{
public MyTestAdapterItemType type { get; set; }
public string data { get; set; }
}
public class PagerFragmentAdapter : Android.Support.V4.App.FragmentStatePagerAdapter {
public List<MyTestPageFragmentContainer> Tabs { get; set; }
public PagerFragmentAdapter(Android.Support.V4.App.FragmentManager fm) : base(fm) {
}
public override Android.Support.V4.App.Fragment GetItem(int position) {
return Tabs [position].Fragment;
}
public override Java.Lang.ICharSequence GetPageTitleFormatted(int position)
{
return new JavaString(Tabs [position].Title);
}
public override int GetItemPosition (Java.Lang.Object objectValue) {
for (int i = 0; i < Tabs.Count; i++) {
if (Tabs[i].Fragment.Equals (objectValue) ) {
return i;
}
}
return PositionNone;
}
public override int Count {
get {
return Tabs.Count;
}
}
}
public class MyTestPageFragmentContainer {
public string Title { get; set; }
public Android.Support.V4.App.Fragment Fragment { get; set; }
public MyTestPageFragmentContainer(string title, Android.Support.V4.App.Fragment fragment)
{
this.Title = title;
this.Fragment = fragment;
}
}
public class BaseFragment : Android.Support.V4.App.Fragment
{
public static Android.Support.V4.App.Fragment newInstance(int position) {
BaseFragment f = new BaseFragment ();
// Supply num input as an argument.
Bundle args = new Bundle ();
args.PutInt ("num", position);
f.Arguments = (args);
return f;
}
}
public class PageFragment1 : BaseFragment {
View RootView;
public override void OnCreate (Bundle savedInstanceState)
{
base.OnCreate (savedInstanceState);
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
RootView = inflater.Inflate (Resource.Layout.LoadingIndicatorOverlay, container, false);
return RootView;
}
public override void OnResume ()
{
base.OnResume ();
ValueAnimator _animator = ValueAnimator.OfFloat(0, 1);
_animator.SetDuration(2000);
_animator.Update += (object sender, ValueAnimator.AnimatorUpdateEventArgs e) => {
if (RootView != null) {
RootView.Alpha = (float)e.Animation.AnimatedValue;
}
};
}
}
public class PageFragment2 : BaseFragment {
View RootView;
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
RootView = inflater.Inflate(Resource.Layout.MeasureListItem, container, false);
return RootView;
}
public override void OnResume ()
{
base.OnResume ();
ValueAnimator _animator = ValueAnimator.OfFloat(0, 1);
_animator.SetDuration(2000);
_animator.Update += (object sender, ValueAnimator.AnimatorUpdateEventArgs e) => {
if (RootView != null) {
RootView.Alpha = (float)e.Animation.AnimatedValue;
}
};
}
}
public abstract class BaseCardViewHolder : RecyclerView.ViewHolder
{
public ViewGroup Header;
public ViewGroup Footer;
public TextView TitleTextView;
public Button MoreInfoBtn;
public ViewPager ContentViewPager;
public PagerFragmentAdapter Adapter;
public List<MyTestPageFragmentContainer> Tabs;
public Android.Support.V4.App.FragmentManager fm;
public BaseCardViewHolder(View rootView, Android.Support.V4.App.FragmentManager fm) : base(rootView)
{
Header = rootView.FindViewById<ViewGroup> (Resource.Id.card_view_header);
Footer = rootView.FindViewById<ViewGroup> (Resource.Id.card_view_footer);
ContentViewPager = rootView.FindViewById<ViewPager> (Resource.Id.card_view_content_viewPager);
TitleTextView = Header.FindViewById<TextView> (Resource.Id.card_view_title);
MoreInfoBtn = Footer.FindViewById<Button> (Resource.Id.card_view_moreInfoBtn);
this.fm = fm;
Tabs = setupTabs ();
if (Tabs != null && fm != null) {
Adapter = new PagerFragmentAdapter (fm);
Adapter.Tabs = Tabs;
ContentViewPager.Adapter = Adapter;
}
}
public void RefreshViewPager()
{
ContentViewPager.Adapter.NotifyDataSetChanged ();
}
public abstract List<MyTestPageFragmentContainer> setupTabs ();
}
public class Type1ViewHolder : BaseCardViewHolder
{
public Type1ViewHolder(View v, Android.Support.V4.App.FragmentManager fm) : base(v, fm)
{
}
public override List<MyTestPageFragmentContainer> setupTabs()
{
return new List<MyTestPageFragmentContainer> {
new MyTestPageFragmentContainer ("Tab1", new PageFragment1 ()),
new MyTestPageFragmentContainer ("Tab2", new PageFragment1 ())
};
}
}
public class Type2ViewHolder : BaseCardViewHolder
{
public Type2ViewHolder(View v, Android.Support.V4.App.FragmentManager fm) : base(v, fm)
{
}
public override List<MyTestPageFragmentContainer> setupTabs()
{
return new List<MyTestPageFragmentContainer> {
new MyTestPageFragmentContainer ("Tab1", new PageFragment2 ()),
new MyTestPageFragmentContainer ("Tab2", new PageFragment2 ()),
new MyTestPageFragmentContainer ("Tab1", new PageFragment1 ()),
new MyTestPageFragmentContainer ("Tab2", new PageFragment1 ()),
};
}
}
public class Type3ViewHolder : BaseCardViewHolder
{
public Type3ViewHolder(View v, Android.Support.V4.App.FragmentManager fm) : base(v, fm)
{
}
public override List<MyTestPageFragmentContainer> setupTabs()
{
return new List<MyTestPageFragmentContainer> {
new MyTestPageFragmentContainer ("Tab1", new PageFragment2 ()),
new MyTestPageFragmentContainer ("Tab2", new PageFragment1 ()),
new MyTestPageFragmentContainer ("Tab3", new PageFragment2 ()),
new MyTestPageFragmentContainer ("Tab4", new PageFragment1 ())
};
}
}
public class MyTestRecyclerAdapter : RecyclerView.Adapter
{
public Android.Support.V4.App.FragmentManager FM;
readonly List<MyTestDataObj> myTestDataList = new List<MyTestDataObj>{
new MyTestDataObj {type = MyTestAdapterItemType.Type1, data = "Item 1"},
new MyTestDataObj {type = MyTestAdapterItemType.Type1, data = "Item 2"},
new MyTestDataObj {type = MyTestAdapterItemType.Type2, data = "Item 3"},
new MyTestDataObj {type = MyTestAdapterItemType.Type3, data = "Item 4"},
new MyTestDataObj {type = MyTestAdapterItemType.Type1, data = "Item 5"},
new MyTestDataObj {type = MyTestAdapterItemType.Type2, data = "Item 6"},
new MyTestDataObj {type = MyTestAdapterItemType.Type1, data = "Item 7"},
new MyTestDataObj {type = MyTestAdapterItemType.Type1, data = "Item 8"},
new MyTestDataObj {type = MyTestAdapterItemType.Type2, data = "Item 9"},
new MyTestDataObj {type = MyTestAdapterItemType.Type3, data = "Item 10"},
new MyTestDataObj {type = MyTestAdapterItemType.Type1, data = "Item 11"},
new MyTestDataObj {type = MyTestAdapterItemType.Type2, data = "Item 12"},
new MyTestDataObj {type = MyTestAdapterItemType.Type1, data = "Item 13"},
new MyTestDataObj {type = MyTestAdapterItemType.Type1, data = "Item 14"},
new MyTestDataObj {type = MyTestAdapterItemType.Type2, data = "Item 15"},
new MyTestDataObj {type = MyTestAdapterItemType.Type3, data = "Item 16"},
new MyTestDataObj {type = MyTestAdapterItemType.Type1, data = "Item 17"},
new MyTestDataObj {type = MyTestAdapterItemType.Type2, data = "Item 18"},
new MyTestDataObj {type = MyTestAdapterItemType.Type1, data = "Item 19"},
new MyTestDataObj {type = MyTestAdapterItemType.Type1, data = "Item 20"},
new MyTestDataObj {type = MyTestAdapterItemType.Type2, data = "Item 21"},
new MyTestDataObj {type = MyTestAdapterItemType.Type3, data = "Item 22"},
new MyTestDataObj {type = MyTestAdapterItemType.Type1, data = "Item 23"},
new MyTestDataObj {type = MyTestAdapterItemType.Type2, data = "Item 24"},
};
#region implemented abstract members of Adapter
public override void OnBindViewHolder (RecyclerView.ViewHolder holder, int position)
{
MyTestDataObj item = myTestDataList [position];
switch (GetItemViewType (position)) {
case (int) MyTestAdapterItemType.Type1:
{
((Type1ViewHolder)holder).TitleTextView.Text = item.data;
((Type1ViewHolder)holder).RefreshViewPager ();
break;
}
case (int) MyTestAdapterItemType.Type2:
{
((Type2ViewHolder)holder).TitleTextView.Text = item.data;
((Type2ViewHolder)holder).RefreshViewPager ();
break;
}
case (int) MyTestAdapterItemType.Type3:
{
((Type3ViewHolder)holder).TitleTextView.Text = item.data;
((Type3ViewHolder)holder).RefreshViewPager ();
break;
}
}
}
public override RecyclerView.ViewHolder OnCreateViewHolder (Android.Views.ViewGroup parent, int viewType)
{
LayoutInflater layoutInflater = LayoutInflater.From (parent.Context);
switch (viewType) {
case (int) MyTestAdapterItemType.Type1:
{
return new Type1ViewHolder (layoutInflater.Inflate (Resource.Layout.MyTestCardViewLayout, parent, false), FM);
}
case (int) MyTestAdapterItemType.Type2:
{
return new Type2ViewHolder (layoutInflater.Inflate (Resource.Layout.MyTestCardViewLayout, parent, false), FM);
}
case (int) MyTestAdapterItemType.Type3:
{
return new Type3ViewHolder (layoutInflater.Inflate (Resource.Layout.MyTestCardViewLayout, parent, false), FM);
}
}
return null;
}
public override int ItemCount {
get {
return myTestDataList.Count;
}
}
public override int GetItemViewType (int position)
{
return (int)myTestDataList [position].type;
}
#endregion
}
}
这是演示:
Note: I'm sure that its possible, since the for both iOS and Android is having the exact same design that I'm looking for.
我将不胜感激任何帮助,谢谢