Using the “animated circle” in an ImageView while loading stuff

后端 未结 6 633
轻奢々
轻奢々 2020-11-29 14:27

I am currently using in my application a listview that need maybe one second to be displayed.

What I currently do is using the @id/android:empty property of the list

相关标签:
6条回答
  • 2020-11-29 15:04

    Simply put this block of xml in your activity layout file:

    <RelativeLayout
        android:id="@+id/loadingPanel"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center" >
    
        <ProgressBar
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:indeterminate="true" />
    </RelativeLayout>
    

    And when you finish loading, call this one line:

    findViewById(R.id.loadingPanel).setVisibility(View.GONE);
    

    The result (and it spins too):

    enter image description here

    0 讨论(0)
  • 2020-11-29 15:09

    If you would like to not inflate another view just to indicate progress then do the following:

    1. Create ProgressBar in the same XML layout of the list view.
    2. Make it centered
    3. Give it an id
    4. Attach it to your listview instance variable by calling setEmptyView

    Android will take care the progress bar's visibility.

    For example, in activity_main.xml:

        <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.fcchyd.linkletandroid.MainActivity">
    
        <ListView
            android:id="@+id/list_view_xml"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:divider="@color/colorDivider"
            android:dividerHeight="1dp" />
    
       <ProgressBar
            android:id="@+id/loading_progress_xml"
            style="?android:attr/progress"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true" />
    
    </RelativeLayout>
    

    And in MainActivity.java:

    package com.fcchyd.linkletandroid;
    
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.widget.ArrayAdapter;
    import android.widget.ListView;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import retrofit2.Call;
    import retrofit2.Callback;
    import retrofit2.Response;
    import retrofit2.Retrofit;
    import retrofit2.converter.gson.GsonConverterFactory;
    
    public class MainActivity extends AppCompatActivity {
    
    final String debugLogHeader = "Linklet Debug Message";
    Call<Links> call;
    List<Link> arraylistLink;
    ListView linksListV;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        linksListV = (ListView) findViewById(R.id.list_view_xml);
        linksListV.setEmptyView(findViewById(R.id.loading_progress_xml));
        arraylistLink = new ArrayList<>();
    
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://api.links.linklet.ml")
                .addConverterFactory(GsonConverterFactory
                        .create())
                .build();
    
        HttpsInterface HttpsInterface = retrofit
                .create(HttpsInterface.class);
    
        call = HttpsInterface.httpGETpageNumber(1);
    
        call.enqueue(new Callback<Links>() {
            @Override
            public void onResponse(Call<Links> call, Response<Links> response) {
                try {
                    arraylistLink = response.body().getLinks();
    
                    String[] simpletTitlesArray = new String[arraylistLink.size()];
                    for (int i = 0; i < simpletTitlesArray.length; i++) {
                        simpletTitlesArray[i] = arraylistLink.get(i).getTitle();
                    }
                    ArrayAdapter<String> simpleAdapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1, simpletTitlesArray);
                    linksListV.setAdapter(simpleAdapter);
                } catch (Exception e) {
                    Log.e("erro", "" + e);
                }
            }
    
            @Override
            public void onFailure(Call<Links> call, Throwable t) {
    
            }
        });
    
    
    }
    

    }

    0 讨论(0)
  • 2020-11-29 15:09

    For the ones developing in Kotlin, there is a sweet method provided by the Anko library that makes the process of displaying a ProgressDialog a breeze!

    Based on that link:

    val dialog = progressDialog(message = "Please wait a bit…", title = "Fetching data")
    dialog.show()
    //....
    dialog.dismiss()
    

    This will show a Progress Dialog with the progress % displayed (for which you have to pass the init parameter also to calculate the progress).

    There is also the indeterminateProgressDialog() method, which provides the Spinning Circle animation indefinitely until dismissed:

    indeterminateProgressDialog("Loading...").show()
    

    Shout out to this blog which led me to this solution.

    0 讨论(0)
  • 2020-11-29 15:13

    You can do this by using the following xml

    <RelativeLayout
        style="@style/GenericProgressBackground"
        android:id="@+id/loadingPanel"
        >
        <ProgressBar
            style="@style/GenericProgressIndicator"/>
    </RelativeLayout>
    

    With this style

    <style name="GenericProgressBackground" parent="android:Theme">
        <item name="android:layout_width">fill_parent</item>    
        <item name="android:layout_height">fill_parent</item>
        <item name="android:background">#DD111111</item>    
        <item name="android:gravity">center</item>  
    </style>
    <style name="GenericProgressIndicator" parent="@android:style/Widget.ProgressBar.Small">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:indeterminate">true</item> 
    </style>
    

    To use this, you must hide your UI elements by setting the visibility value to GONE and whenever the data is loaded, call setVisibility(View.VISIBLE) on all your views to restore them. Don't forget to call findViewById(R.id.loadingPanel).setVisiblity(View.GONE) to hide the loading animation.

    If you dont have a loading event/function but just want the loading panel to disappear after x seconds use a Handle to trigger the hiding/showing.

    0 讨论(0)
  • 2020-11-29 15:21

    This is generally referred to as an Indeterminate Progress Bar or Indeterminate Progress Dialog.

    Combine this with a Thread and a Handler to get exactly what you want. There are a number of examples on how to do this via Google or right here on SO. I would highly recommend spending the time to learn how to use this combination of classes to perform a task like this. It is incredibly useful across many types of applications and will give you a great insight into how Threads and Handlers can work together.

    I'll get you started on how this works:

    The loading event starts the dialog:

    //maybe in onCreate
    showDialog(MY_LOADING_DIALOG);
    fooThread = new FooThread(handler);
    fooThread.start();
    

    Now the thread does the work:

    private class FooThread extends Thread {
        Handler mHandler;
    
        FooThread(Handler h) {
            mHandler = h;
        }
    
        public void run() { 
            //Do all my work here....you might need a loop for this
    
            Message msg = mHandler.obtainMessage();
            Bundle b = new Bundle();                
            b.putInt("state", 1);   
            msg.setData(b);
            mHandler.sendMessage(msg);
        }
    }
    

    Finally get the state back from the thread when it is complete:

    final Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            int state = msg.getData().getInt("state");
            if (state == 1){
                dismissDialog(MY_LOADING_DIALOG);
                removeDialog(MY_LOADING_DIALOG);
            }
        }
    };
    
    0 讨论(0)
  • 2020-11-29 15:24

    You can use this code from firebase github samples ..

    You don't need to edit in layout files ... just make a new class "BaseActivity"

    package com.example;
    
    import android.app.ProgressDialog;
    import android.support.annotation.VisibleForTesting;
    import android.support.v7.app.AppCompatActivity;
    
    
    public class BaseActivity extends AppCompatActivity {
    
        @VisibleForTesting
        public ProgressDialog mProgressDialog;
    
        public void showProgressDialog() {
            if (mProgressDialog == null) {
                mProgressDialog = new ProgressDialog(this);
                mProgressDialog.setMessage("Loading ...");
                mProgressDialog.setIndeterminate(true);
            }
    
            mProgressDialog.show();
        }
    
    
        public void hideProgressDialog() {
            if (mProgressDialog != null && mProgressDialog.isShowing()) {
                mProgressDialog.dismiss();
            }
        }
    
        @Override
        public void onStop() {
            super.onStop();
            hideProgressDialog();
        }
    
    }
    

    In your Activity that you want to use the progress dialog ..

    public class MyActivity extends BaseActivity
    

    Before/After the function that take time

    showProgressDialog();
    .... my code that take some time
    showProgressDialog();
    
    0 讨论(0)
提交回复
热议问题