2011-01-23 9 views
26

¿Hay alguna posibilidad de mostrar una barra de progreso girando en un botón? p. como fondo dibujable?Barra de progreso de Android en el botón

+0

Creé mi propia clase para que parezca que un botón es mucho más simple y más limpio y no es necesario crear un proceso asincrónico – ademar111190

+0

También tengo otra solución: simplemente haga un Framelayout y presione Textview y una barra de progreso en eso. Luego configure onClickListener en FrameLayout. Esto le proporcionará más flexibilidad al crear el diseño :) – Fabian

Respuesta

26

Sí.

Puede crear una AnimationDrawable, como se describe here, y luego usar la etiqueta drawableLeft (por ejemplo) en el XML de su botón. de este modo:

<Button 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:background="@drawable/your_background_drawable_resource" 
     android:drawableLeft="@drawable/your_animation_drawable_resource" 
     android:text="@string/your_text_res"> 
</Button> 
+0

Thx! ¡Esto funciona bien para mi! – Fabian

3

hice un código de ejemplo, como a continuación .. espero que mis códigos :)

[main.xml]

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:gravity="center" 
    > 

    <Button 
     android:id="@+id/wheel_button" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:background="@drawable/icon_spin_animation" 
     /> 
</LinearLayout> 

[icon_spin_animation.xml] ayudan

<?xml version="1.0" encoding="utf-8"?> 
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/selected" android:oneshot="false"> 

    <item android:drawable="@drawable/wheel_db_update01" android:duration="50"/> 
    <item android:drawable="@drawable/wheel_db_update02" android:duration="50"/> 
    <item android:drawable="@drawable/wheel_db_update03" android:duration="50"/> 
    <item android:drawable="@drawable/wheel_db_update04" android:duration="50"/> 
    <item android:drawable="@drawable/wheel_db_update05" android:duration="50"/> 
    <item android:drawable="@drawable/wheel_db_update06" android:duration="50"/> 

</animation-list> 

[Código de Actividad]

public class ProgressOnTheButtonActivity extends Activity implements OnClickListener { 
    /** Called when the activity is first created. */ 
    AnimationDrawable mFrameAnimation = null; 

    boolean mbUpdating = false; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     Button btnWheel = (Button)findViewById(R.id.wheel_button); 
     btnWheel.setOnClickListener(this); 

     mFrameAnimation = (AnimationDrawable) btnWheel.getBackground(); 
    } 

    public void onClick(View v) { 
     if(v.getId() == R.id.wheel_button) { 
      if(!mbUpdating) { 
       mbUpdating = true; 
       new AsyncTaskForUpdateDB().execute(""); 
      } 
     } 

    } 

    private class AsyncTaskForUpdateDB extends AsyncTask<String, Integer, ResultOfAsyncTask> {  

     @Override 
     protected void onPreExecute() { 

      mFrameAnimation.start(); 
      super.onPreExecute(); 
     } 

     @Override 
     protected ResultOfAsyncTask doInBackground(String... strData) { 
      ResultOfAsyncTask result = new ResultOfAsyncTask(); 

      try { 
       Thread.sleep(5000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 

      return result; 
     } 

     @Override 
     protected void onPostExecute(ResultOfAsyncTask result) { 
      mFrameAnimation.stop(); 
      mbUpdating = false; 
     } 

     @Override 
     protected void onCancelled() { 
      mFrameAnimation.stop(); 
      mbUpdating = false; 
      super.onCancelled(); 
     } 

     @Override 
     protected void onProgressUpdate(Integer... progress) { 
     } 
    } 

    private class ResultOfAsyncTask { 
     int iErrorCode = 0; 
    } 
} 
1

Otra opción es utilizar el ingenioso Spezi-Views, contiene un ProgressButton que es bastante fácil de usar:

<de.halfreal.spezi.views.ProgressButton 
     android:id="@+id/button1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Press me" 
     app:selectedText="I am loaded" 
     app:unselectedText="Press me again" 
     app:loadingDrawable="@drawable/spinner" 
     /> 

y en el código:

... 
//show a rotation spinner, and no text (or the loading text) 
progressButton.enableLoadingState(); 

//show no animation, but the selected/ unselected text 
progressButton.disableLoadingState(); 
... 
+0

Gracias por esta información .... Esto es fácil y simple de usar :) – Devrath

16

Sí ... Sólo envolver tanto el botón como la Barra de progreso dentro de un Diseño relativo, como ...

<?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="1"> 

    <RelativeLayout 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center_horizontal"> 

     <ProgressBar 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:id="@+id/progressBar" 
      android:layout_gravity="right" 
      android:layout_alignTop="@+id/btnConnect" 
      android:layout_alignRight="@+id/btnConnect" 
      android:layout_alignEnd="@+id/btnConnect" /> 

     <Button 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="Connect" 
      android:id="@+id/btnConnect" 
      android:layout_gravity="center_horizontal" 
      android:layout_marginTop="30dp" 
      android:width="200dp" 
      android:focusable="false" 
      android:focusableInTouchMode="false" /> 
    </RelativeLayout> 

    <TextView 
     android:id="@+id/txtConnectStatus" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_below="@+id/btnConnect" 
     android:layout_alignParentBottom="true" 
     android:layout_centerHorizontal="true" 
     android:text="Status : Not connected" 
     android:textSize="12dp" 
     android:layout_gravity="center_horizontal" /> 

    <LinearLayout 
     android:orientation="vertical" 

quería publicar la imagen de muestra, pero no tengo la reputación suficiente por el momento ...;)

+0

En realidad, me gusta este método mejor a medida que gana más control sobre la ocultación de la barra de progreso con la animación. –

+0

Ahora puede publicar la imagen. Buena reputación que tiene. – XoXo

1

Para hacer Animatable dibujables funcione, es necesario extender la clase Button y llame Animatable.start() para dibujables. He hecho una aplicación para esto:

package com.example.yourapplication; 

import android.content.Context; 
import android.graphics.drawable.Animatable; 
import android.graphics.drawable.Drawable; 
import android.support.v7.widget.AppCompatButton; 
import android.util.AttributeSet; 

public class AnimateCompoundDrawableButton extends AppCompatButton { 

    public AnimateCompoundDrawableButton(Context context) { 
     super(context); 
    } 

    public AnimateCompoundDrawableButton(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public AnimateCompoundDrawableButton(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
    } 

    @Override 
    public void setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom) { 
     super.setCompoundDrawables(left, top, right, bottom); 

     startIfAnimatable(left); 
     startIfAnimatable(top); 
     startIfAnimatable(right); 
     startIfAnimatable(bottom); 
    } 

    @Override 
    public void setCompoundDrawablesRelative(Drawable start, Drawable top, Drawable end, Drawable bottom) { 
     super.setCompoundDrawablesRelative(start, top, end, bottom); 

     startIfAnimatable(start); 
     startIfAnimatable(top); 
     startIfAnimatable(end); 
     startIfAnimatable(bottom); 
    } 

    @Override 
    protected void onAttachedToWindow() { 
     super.onAttachedToWindow(); 

     // Makes a copy of the array, however we cannot do this otherwise. 
     for (Drawable drawable : getCompoundDrawables()) { 
      startIfAnimatable(drawable); 
     } 
    } 

    @Override 
    protected void onDetachedFromWindow() { 
     super.onDetachedFromWindow(); 

     // Makes a copy, however we cannot do this otherwise. 
     for (Drawable drawable : getCompoundDrawables()) { 
      stopIfAnimatable(drawable); 
     } 
    } 

    private void startIfAnimatable(Drawable drawable) { 
     if (drawable instanceof Animatable) { 
      ((Animatable) drawable).start(); 
     } 
    } 

    private void stopIfAnimatable(Drawable drawable) { 
     if (drawable instanceof Animatable) { 
      ((Animatable) drawable).stop(); 
     } 
    } 
} 
13

que estaba teniendo el mismo problema, así que creé un botón especializado para esto: LoadingProgressButton

Incluir el botón de la siguiente manera:

<br.com.simplepass.loading_button_lib.CircularProgressButton 
android:id="@+id/btn_id" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:background="@drawable/circular_border_shape" 
    app:spinning_bar_width="4dp" <!-- Optional --> 
    app:spinning_bar_color="#FFF" <!-- Optional --> 
    app:spinning_bar_padding="6dp" <!-- Optional --> 

y utilizar de esta manera:

CircularProgressButton btn = (CircularProgressButton) findViewById(R.id.btn_id) 
      btn.startAnimation(); 
       [do some async task. When it finishes] 

       //You can choose the color and the image after the loading is finished 
       btn.doneLoagingAnimation(fillColor, bitmap); 
       [or just revert de animation] 
       btn.revertAnimation(); 

enter image description here

Cuestiones relacionadas