Podsumowanie pytania: Jak mogę zrobić ProgressBar
integrację wewnątrz ActionBar
, tak jak w aplikacji Chrome?
Szczegóły: spójrz na ten zrzut ekranu z Chrome:
Chcę utworzyć pasek akcji, tak jak ten. Tuż pod paskiem akcji znajduje się pasek postępu, który wypełnia się zgodnie z ładowaniem strony. Widziałem ten przykład z wielu aplikacji, takich jak Feedly, ale nie byłem w stanie stworzyć własnej implementacji. Próbowałem użyć własnych interfejsów API Androida, aby go utworzyć:
@Override
protected void onCreate(Bundle savedInstanceState) {
//Request Permission to display the Progress Bar...
this.requestWindowFeature(Window.FEATURE_PROGRESS);
this.setWindowContentView(R.layout.activity_main)
super.onCreate(savedInstanceState);
this.setProgressBarIndeterminate(true);
}
Ale ten kod powoduje tylko wyświetlenie ProgressBar nad paskiem akcji, na przykład:
Jak więc mogę sprawić, by mój pasek ProgressBar pojawił się pod paskiem akcji, tak jak w aplikacji Chrome?
android
android-actionbar
android-progressbar
zubietaroberto
źródło
źródło
Odpowiedzi:
Jest to teraz natywne zachowanie, które można uzyskać za pomocą SwipeRefreshLayout .
Możesz zawinąć przewijalny widok za pomocą,
SwipeRefreshLayout
a następnie wystarczy odsłuchać zdarzenia onRefresh :@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container); swipeLayout.setOnRefreshListener(this); swipeLayout.setColorScheme(android.R.color.holo_blue_bright, android.R.color.holo_green_light, android.R.color.holo_orange_light, android.R.color.holo_red_light); } @Override public void onRefresh() { new Handler().postDelayed(new Runnable() { @Override public void run() { swipeLayout.setRefreshing(false); } }, 5000); }
Ładny i prosty poradnik można znaleźć na tym blogu .
źródło
Nie byłem w pełni zadowolony z zaakceptowanej odpowiedzi powyżej, więc sam przeprowadziłem dodatkowe badania.
Uważam, że sztuczka, której użyli, polega na tym, że pobrali widok z góry w wywołanej hierarchii widoków
DecorView
i dodali tam pasek postępu. W ten sposób pasek postępu wyświetla się zarówno nad paskiem akcji, jak i obszarem zawartości. Zwróć uwagę, że odpowiedź SD umieszcza pasek postępu w obszarze zawartości i „kradnie” miejsce z rzeczywistej treści, co może prowadzić do nieoczekiwanych wyników.Przykładowe zrzuty ekranu tej implementacji:
Kod
Po prostu wstaw ten kod do
onCreate
metody jakiejś aktywności i powinno zadziałać:// create new ProgressBar and style it final ProgressBar progressBar = new ProgressBar(this, null, android.R.attr.progressBarStyleHorizontal); progressBar.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 24)); progressBar.setProgress(65); // retrieve the top view of our application final FrameLayout decorView = (FrameLayout) getWindow().getDecorView(); decorView.addView(progressBar); // Here we try to position the ProgressBar to the correct position by looking // at the position where content area starts. But during creating time, sizes // of the components are not set yet, so we have to wait until the components // has been laid out // Also note that doing progressBar.setY(136) will not work, because of different // screen densities and different sizes of actionBar ViewTreeObserver observer = progressBar.getViewTreeObserver(); observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { View contentView = decorView.findViewById(android.R.id.content); progressBar.setY(contentView.getY() - 10); ViewTreeObserver observer = progressBar.getViewTreeObserver(); observer.removeOnGlobalLayoutListener(this); } });
Możesz grać z argumentem wysokości LayoutParams, aby ustawić pasek postępu na szerszy lub węższy, ale może być konieczne dostosowanie
-10
przesunięcia.Stylizacja
Niestety widać brzydkie szare tło paska postępu. Aby go usunąć, po prostu wyszukując tło według identyfikatora i próbując go ukryć, nie działa. Aby usunąć tło, musiałem stworzyć identyczny rysunek wersji systemu i usunąć element tła.
TL; DR: Utwórz plik
progress_horizontal_holo_no_background_light.xml
i wklej to do rysowania:<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/secondaryProgress"> <scale android:scaleWidth="100%" android:drawable="@drawable/progress_secondary_holo_light" /> </item> <item android:id="@android:id/progress"> <scale android:scaleWidth="100%" android:drawable="@drawable/progress_primary_holo_light" /> </item> </layer-list>
Skopiuj odpowiednie rysunki .png z
sdk/platforms/android-xx/data/res/drawable-xxx/
do swojego projektu, a następnie w kodzie możesz dodać:progressBar.setProgressDrawable(getResources().getDrawable(R.drawable.progress_horizontal_holo_no_background_light));
Dodatkowo: nieokreślony pasek postępu
Wersje nieokreślonych pasków postępu sprzed KitKata są dość brzydkie i opóźnione. Możesz pobrać nowy płynny pasek postępu o nazwie
ButteryProgressBar
. Po prostu wyszukaj go w google (nie mogę już dodawać linków, ponieważ jestem nowy tutaj: [), dodaj klasę do swojego projektu i możesz po prostu zastąpić poprzedni ProgressBar tym kodem i mieć chrupiący nieokreślony pasek postępu:final ButteryProgressBar progressBar = new ButteryProgressBar(this); progressBar.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 24));
Konieczne może być również uproszczenie tego kodu:
final TypedArray ta = c.obtainStyledAttributes(attrs, R.styleable.ButteryProgressBar); try { mBarColor = ta.getColor(R.styleable.ButteryProgressBar_barColor, c.getResources().getColor(android.R.color.holo_blue_light)); mSolidBarHeight = ta.getDimensionPixelSize( R.styleable.ButteryProgressBar_barHeight, Math.round(DEFAULT_BAR_HEIGHT_DP * mDensity)); mSolidBarDetentWidth = ta.getDimensionPixelSize( R.styleable.ButteryProgressBar_detentWidth, Math.round(DEFAULT_DETENT_WIDTH_DP * mDensity)); } finally { ta.recycle(); }
do tego kodu:
mBarColor = c.getResources().getColor(android.R.color.holo_blue_light); mSolidBarHeight = Math.round(DEFAULT_BAR_HEIGHT_DP * mDensity); mSolidBarDetentWidth = Math.round(DEFAULT_DETENT_WIDTH_DP * mDensity);
Mam nadzieję, że pomogłem :)
źródło
ButteryProgressBar
) z,ActionBarActivity
ale to nie działa. Jak mogę umieścić nieokreślony pasek postępu podActionBar/Toolbar
? To jest układ, którego używam: stackoverflow.com/a/26440880/1480019getSupportActionBar().getHeight()
funkcja działa, prawie gotowe .progressBar.setY()
Funkcja ustawia Stanowisko w stosunku do górnej części ekranu, w tym na pasku stanu. Więc co musisz zrobić, tosetY(supportActionBarHeight + Math.ceil(25 * context.getResources().getDisplayMetrics().density))
. Pasek stanu ma wysokość 25 pikseli (mdpi) i skaluje się z wyższą gęstością (hdpi / xhdpi / ...). Spróbuj i powiedz, czy działa.Rozszerz Działania z następującej klasy, aby mieć ProgressBar na górze (poniżej ActionBar) każdej z nich i
getProgressBar()
metodę:Klasa nadrzędna:
public abstract class ProgressActivity extends Activity { private ProgressBar mProgressBar; @Override public void setContentView(View view) { init().addView(view); } @Override public void setContentView(int layoutResID) { getLayoutInflater().inflate(layoutResID,init(),true); } @Override public void setContentView(View view, ViewGroup.LayoutParams params) { init().addView(view,params); } private ViewGroup init(){ super.setContentView(R.layout.progress); mProgressBar = (ProgressBar) findViewById(R.id.activity_bar); return (ViewGroup) findViewById(R.id.activity_frame); } protected ProgressBar getProgressBar(){ return mProgressBar; } }
Układ (progress.xml):
<?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"> <ProgressBar android:id="@+id/activity_bar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="-8dp" style="@android:style/Widget.DeviceDefault.ProgressBar.Horizontal" /> <FrameLayout android:id="@+id/activity_frame" android:layout_width="match_parent" android:layout_height="fill_parent" /> </LinearLayout>
źródło
android:layout_marginTop="-8dp"
do ProgressBar, aby zasymulować efekt „cienia”. Ale w przypadku tej metody prawdopodobnie bardziej wydajne jest dodanie jej do samego głównego układu. Jednak teraz działa zgodnie z przeznaczeniem. Dzięki za hack.Skompilowałem kod z tego wątku, a także innych wątków na StackOverflow i stworzyłem projekt, który może być użyty do implementacji ButteryProgessbar, a także do "pull down to refresh". https://github.com/pauldmps/Gmail-like-Pull-Down-to-Refresh
Zapraszam do wykorzystania kodu w swojej aplikacji.
Wielkie dzięki dla was.
źródło
Proszę użyć poniższego kodu. po prostu użyj jednego domyślnego stylu na pasku postępu jako
style="?android:attr/progressBarStyleHorizontal"
<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" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <ProgressBar android:layout_width="match_parent" android:layout_height="wrap_content" style="?android:attr/progressBarStyleHorizontal" android:indeterminate="true" /> </RelativeLayout>
źródło
Cóż, zrobiłem coś podobnego dla jednej z moich aplikacji dla zwierząt domowych i nie jestem pewien, czy to jedyny lub najlepszy sposób, aby to zrobić, ale zdecydowanie działa.
Na początek użyj paska akcji nakładki, a następnie ustaw tło, które można rysować na „null”, aby pasek akcji nakładki był przezroczysty.
Teraz w swoim układzie aktywności ustaw górny margines widoku głównego na „wysokość paska akcji”. Możesz to zrobić w ten sposób.
<RelativeLayout ... android:layout_marginTop="?android:attr/actionBarSize" />
Teraz akcja nie będzie ukrywać żadnej zawartości Twojej aktywności.
Następną rzeczą, którą musisz teraz zrobić, jest - dodaj widok nagłówka na górze widoku głównego o wysokości takiej samej jak pasek akcji. Ustaw kolor tła. Byłby to teraz kolor twojego paska akcji, a ponieważ pasek akcji jest idealnie wyrównany na górze tego widoku nagłówka.
Teraz możesz łatwo umieścić pasek postępu w widoku nagłówka i wyrównać go do dołu widoku nagłówka. Dla użytkownika wyglądałoby to tak, jakby pasek postępu znajdował się na samym pasku akcji, podobnie jak chrome.
źródło