android - progressbar - Usar el "círculo animado" en un ImageView mientras carga cosas
progressbar circular en android studio (5)
Actualmente estoy usando en mi aplicación una vista de lista que puede necesitar un segundo para mostrarse.
Lo que hago actualmente es usar la propiedad @ id / android: empty de la vista de lista para crear un texto de "carga".
<TextView android:id="@id/android:empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF0000"
android:text="Loading..."/>
Ahora, me gustaría reemplazar eso con el círculo animado que se usa en un diálogo de carga en lugar de este texto, supongo que todos saben lo que quiero decir:
Editar: no quiero un diálogo. Quiero mostrar eso dentro de mi diseño.
¡Muchas gracias por tu ayuda!
Esto generalmente se conoce como una barra de progreso indeterminada o un cuadro de diálogo de progreso indeterminado.
Combine esto con un Thread y un Handler para obtener exactamente lo que desea. Hay una serie de ejemplos sobre cómo hacer esto a través de Google o aquí en SO. Recomiendo encarecidamente dedicar el tiempo para aprender a usar esta combinación de clases para realizar una tarea como esta. Es increíblemente útil en muchos tipos de aplicaciones y le dará una gran idea de cómo los hilos y manipuladores pueden trabajar juntos.
Te enseñaré cómo funciona esto:
El evento de carga inicia el diálogo:
//maybe in onCreate
showDialog(MY_LOADING_DIALOG);
fooThread = new FooThread(handler);
fooThread.start();
Ahora el hilo hace el trabajo:
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);
}
}
Finalmente, recupere el estado del hilo cuando esté completo:
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);
}
}
};
Puedes hacer esto usando el siguiente xml
<RelativeLayout
style="@style/GenericProgressBackground"
android:id="@+id/loadingPanel"
>
<ProgressBar
style="@style/GenericProgressIndicator"/>
</RelativeLayout>
Con este estilo
<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>
Para usar esto, debe ocultar sus elementos de UI configurando el valor de visibilidad en GONE y cada vez que se carguen los datos, llame a setVisibility(View.VISIBLE)
en todas sus vistas para restaurarlas. No olvides llamar a findViewById(R.id.loadingPanel).setVisiblity(View.GONE)
para ocultar la animación de carga.
Si no tiene un evento / función de carga pero solo desea que el panel de carga desaparezca después de x segundos, use un Handle para activar el ocultamiento / presentación.
Puedes usar este código de firebase github samples ..
No necesita editar en archivos de diseño ... simplemente haga una nueva clase "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();
}
}
En tu actividad, quieres usar el diálogo de progreso.
public class MyActivity extends BaseActivity
Antes / Después de la función que lleva tiempo
showProgressDialog();
.... my code that take some time
showProgressDialog();
Si no desea inflar otra vista solo para indicar el progreso, haga lo siguiente:
- Cree ProgressBar en el mismo diseño XML de la vista de lista.
- Hazlo centrado
- Darle una identificación
- Adjúntelo a su variable de instancia listview llamando a setEmptyView
Android se ocupará de la visibilidad de la barra de progreso.
Por ejemplo, en 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>
Y en 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) {
}
});
}
}
Simplemente coloque este bloque de xml en su archivo de diseño de actividad:
<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>
Y cuando termine de cargar, llame a esta línea:
findViewById(R.id.loadingPanel).setVisibility(View.GONE);
El resultado (y también gira):