Niestandardowy do rysowania dla ProgressBar / ProgressDialog

130

Czytając ograniczoną dokumentację dostarczoną przez Google, mam wrażenie, że można zmienić wygląd (możliwy do rysowania) ProgressBar / ProgressDialog, po prostu tworząc nowy styl i przypisując go do właściwości stylu ProgressBar. Ale nie mogę sprawić, żeby to działało poprawnie. Oto co zrobiłem do tej pory:

Utworzyłem taki kształt (mp2.xml)

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
  android:shape="ring"
  android:innerRadiusRatio="4"
  android:thicknessRatio="4"
  android:useLevel="false">
 <size android:width="50dip" android:height="50dip" />
 <gradient android:type="sweep" android:useLevel="false" android:startColor="#300000ff" android:centerColor="#500000ff" android:endColor="#ff0000ff" />
</shape>

następnie utworzył animację (mp3.xml) w następujący sposób:

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
 <item android:duration="70">
  <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/mp2" android:pivotX="50%" android:pivotY="50%" android:fromDegrees="0" android:toDegrees="30" android:repeatCount="1" />
 </item>
 <item android:duration="70">
  <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/mp2" android:pivotX="50%" android:pivotY="50%" android:fromDegrees="30" android:toDegrees="60" android:repeatCount="1" />
 </item>
 <item android:duration="70">
  <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/mp2" android:pivotX="50%" android:pivotY="50%" android:fromDegrees="60" android:toDegrees="90" android:repeatCount="1" />
 </item>
 <item android:duration="70">
  <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/mp2" android:pivotX="50%" android:pivotY="50%" android:fromDegrees="90" android:toDegrees="120" android:repeatCount="1" />
 </item>
 <item android:duration="70">
  <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/mp2" android:pivotX="50%" android:pivotY="50%" android:fromDegrees="120" android:toDegrees="150" android:repeatCount="1" />
 </item>
 <item android:duration="70">
  <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/mp2" android:pivotX="50%" android:pivotY="50%" android:fromDegrees="150" android:toDegrees="180" android:repeatCount="1" />
 </item>
 <item android:duration="70">
  <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/mp2" android:pivotX="50%" android:pivotY="50%" android:fromDegrees="180" android:toDegrees="210" android:repeatCount="1" />
 </item>
 <item android:duration="70">
  <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/mp2" android:pivotX="50%" android:pivotY="50%" android:fromDegrees="210" android:toDegrees="240" android:repeatCount="1" />
 </item>
 <item android:duration="70">
  <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/mp2" android:pivotX="50%" android:pivotY="50%" android:fromDegrees="240" android:toDegrees="270" android:repeatCount="1" />
 </item>
 <item android:duration="70">
  <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/mp2" android:pivotX="50%" android:pivotY="50%" android:fromDegrees="270" android:toDegrees="300" android:repeatCount="1" />
 </item>
 <item android:duration="70">
  <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/mp2" android:pivotX="50%" android:pivotY="50%" android:fromDegrees="300" android:toDegrees="330" android:repeatCount="1" />
 </item>
 <item android:duration="70">
  <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/mp2" android:pivotX="50%" android:pivotY="50%" android:fromDegrees="330" android:toDegrees="360" android:repeatCount="1" />
 </item>
</animation-list>

następnie utworzył styl (attrs.xml) taki jak ten:

<?xml version="1.0" encoding="utf-8"?>
<resources>
 <style parent="@android:style/Widget.ProgressBar" name="customProgressBar">
  <item name="android:progressDrawable">@anim/mp3</item>
 </style>
</resources>

aw moim main.xml ustawiłem styl w następujący sposób:

<?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:drawingCacheQuality="high">
 <ProgressBar android:id="@+id/ProgressBar01"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content" style="@style/customProgressBar"/>
</LinearLayout>

Ale nadal pokazuje to samo, co wcześniej. Co ja robię źle?

Sam
źródło
Po prostu przeglądałem próbki i natknąłem się na twoje po przeczytaniu tego . Mam nadzieję, że to rozwiąże Twój problem.
reuscam
Wiedziałem, jak tworzyć kształty / gradienty / animacje. Ten, który utworzyłem powyżej, jest oparty na poście, do którego się odnosisz (musiałem go nieco zmienić, ponieważ wygląda bardzo niepewnie i wolno). Miałem tylko nadzieję, że uda mi się to osiągnąć używając „stylu”. Mimo wszystko dzięki za odpowiedź
Sam
Jeśli chcesz całkowicie dostosować swój pasek postępu i naprawdę spodobać się, zajrzyj do tego wpisu na blogu. Może to być trochę poza tym, czego chciałeś lub może być po prostu tym, czego szukasz. Mam nadzieję, że to pomoże!
jagsaund

Odpowiedzi:

144

Użyłem poniższego do stworzenia niestandardowego paska postępu.

Plik res/drawable/progress_bar_states.xmldeklaruje kolory różnych stanów:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:id="@android:id/background">
        <shape>
            <gradient
                    android:startColor="#000001"
                    android:centerColor="#0b131e"
                    android:centerY="0.75"
                    android:endColor="#0d1522"
                    android:angle="270"
            />
        </shape>
    </item>

    <item android:id="@android:id/secondaryProgress">
        <clip>
            <shape>
                <gradient
                        android:startColor="#234"
                        android:centerColor="#234"
                        android:centerY="0.75"
                        android:endColor="#a24"
                        android:angle="270"
                />
            </shape>
        </clip>
    </item>

    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <gradient
                    android:startColor="#144281"
                    android:centerColor="#0b1f3c"
                    android:centerY="0.75"
                    android:endColor="#06101d"
                    android:angle="270"
                />
            </shape>
        </clip>
    </item>

</layer-list>

A kod wewnątrz twojego układu xml:

<ProgressBar android:id="@+id/progressBar"
    android:progressDrawable="@drawable/progress_bar_states"
    android:layout_width="fill_parent" android:layout_height="8dip" 
    style="?android:attr/progressBarStyleHorizontal" 
    android:indeterminateOnly="false" 
    android:max="100">
</ProgressBar>

Cieszyć się!

Jona
źródło
@YuliaRogovaya czy to dlatego, że elementy do rysowania nie znajdują się w elementach klipu? Nie mogłem też sprawić, żeby to zadziałało; podejrzewam, że kluczem jest element klipu.
Andrew Wyld
2
jak to zrobić za ProgressDialog?
Nezam
@Nezam Nie mogę podać dokładnego kodu ani próbek, ale musisz to zrobić. Podaj motyw niestandardowy do ProgressDialog. Motyw niestandardowy definiowałby styl paska postępu.
Jona
Byłoby miło zobaczyć zrzut ekranu tego obiektu w akcji
QED
@Jona Wiem, że minęło trochę czasu, ale jak mogę zmniejszyć wysokość tego elementu do rysowania?
leofontes
55

Miałem problemy z używaniem okna dialogowego nieokreślonego postępu z rozwiązaniem tutaj, po kilku pracach i próbach i błędach udało mi się go uruchomić.

Najpierw utwórz animację, której chcesz użyć w oknie dialogowym postępu. W moim przypadku użyłem 5 zdjęć.

../res/anim/progress_dialog_icon_drawable_animation.xml:

<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/icon_progress_dialog_drawable_1" android:duration="150" />
    <item android:drawable="@drawable/icon_progress_dialog_drawable_2" android:duration="150" />
    <item android:drawable="@drawable/icon_progress_dialog_drawable_3" android:duration="150" />
    <item android:drawable="@drawable/icon_progress_dialog_drawable_4" android:duration="150" />
    <item android:drawable="@drawable/icon_progress_dialog_drawable_5" android:duration="150" />
</animation-list>

Gdzie chcesz wyświetlić okno dialogowe ProgressDialog:

dialog = new ProgressDialog(Context.this);
dialog.setIndeterminate(true);
dialog.setIndeterminateDrawable(getResources().getDrawable(R.anim.progress_dialog_icon_drawable_animation));
dialog.setMessage("Some Text");
dialog.show();

To rozwiązanie jest naprawdę proste i działało dla mnie, możesz rozszerzyć ProgressDialog i sprawić, że zastąpi on wewnętrznie rysowany, jednak było to naprawdę zbyt skomplikowane w stosunku do tego, czego potrzebowałem, więc tego nie zrobiłem.

ślepy
źródło
1
Dzięki za zwrócenie uwagi na „dialog.setIndeterminateDrawable ()”
scottyab
Czy jest sposób, aby w oknie dialogowym był tylko obraz, bez komunikatu, ale można go narysować w całym oknie dialogowym?
Diego
@Diego Nie próbowałem, ale nie widzę dlaczego nie. Czy próbowałeś użyć narzędzia do rysowania, które zajmowałoby żądane miejsce (tj. Miało długi współczynnik proporcji) i nie ustawiało żadnego tekstu w oknie dialogowym?
blindstuff
42

Spróbuj ustawić:

android:indeterminateDrawable="@drawable/progress" 

U mnie to zadziałało. Oto także kod progress.xml:

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:pivotX="50%" android:pivotY="50%" android:fromDegrees="0"
    android:toDegrees="360">

    <shape android:shape="ring" android:innerRadiusRatio="3"
        android:thicknessRatio="8" android:useLevel="false">

        <size android:width="48dip" android:height="48dip" />

        <gradient android:type="sweep" android:useLevel="false"
            android:startColor="#4c737373" android:centerColor="#4c737373"
            android:centerY="0.50" android:endColor="#ffffd300" />

    </shape>

</rotate> 
błoto
źródło
3
Jeśli chcesz użyć elementu do rysowania, po prostu android:drawable=w tagu obracania, a następnie usuń kształt. Wreszcie ktoś, kto odpowie na pytanie o obracający się pasek postępu.
MinceMan
2
Ustawia kolor, ale pasek postępu się nie obraca
Crawler
Aby szybko dostosować prędkość obrotową, android:toDegreesmożna ustawić wyższą wartość. Ustawienie tej opcji android:toDegrees="1080"zwiększy rotację 3 razy.
Levor
10

Twój styl powinien wyglądać tak:

<style parent="@android:style/Widget.ProgressBar" name="customProgressBar">
    <item name="android:indeterminateDrawable">@anim/mp3</item>
</style>
Zwycięzca
źródło
6

robię twój kod. i mogę uruchomić, ale muszę zmodyfikować dwa miejsca:

  1. name="android:indeterminateDrawable" zamiast android:progressDrawable

  2. zmodyfikuj nazwę attrs.xml ---> styles.xml

pengwang
źródło
modyfikujesz androida: startColor = "# 300000ff" na # FF00ff00, modyfikujesz inny kolor
pengwang
6

Niestandardowy postęp ze skalą!

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:duration="150">
        <scale
            android:drawable="@drawable/face_no_smile_eyes_off"
            android:scaleGravity="center" />
    </item>
    <item android:duration="150">
        <scale
            android:drawable="@drawable/face_no_smile_eyes_on"
            android:scaleGravity="center" />
    </item>
    <item android:duration="150">
        <scale
            android:drawable="@drawable/face_smile_eyes_off"
            android:scaleGravity="center" />
    </item>
    <item android:duration="150">
        <scale
            android:drawable="@drawable/face_smile_eyes_on"
            android:scaleGravity="center" />
    </item>

</animation-list>
Dmitrij
źródło
1
public class CustomProgressBar {
    private RelativeLayout rl;
    private ProgressBar mProgressBar;
    private Context mContext;
    private String color__ = "#FF4081";
    private ViewGroup layout;
    public CustomProgressBar (Context context, boolean isMiddle, ViewGroup layout) {
        initProgressBar(context, isMiddle, layout);
    }

    public CustomProgressBar (Context context, boolean isMiddle) {
        try {
            layout = (ViewGroup) ((Activity) context).findViewById(android.R.id.content).getRootView();
        } catch (Exception e) {
            e.printStackTrace();
        }
        initProgressBar(context, isMiddle, layout);
    }

    void initProgressBar(Context context, boolean isMiddle, ViewGroup layout) {
        mContext = context;
        if (layout != null) {
            int padding;
            if (isMiddle) {
                mProgressBar = new ProgressBar(context, null, android.R.attr.progressBarStyleSmall);
                // mProgressBar.setBackgroundResource(R.drawable.pb_custom_progress);//Color.parseColor("#55000000")
                padding = context.getResources().getDimensionPixelOffset(R.dimen.padding);
            } else {
                padding = context.getResources().getDimensionPixelOffset(R.dimen.padding);
                mProgressBar = new ProgressBar(context, null, android.R.attr.progressBarStyleSmall);
            }
            mProgressBar.setPadding(padding, padding, padding, padding);
            mProgressBar.setBackgroundResource(R.drawable.pg_back);
            mProgressBar.setIndeterminate(true);
                try {
                    color__ = AppData.getTopColor(context);//UservaluesModel.getAppSettings().getSelectedColor();
                } catch (Exception e) {
                    color__ = "#FF4081";
                }
                int color = Color.parseColor(color__);
//                color=getContrastColor(color);
//                color__ = color__.replaceAll("#", "");//R.color.colorAccent
                mProgressBar.getIndeterminateDrawable().setColorFilter(color, android.graphics.PorterDuff.Mode.SRC_ATOP);
            } 
            }

            RelativeLayout.LayoutParams params = new
                    RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
            rl = new RelativeLayout(context);
            if (!isMiddle) {
                int valueInPixels = (int) context.getResources().getDimension(R.dimen.padding);
                lp.setMargins(0, 0, 0, (int) (valueInPixels / 1.5));//(int) Utils.convertDpToPixel(valueInPixels, context));
                rl.setClickable(false);
                lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
            } else {
                rl.setGravity(Gravity.CENTER);
                rl.setClickable(true);
            }
            lp.addRule(RelativeLayout.CENTER_IN_PARENT);
            mProgressBar.setScaleY(1.55f);
            mProgressBar.setScaleX(1.55f);
            mProgressBar.setLayoutParams(lp);

            rl.addView(mProgressBar);
            layout.addView(rl, params);
        }
    }

    public void show() {
        if (mProgressBar != null)
            mProgressBar.setVisibility(View.VISIBLE);
    }

    public void hide() {
        if (mProgressBar != null) {
            rl.setClickable(false);
            mProgressBar.setVisibility(View.INVISIBLE);
        }
    }
}

A potem zadzwoń

customProgressBar = new CustomProgressBar (Activity, true);
customProgressBar .show();
VV W
źródło
0

Nie jestem pewien, ale w tym przypadku nadal możesz przejść z całkowicie dostosowanym AlertDialog, ustawiając oddzielny plik układu w oknie dialogowym ostrzeżenia i ustawiając animację dla widoku obrazu za pomocą części powyższego kodu, która również powinna to zrobić!

Jayshil Dave
źródło