Панель прогресса Android в кнопке

Есть ли возможность отображать вращающийся индикатор выполнения кнопкой? Например, в качестве фонового рисунка?

Да.

Вы можете создать AnimationDrawable, как описано здесь , а затем использовать тег drawableLeft (например) в XML вашей кнопки. вот так:

 <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> 

Да … Просто оберните вокруг кнопки и progressBar внутри Relative Layout, так …

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

Хотел опубликовать образец изображения, но пока у меня недостаточно репутации …;)

У меня была такая же проблема, поэтому я создал специальную кнопку для этого: LoadingProgressButton

Включите эту кнопку:

  <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 --> 

И используйте его вот так:

  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(); 

Введите описание изображения здесь

Я сделал пример кода, как показано ниже. Я надеюсь, что мои коды помогут вам 🙂

[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]

 <?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> 

[Код активности]

 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; } } 

Другой вариант – использовать отличные Spezi-Views , он содержит ProgressButton, который довольно прост в использовании:

 <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" /> 

И в коде:

 ... //show a rotation spinner, and no text (or the loading text) progressButton.enableLoadingState(); //show no animation, but the selected/ unselected text progressButton.disableLoadingState(); ... 

Чтобы сделать Animatable , вам необходимо расширить класс Button и вызвать Animatable.start() для drawables. Я сделал реализацию для этого:

 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(); } } }