ProgressBar перестает вращаться в какой-то момент при загрузке данных внутри активности (Xamarin. Android) - PullRequest
0 голосов
/ 08 апреля 2020

У меня есть следующий экран:

enter image description here

Когда я нажимаю Ponentes ImageButton, появляется ProgressBar, пока данные внутри Ponentes активность загружается. Проблема в том, что он перестает вращаться в какой-то момент. Что может вызвать проблему и как я могу ее исправить?

Вот ProgressBar в Ponentes axml:

<ProgressBar
    android:id = "@+id/loadingSpinner"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:visibility="gone"
    android:gravity="center"/>

Вот OnCreate метод Ponentes Activity:

protected override async void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);
    SetContentView(Resource.Layout.SpeakersActivity);

    Android.Widget.Toolbar toolbar = FindViewById<Android.Widget.Toolbar>(Resource.Id.toolbar);
    toolbar.NavigationOnClick += delegate
    {
        this.OnBackPressed();
    };


    loadingSpinner = FindViewById<ProgressBar>(Resource.Id.loadingSpinner);
    loadingSpinner.Visibility = ViewStates.Visible;
    await Task.Run(() =>
    {
        //get all the speakers from the db
        allSpeakers = DatabaseHelper.GetAllFromTable<Speaker>("speakers.db");

        //get only the international spakers
        internationalSpeakers = allSpeakers.Where(x => x.Nationality.Equals("international")).ToList();

        //get only the national speakers
        nationalSpeakers = allSpeakers.Where(x => x.Nationality.Equals("national")).ToList();

        RunOnUiThread(() =>
        {
            speakersRecyclerView = FindViewById<RecyclerView>(Resource.Id.speakersRecyclerView);
            speakersLayoutManager = new LinearLayoutManager(this);
            speakersRecyclerView.SetLayoutManager(speakersLayoutManager);
            speakersAdapter = new SpeakersAdapter(internationalSpeakers);
            speakersAdapter.ItemClick += OnItemClick;
            speakersRecyclerView.SetAdapter(speakersAdapter);

            loadingSpinner.Visibility = ViewStates.Gone;
        });
     });

     internationalSpeakersTextView = FindViewById<TextView>(Resource.Id.internationalSpeakersTextView);
     internationalSpeakersTextView.Click += delegate
     {
            //change TextViews's style when selected/not-selected
            internationalSpeakersTextView.SetBackgroundResource(Resource.Drawable.textView_selected);
            nationalSpeakersTextView.SetBackgroundResource(Resource.Drawable.textView_unselected);

            LoadSpeakers(internationalSpeakers);
     };

     nationalSpeakersTextView = FindViewById<TextView>(Resource.Id.nationalSpeakersTextView);
     nationalSpeakersTextView.Click += delegate
     {
            //change TextViews's style when selected/not-selected
            nationalSpeakersTextView.SetBackgroundResource(Resource.Drawable.textView_selected);
            internationalSpeakersTextView.SetBackgroundResource(Resource.Drawable.textView_unselected);

            LoadSpeakers(nationalSpeakers);
     };
}

Если вы хотите, я могу вставить вам весь Ponentes Activity

1 Ответ

0 голосов
/ 13 апреля 2020

SpeakersActivity.cs:

[Activity(Label = "SpeakersActivity", ScreenOrientation = ScreenOrientation.Portrait)]
public class SpeakersActivity : BaseActivity
{
    TextView internationalSpeakersTextView;

    TextView nationalSpeakersTextView;

    RecyclerView speakersRecyclerView;

    // Layout manager that lays out each card in the RecyclerView:
    RecyclerView.LayoutManager speakersLayoutManager;

    // Adapter that accesses the data set (speakers):
    SpeakersAdapter speakersAdapter;

    /// <summary>
    /// List that contains all the speakers
    /// </summary>
    List<Speaker> allSpeakers;

    /// <summary>
    /// List that contains the international speakers
    /// </summary>
    List<Speaker> internationalSpeakers;

    /// <summary>
    /// List that contains the national speakers
    /// </summary>
    List<Speaker> nationalSpeakers;

    ProgressBar loadingSpinner;

    protected override async void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        SetContentView(Resource.Layout.SpeakersActivity);

        Android.Widget.Toolbar toolbar = FindViewById<Android.Widget.Toolbar>(Resource.Id.toolbar);
        toolbar.NavigationOnClick += delegate
        {
            this.OnBackPressed();
        };

        loadingSpinner = FindViewById<ProgressBar>(Resource.Id.loadingSpinner);
        loadingSpinner.Visibility = ViewStates.Visible;
        await Task.Run(() =>
        {
            //get all the speakers from the db
            allSpeakers = GetAllSpeakers();

            //get only the international spakers
            internationalSpeakers = allSpeakers.Where(x => x.Nationality.Equals("international")).ToList();

            //get only the national speakers
            nationalSpeakers = allSpeakers.Where(x => x.Nationality.Equals("national")).ToList();

            RunOnUiThread(() =>
            {
                speakersRecyclerView = FindViewById<RecyclerView>(Resource.Id.speakersRecyclerView);
                speakersLayoutManager = new LinearLayoutManager(this);
                speakersRecyclerView.SetLayoutManager(speakersLayoutManager);
                LoadSpeakers(internationalSpeakers);

                loadingSpinner.Visibility = ViewStates.Gone;
            });
        });

        internationalSpeakersTextView = FindViewById<TextView>(Resource.Id.internationalSpeakersTextView);
        internationalSpeakersTextView.Click += delegate
        {
            //change TextViews's style when selected/not-selected
            internationalSpeakersTextView.SetBackgroundResource(Resource.Drawable.textView_selected);
            nationalSpeakersTextView.SetBackgroundResource(Resource.Drawable.textView_unselected);

            LoadSpeakers(internationalSpeakers);
        };

        nationalSpeakersTextView = FindViewById<TextView>(Resource.Id.nationalSpeakersTextView);
        nationalSpeakersTextView.Click += delegate
        {
            //change TextViews's style when selected/not-selected
            nationalSpeakersTextView.SetBackgroundResource(Resource.Drawable.textView_selected);
            internationalSpeakersTextView.SetBackgroundResource(Resource.Drawable.textView_unselected);

            LoadSpeakers(nationalSpeakers);
        };
    }

    /// <summary>
    /// Load speakers inside activity
    /// </summary>
    /// <param name="speakers">speakers</param>
    private void LoadSpeakers(List<Speaker> speakers)
    {
        speakersAdapter = new SpeakersAdapter(speakers);
        speakersAdapter.ItemClick += OnItemClick;
        speakersRecyclerView.SetAdapter(speakersAdapter);
    }

    private void OnItemClick(object sender, string speakerResumeUrl)
    {
        var speakerDetailsActivity = new Intent(this, typeof(SpeakerDetailsActivity));
        speakerDetailsActivity.PutExtra("speakerResumeUrl", speakerResumeUrl);
        StartActivity(speakerDetailsActivity);
    }

    public override void OnBackPressed()
    {
        StartActivity(typeof(CongressActivity));
        Finish();
    }

private List<Speaker> GetAllSpeakers()
    {
        System.Threading.Thread.Sleep(4000);

        List<Speaker> speakers = new List<Speaker>();
        speakers.Add(new Speaker { Photo = "https://i.imgur.com/DDH2Ckk.png", Name = "Anne-Maree Keenan", Resume = "https://51congresopodologia.com/?page_id=4004", Nationality = "international" });
        speakers.Add(new Speaker { Photo = "https://i.imgur.com/DDH2Ckk.png", Name = "Anthony Redmond", Resume = "https://51congresopodologia.com/?page_id=4004", Nationality = "international" });
        speakers.Add(new Speaker { Photo = "https://i.imgur.com/DDH2Ckk.png", Name = "Chris Nester", Resume = "https://51congresopodologia.com/?page_id=4004", Nationality = "national" });
        speakers.Add(new Speaker { Photo = "https://i.imgur.com/DDH2Ckk.png", Name = "Amol Saxena", Resume = "https://51congresopodologia.com/?page_id=4004", Nationality = "international" });

        return speakers;
    }
}

SpeakersActivity.axml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:weightSum="100">
    <Toolbar 
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="?attr/actionBarSize"
        android:background="@color/appColor"
        android:navigationIcon="@drawable/ic_toolbar_back_button">
        <TextView
            android:text="Ponentes"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#FFFFFF"/>
    </Toolbar>
    <LinearLayout
        android:orientation="horizontal"
        android:minWidth="25px"
        android:minHeight="25px"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:weightSum="100"
        android:layout_weight="10">
        <TextView
            android:text="Internacionales"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:id="@+id/internationalSpeakersTextView"
            android:layout_weight="50"
            android:gravity="center"
            android:background="@drawable/textView_selected"/>
        <TextView
            android:text="Nacionales"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:id="@+id/nationalSpeakersTextView"
            android:layout_weight="50"
            android:gravity="center"
            android:background="@drawable/textView_unselected"/>
    </LinearLayout>
    <android.support.v7.widget.RecyclerView
        android:minWidth="25px"
        android:minHeight="25px"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:id="@+id/speakersRecyclerView"
        android:layout_weight="90"/>
    <ProgressBar
        android:id = "@+id/loadingSpinner"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone"
        android:gravity="center"/>
        <!--android:indeterminateDrawable="@drawable/animdraw"-->
</LinearLayout>

SpeakersAdapter.cs:

public class SpeakersAdapter : RecyclerView.Adapter
{
    public event EventHandler<string> ItemClick;
    public List<Speaker> listOfSpeakers;

    public SpeakersAdapter(List<Speaker> speakers)
    {
        listOfSpeakers = speakers;
    }

    public override int ItemCount
    {
        get { return listOfSpeakers.Count; }
    }

    void OnClick(int position)
    {
        if (ItemClick != null)
            ItemClick(this, listOfSpeakers[position].Resume);
    }

    public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
    {
        SpeakerViewHolder vh = holder as SpeakerViewHolder;

        var imageBitmap = GetImageBitmapFromUrl(listOfSpeakers[position].Photo);
        vh.speakerPhotoImageView.SetImageBitmap(imageBitmap);

        vh.speakerNameTextView.Text = listOfSpeakers[position].Name;
    }

    public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
    {
        View itemView = LayoutInflater.From(parent.Context).
                    Inflate(Resource.Layout.SpeakerCardView, parent, false);

        SpeakerViewHolder vh = new SpeakerViewHolder(itemView, OnClick);
        return vh;
    }

    private Bitmap GetImageBitmapFromUrl(string url)
    {
        Bitmap imageBitmap = null;

        using (var webClient = new WebClient())
        {
            var imageBytes = webClient.DownloadData(url);
            if (imageBytes != null && imageBytes.Length > 0)
            {
                imageBitmap = BitmapFactory.DecodeByteArray(imageBytes, 0, imageBytes.Length);
            }
        }

        return imageBitmap;
    }
}

SpeakerViewHolder.cs:

public class SpeakerViewHolder : RecyclerView.ViewHolder
{
    public ImageView speakerPhotoImageView { get; private set; }
    public TextView speakerNameTextView { get; private set; }
    public TextView speakerResumeTextView { get; private set; }

    // Get references to the views defined in the CardView layout.
    public SpeakerViewHolder(View itemView, Action<int> listener)
        : base(itemView)
    {
        // Locate and cache view references:
        speakerPhotoImageView = itemView.FindViewById<ImageView>(Resource.Id.speakerPhotoImageView);
        speakerNameTextView = itemView.FindViewById<TextView>(Resource.Id.speakerNameTextView);

        // Detect user clicks on the item view and report which item
        // was clicked (by layout position) to the listener:
        itemView.Click += (sender, e) => listener(base.LayoutPosition);
    }
}

textView_selected.xml:

<?xml version="1.0" encoding="utf-8" ?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    <solid android:color="#6495ED" />
    <stroke
      android:width="1dp"
      android:color="#DCDCDC" />
</shape>

textView_unselected.xml:

<?xml version="1.0" encoding="utf-8" ?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    <stroke
      android:width="1dp"
      android:color="#DCDCDC" />
</shape>

Я положил System.Threading.Thread.Sleep(4000); в методе GetAllSpeakers в SpeakersActivity в порядке чтобы имитировать задержку, когда я получаю записи из реальной базы данных. Скажите, если мне не хватает какого-то файла.

...