Search code examples
c#androidxamarinxamarin.android

TextView not displaying the string assigned to the Text property


I have a TextView defined like so:

<TextView
        android:id="@+id/middleText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Click the mail button" />

Which I get a reference to like so:

    private TextView _textView;

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        SetContentView(Resource.Layout.activity_main);

        _textView = FindViewById<TextView>(Resource.Id.middleText);

When a button in the view is clicked, the following code runs:

        if (_accelerometerController.IsStarted)
        {
            _accelerometerController.Stop();
            _timer?.Stop();
            _timer?.Dispose();
            _timer = null;
        }
        else
        {
            _accelerometerController.Start();
            _timer = new Timer(1000);
            _timer.Elapsed += Timer_Elapsed;
            _timer.AutoReset = true;
            _timer.Enabled = true;
        }

When the _timer.Elapsed event is invoked the following code runs:

    private void Timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        //MainThread.BeginInvokeOnMainThread(() => _textView.Text = _accelerometerController.Status);
        //_textView.SetText(_accelerometerController.Status, TextView.BufferType.Normal);
        //RunOnUiThread(() => _textView.Text = _accelerometerController.Status);
        _textView.Text = _accelerometerController.Status;
        _textView.Invalidate();
    }

The _textView.Text property is set correctly, but the graphic does most of the time not update to display the new string. Once the application chooses to not update the graphic, it does not recover and the text will be the same seemingly forever and when debugging I can see that the Text property is being set correctly and other controls continues to work. I've tried setting the text in a bunch of different ways but all yields the same result.

I'm am kind of new to Xamarin and I'm not sure about the project type, I chose the "Android App (Xamarin)" project template for this project and I'm unsure if that is the same as, or includes, Xamarin.Forms.

Why is this happening? How do I solve it?


Solution

  • If you use the Xamarin.Android project, you could refer to the code below.

    Layout:

    <LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/middleText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Click the mail button" />
    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    </LinearLayout>
    

    Activity: Due to i do not know what _accelerometerController is, i start the timer directly.

      public class Activity8 : Activity
    {
        private TextView _textView;
        private Button button;
    
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
    
            // Create your application here
    
            SetContentView(Resource.Layout.layout8);
            _textView = FindViewById<TextView>(Resource.Id.middleText);
            button = FindViewById<Button>(Resource.Id.button1);
    
            button.Click += Button_Click;
    
        }
    
        private void Button_Click(object sender, EventArgs e)
        {
            Timer _timer = new Timer(1000);
            _timer.Elapsed += Timer_Elapsed;
            _timer.AutoReset = true;
            _timer.Enabled = true;
        }
        private void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            //MainThread.BeginInvokeOnMainThread(() => _textView.Text = _accelerometerController.Status);
            //_textView.SetText(_accelerometerController.Status, TextView.BufferType.Normal);
            //RunOnUiThread(() => _textView.Text = _accelerometerController.Status);
            _textView.Text = "Hello";
            _textView.Invalidate();
        }
    }