Bir şey yüklerken ImageView'de “animasyonlu çemberi” kullanma


219

Şu anda benim uygulamada belki bir saniye görüntülenmesi gereken bir liste görünümü kullanıyorum.

Şu anda bir "yükleme" metin oluşturmak için listview @ id / android: empty özelliğini kullanmak.

 <TextView android:id="@id/android:empty"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:background="#FF0000"
           android:text="Loading..."/>

Şimdi, bu metin yerine bir yükleme iletişim kutusunda kullanılan animasyonlu daire ile değiştirmek istiyorum, sanırım hepiniz ne demek istediğimi biliyorsunuz:

Düzenleme: Bir iletişim kutusu istemiyorum. Bunu düzenimin içinde göstermek istiyorum.

http://flexfwd.com/DesktopModules/ATI_Base/resources/images/loading_blue_circle.gif

Yardımınız için çok teşekkürler!

Yanıtlar:


443

Bu xml bloğunu etkinlik düzeni dosyanıza koymanız yeterlidir:

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

Ve yüklemeyi bitirdiğinizde, bu tek satır olarak adlandırın:

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

Sonuç (ve ayrıca dönüyor):

resim açıklamasını buraya girin


17
+1 düğmesini çökertti
TSR

Bunun bir ImageView'da animasyonlu bir daire gösterme sorununu nasıl çözdüğünü göremiyorum.
Gustavo

4
@Gustavo, istediği şey, "belirsiz ilerleme animasyonu" göstermek için, bu yüzden sorunu çözdüğünü düşünüyorum. ; -]
Thalis Vilela

143

Bunu aşağıdaki xml'yi kullanarak yapabilirsiniz

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

Bu tarz ile

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

Bunu kullanmak için, görünürlük değerini GONE olarak ayarlayarak UI öğelerinizi gizlemeniz gerekir ve veriler her yüklendiğinde setVisibility(View.VISIBLE)geri yüklemek için tüm görünümlerinizi arayın . findViewById(R.id.loadingPanel).setVisiblity(View.GONE)Yükleme animasyonunu gizlemek için aramayı unutmayın .

Bir yükleme etkinliğiniz / fonksiyonunuz yoksa, ancak yükleme panelinin x saniye sonra kaybolmasını istiyorsanız , gizlemeyi / gösterimi tetiklemek için bir Tutamaç kullanın.


4
Mükemmel cevap. Google arama yoluyla bulundu ve sorunumu da çözdü. Teşekkürler!
Dave

Bu yöntemi kullanarak findViewById(...).setVisibility(View.GONE), ekranı döndürdüğümde satırda bir NullPointerException alıyorum. Bir yönde bir çekicilik gibi çalışır, ancak bunun neden kırıldığına dair herhangi bir fikir var mı?
Kalina

Bir sorum var. RelativeLayout'um, Doğrusal Düzenin içindeki iki düğme arasında ve düğmeler arasında da bulunur. Bunu çalıştırdığımda tüm ekranı kaplıyor. Bu yükleme çubuğunu iki düğme arasında tutmaya ilişkin herhangi bir ipucu var mı?
Alioo

Peki, kodu findViewById(R.id.loadingPanel).setVisiblity(View.GONE)ikinci etkinliğe nereye koymalıyım ? Bu bulamıyorum viewhiçbir olmadığından setContnetView()2 fragmanı aktivitesinde yöntemi. Teşekkürler!
Alston

10

Bu genellikle Belirsiz İlerleme Çubuğu veya Belirsiz İlerleme İletişim Kutusu olarak adlandırılır.

Tam olarak ne istediğinizi elde etmek için bunu bir İş Parçacığı ve İşleyici ile birleştirin . Bunu Google üzerinden veya doğrudan SO üzerinden nasıl yapacağınıza dair birkaç örnek vardır. Böyle bir görevi gerçekleştirmek için sınıfların bu kombinasyonunu nasıl kullanacağınızı öğrenmek için zaman harcamanızı şiddetle tavsiye ederim. Birçok uygulama türü için inanılmaz derecede faydalıdır ve Konuların ve İşleyicilerin birlikte nasıl çalışabileceği konusunda size harika bir fikir verecektir.

Bunun nasıl çalıştığına başlayacağım:

Loading olayı iletişim kutusunu başlatır:

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

Şimdi iş parçacığı çalışır:

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

Son olarak, tamamlandığında durumu iş parçacığından geri alın:

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

2
Cevabınız gerçekten hoş görünüyor, ancak bunu mizanpajımın içine eklemek istiyorum ... Venkatesh'in cevabı kullanımım için daha uygun görünüyor.Geri bildirimde bulunmaya çalışacağım. Zaman ayırdığınız için çok teşekkür ederiz!
Waza_Be

Bunun için teşekkürler, aslında hem XML hem de programlı şeyler yapmak için çözüm bulmak iyidir.
Neon Warge

1

Sadece ilerlemeyi göstermek için başka bir görünümü şişirmek istemiyorsanız, aşağıdakileri yapın:

  1. Liste görünümü ile aynı XML düzeninde ProgressBar oluşturun.
  2. Merkezleyin
  3. Kimlik verin
  4. SetEmptyView öğesini çağırarak listview örneği değişkeninize ekleyin

Android, ilerleme çubuğunun görünürlüğünü koruyacaktır.

Örneğin, içinde 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>

Ve içinde 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) {

        }
    });


}

}


ProgressBar, RelativeLayout içinde ikinci noktada olmalıdır, aksi takdirde ikinci noktadaki Görünüm'ün arkasında (benim durumumda bir ImageView ve
davanızdaki

1

Bu kodu firebase github örneklerinden kullanabilirsiniz .

Düzen dosyalarında düzenleme yapmanız gerekmez ... sadece yeni bir sınıf "BaseActivity" yapın

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

}

Faaliyetinizde ilerleme iletişim kutusunu kullanmak istediğiniz ..

public class MyActivity extends BaseActivity

Zaman alan fonksiyondan önce / sonra

showProgressDialog();
.... my code that take some time
showProgressDialog();

0

Kotlin'de gelişenlere, Anko kütüphanesi tarafından sağlanan veProgressDialog esinti yapma sürecini bir esinti haline getiren tatlı bir yöntem var !

Bu bağlantıya dayanarak:

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

Bu, ilerleme% 'si görüntülenen bir İlerleme İletişim Kutusu gösterecektir ( initilerlemeyi hesaplamak için parametreyi de geçmeniz gerekir ).

Ayrıca, indeterminateProgressDialog()Dönme Çemberi animasyonunu yok olana kadar süresiz olarak sağlayan bir yöntem de vardır :

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

Beni bu çözüme götüren bu bloga bağır .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.