OnScrollChanged没有获得RecyclerView参数

时间:2018-05-13 17:48:27

标签: c# android android-recyclerview onscrollchanged

我试图在我的项目中实现此代码:https://startupriteofpassage.wordpress.com/2014/09/04/android-fading-action-bar-in-xamarin-c/

不同之处在于,我使用RecyclerView而不是ScrollView,而不是将我的RecyclerView直接放在我所拥有的Activity中,而是在片段中设置我需要的监听器。 问题是虽然每次滚动时实际调用OnScrollChanged(int l,int t,int oldl,int oldt),但它获得的参数总是0,我不明白为什么,所以ScrollChangedTarget不会这样做。按预期工作。

这是自定义的RecyclerView:

 public class NotifyingScrollRecyclerView : RecyclerView
{
    private Activity activity;
    private View headerView;
    private View footerView;

    public delegate void ScrollChangedHandler(int l, int t, int oldl, int oldt, EventArgs e);

    public event ScrollChangedHandler scrollChanged;
    public EventArgs e = null;

    //Enabling all required constructors
    public NotifyingScrollRecyclerView(Context context) : base(context)
    {

    }

    public NotifyingScrollRecyclerView(Context context, IAttributeSet attrs) : base(context, attrs)
    {

    }

    public NotifyingScrollRecyclerView(IntPtr ptr, JniHandleOwnership ownership) : base(ptr, ownership)
    {

    }

    public NotifyingScrollRecyclerView(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
    {

    }

    //This method attribute allows us to register the inbuilt OnScrollChanged event that fires when scrolling a ScrollView
    [Android.Runtime.Register("onScrollChanged", "(IIII)V", "GetOnScrollChanged_IIIIHandler")]
    protected override void OnScrollChanged(int l, int t, int oldl, int oldt)
    {
        base.OnScrollChanged(l, t, oldl, oldt);
        scrollChanged(l, t, oldl, oldt, e);
    }



}


//Set an event listener
public class ScrollViewChangedListener
{
    private Activity activity;
    private NotifyingScrollRecyclerView scrollView;
    private Android.Support.V7.App.ActionBar actionBar;
    private Drawable actionBarDrawable;
  be changed
    public ScrollViewChangedListener(Activity a, NotifyingScrollRecyclerView n)
    {
        n.scrollChanged += ScrollChangedTarget;
        this.activity = a;
        this.scrollView = n;
        this.actionBar = ((UserPageActivity)a).SupportActionBar;

        this.actionBarDrawable = a.GetDrawable(Resource.Drawable.actionbar_background);
        this.actionBarDrawable.SetAlpha(0);

    }

    //Handle the changing of the scroll
    public void ScrollChangedTarget(int l, int t, int oldl, int oldt, EventArgs e)
    {
        //You set the View you want to be your header as a header height, and then get it's height
        int headerHeight = activity.FindViewById<ImageView>(Resource.Id.profilebanner).Height -
        this.actionBar.Height;
        float ratio = (float)Math.Min(Math.Max(t, 0), headerHeight) / headerHeight;
        int newAlpha = (int)(ratio * 255);

            this.actionBarDrawable.SetAlpha(newAlpha);
            this.actionBar.SetBackgroundDrawable(this.actionBarDrawable);


    }

}

这是调用片段的Activity(除非在这种情况下调用片段,否则它不会做任何事情):

[Activity(Label = "UserPageActivity")]
public class UserPageActivity : BaseActivity
{
    protected override int LayoutResource => Resource.Layout.activity_user_page;
    UserViewModel viewModel;
    TextView username;
    TextView usernameToolbar;
    Button followButton;


    ViewPager pager;
    UserTabsAdapter adapter;
    bool IsLoggedUser;

    protected override void OnCreate(Bundle savedInstanceState)
    {
        IsLoggedUser = Intent.GetStringExtra("userId").Equals(LoginController.GetInstance().CurrentUser.Email);
        base.OnCreate(savedInstanceState);
        viewModel = new UserViewModel();
        viewModel.UserLoaded += new UserViewModel.UserLoadedHandler(OnUserLoaded);
        viewModel.LoadUserCommand.Execute(Intent.GetStringExtra("userId"));
        username = FindViewById<TextView>(Resource.Id.profilename);
        usernameToolbar = FindViewById<TextView>(Resource.Id.usernamePage);
        followButton = FindViewById<Button>(Resource.Id.followButton);

        username.Text = Intent.GetStringExtra("username");
        usernameToolbar.Text = Intent.GetStringExtra("username");

        adapter = new UserTabsAdapter(this, SupportFragmentManager);
        pager = FindViewById<ViewPager>(Resource.Id.user_viewpager);
        var tabs = FindViewById<TabLayout>(Resource.Id.tabs);
        pager.Adapter = adapter;
        tabs.SetupWithViewPager(pager);
        pager.OffscreenPageLimit = 5;


        pager.PageSelected += (sender, args) =>
        {
            var fragment = adapter.InstantiateItem(pager, args.Position) as IFragmentVisible;

            fragment?.BecameVisible();
        };
    }

    private void OnUserLoaded(bool loaded)
    {

    }

    protected override void OnStart()
    {
        base.OnStart();

        if (IsLoggedUser)
        {
            followButton.Visibility = ViewStates.Gone;

        }
        else
        {
            bool following;
            if (LoginController.GetInstance().CurrentUser.FollowsUsers.ContainsKey(Intent.GetStringExtra("userId")))
            {
                followButton.Text = "Unfollow";
                following = true;
            }
            else
            {
                followButton.Text = "Follow";
                following = false;
            }

            followButton.Click += (object sender, EventArgs e) =>
            {
                followButton.Enabled = false;
                if (following)
                {
                    UserService service = ServiceLocator.Instance.Get<UserService>();

                    service.SetUser(LoginController.GetInstance().CurrentUser);
                    service.RemoveFollowsUserCommand.Execute(viewModel.LoadedUser.Email);

                    service.SetUser(viewModel.LoadedUser);
                    service.RemoveFollowedByUserCommand.Execute(LoginController.GetInstance().CurrentUser.Email);

                    followButton.Text = "Follow";
                    following = false;
                }
                else
                {
                    UserService service = ServiceLocator.Instance.Get<UserService>();

                    service.SetUser(LoginController.GetInstance().CurrentUser);
                    service.AddFollowsUserCommand.Execute(viewModel.LoadedUser);

                    service.SetUser(viewModel.LoadedUser);
                    service.AddFollowedByUserCommand.Execute(LoginController.GetInstance().CurrentUser);

                    followButton.Text = "Unfollow";
                    following = true;
                }
                followButton.Enabled = true;
            };
        }
    }
}

class UserTabsAdapter : FragmentStatePagerAdapter
{
    string[] titles;

    public override int Count => titles.Length;

    public UserTabsAdapter(Context context, Android.Support.V4.App.FragmentManager fm) : base(fm)
    {
        titles = context.Resources.GetTextArray(Resource.Array.user_sections);
    }

    public override Java.Lang.ICharSequence GetPageTitleFormatted(int position) =>
                        new Java.Lang.String(titles[position]);

    public override Android.Support.V4.App.Fragment GetItem(int position)
    {
        switch (position)
        {
            case 0: return UserContestsFragment.NewInstance();
            case 1: return UserPartecipationsFragment.NewInstance();
            case 2: return GlobalContestFragment.NewInstance();
            case 3: return MessagesFragment.NewInstance();
        }
        return null;
    }

    public override int GetItemPosition(Java.Lang.Object frag) => PositionNone;
}

这是为recyclerview设置监听器的片段:

      public class UserContestsFragment : AbstractRefresherFadingToolbarFragment<Contest>
{
    public static UserContestsFragment NewInstance() =>
        new UserContestsFragment { Arguments = new Bundle() };


    public override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
    }

    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        ContestViewModel viewModel = new ContestViewModel();
        base.ViewModel = viewModel;
        base.LoadItemsCommand = viewModel.LoadAllByCreatorUserCommand;
        base.param = Activity.Intent.GetStringExtra("userId");
        base.adapter = new ContestsAdapter(Activity, viewModel);
        var view = base.OnCreateView(inflater, container, savedInstanceState);

        ScrollViewChangedListener listener = new ScrollViewChangedListener(Activity, recyclerView);
        return view;
    }

这是该片段所需的抽象片段,负责设置布局:

  public abstract class AbstractRefresherFadingToolbarFragment<T> : Android.Support.V4.App.Fragment, IFragmentVisible
{
    public ICollectionViewModel<T> ViewModel;
    public ICommand LoadItemsCommand;
    public object param; //parametro per il LoadItemsCommand
    public ItemsAdapter<T> adapter;
    public SwipeRefreshLayout refresher;
    public ProgressBar progress;
    public NotifyingScrollRecyclerView recyclerView;
    //LruCache cache = new LruCache((int)(Runtime.GetRuntime().MaxMemory() / 4));

    public override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
    }

    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View view = inflater.Inflate(Resource.Layout.fragment_fading_toolbar, container, false);
        recyclerView = view.FindViewById<NotifyingScrollRecyclerView>(Resource.Id.recyclerView);
        //ScrollViewChangedListener listener = new ScrollViewChangedListener((UserPageActivity)Activity, recyclerView);
        //adapter.cache = cache;
        recyclerView.HasFixedSize = true;
        recyclerView.SetAdapter(adapter);
        recyclerView.SetItemViewCacheSize(4);
        //recyclerView.ChildViewAttachedToWindow += new EventHandler<RecyclerView.ChildViewAttachedToWindowEventArgs>(OnChildViewAttached);
        //recyclerView.ChildViewDetachedFromWindow += new EventHandler<RecyclerView.ChildViewDetachedFromWindowEventArgs>(OnChildViewDetached);

        refresher = view.FindViewById<SwipeRefreshLayout>(Resource.Id.refresher);
        refresher.SetColorSchemeColors(Resource.Color.accent);

        progress = view.FindViewById<ProgressBar>(Resource.Id.progressbar_loading);
        progress.Visibility = ViewStates.Gone;

        return view;
    }


}

1 个答案:

答案 0 :(得分:0)

我没有阅读您的整个代码,但我查看了您在问题中链接的网站。要使用的隐藏操作栏的功能由支持库中的CollapsingToolbarLayout处理。要了解如何使用它,请转到Cheesesquare。它是支持库小部件的完整示例,无需任何更改即可构建和运行。

编辑: RecyclerView有一个名为AddOnScrollListener的方法。使用它而不是OnScrollChanged。如果您使用RecyclerView中的继承类,则可以在该类的所有构造函数中调用它。