Search code examples
c#androidxamarinxamarin.androidnumberpicker

NumberPicker does not reset as you'd expect when scrolling to it's max value


I am making a score tracker in Xamarin.Android (not Forms) and am running into a problem with the NumberPicker. I tried searching for an answer, but I haven't been able to find anything like my problem. I am new to Xamarin (not C#), so I might just not know the right terms.

To keep things readable, I created a new project, which has the exact same bug.

The issue is easy to recreate: Create a new Xamarin.Android project (with the template that has the menu, FAB etc.)

I then added a NumberPicker to content_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:showIn="@layout/app_bar_main">
 
    <NumberPicker
        android:id="@+id/picker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center" />
 
</RelativeLayout>

And set things up in MainActivity.cs:

using System;
using Android.App;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using AndroidX.AppCompat.App;
using AndroidX.AppCompat.Widget;
using AndroidX.Core.View;
using AndroidX.DrawerLayout.Widget;
using Google.Android.Material.FloatingActionButton;
using Google.Android.Material.Navigation;
using Google.Android.Material.Snackbar;
using Toolbar = AndroidX.AppCompat.Widget.Toolbar;
 
namespace NumberPickerBugDemoProject
{
    [Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true)]
    public class MainActivity : AppCompatActivity, NavigationView.IOnNavigationItemSelectedListener
    {
        private Snackbar m_snackBar;
        private NumberPicker m_picker;
        private int m_score; // in actual app this is inside the model
 
        protected override void OnCreate(Bundle savedInstanceState)
        {
            // default code...
 
            SetupNumberPicker();
            CreateSnackbar(m_picker);
        }
 
        private void SetupNumberPicker()
        {
            m_picker = FindViewById<NumberPicker>(Resource.Id.picker);
 
            if (m_picker != null)
            {
                m_picker.Value = 0;
                m_picker.MinValue = 0;
                m_picker.MaxValue = 13;
                m_picker.WrapSelectorWheel = false;
 
                m_picker.ValueChanged += (sender, e) =>
                {
                    m_score = e.Picker.Value;
 
                    if (e.Picker.Value >= 13)
                    {
                        m_snackBar.Show();
                    }
                };
            }
        }
 
        private void CreateSnackbar(NumberPicker picker)
        {
            m_snackBar = Snackbar.Make(picker, "Reset?", Snackbar.LengthIndefinite);
            m_snackBar.SetAction("Action", (view) =>
            {
                m_picker.Value = 0;
                m_score = 0;
            });
        }
 
        // default code...
}

Then, when running on either emulated device or real device, the picker remains stuck on 13 after clicking the Action on the Snackbar. It doesn't seem to happen when inputting a number directly, but when spinning the Picker to 13 it will get stuck between 1-5 tries. It does reset after moving it back and forth (eg. 13->11; 11 -> 13 -> Snackbar shows again, click it and then it does reset).


Solution

  • I have created a new project to test the code your provided. And I can reproduce your problem when I scroll the number picker quickly.

    But the issue not appears every time. It only appear when I scroll it quickly to the value 13 and click the action quickly too.

    I have checked the code I used yesterday, if I removed the m_picker.WrapSelectorWheel = false;, this problem will never appear. In addition, I also tried your code in the native android project of the android studio and met the same problem.

    So you can post a new issue to the google developers community.