web-dev-qa-db-fra.com

Barre de progression sous la barre d'action

Résumé de la question: Comment puis-je créer une ProgressBar intégrée à la ActionBar, comme dans l'application Chrome?

Détails: Regardez cette capture d'écran de Chrome:

Chrome for Android screenshot

Je veux créer une barre d'action comme celle-ci. Juste sous la barre d'action, il y a une barre de progression qui se remplit en fonction du chargement des pages. J'ai vu cet exemple dans de nombreuses applications, telles que Feedly, mais je n'ai pas été en mesure de créer ma propre implémentation. J'ai essayé d'utiliser les propres API d'Android pour le créer:

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

Mais ce code force uniquement la barre de progression à afficher sur la barre d’action, comme ceci:

My App Screenshot

Alors, comment puis-je afficher ma barre de progression sous la barre d’action, comme sur l’application Chrome?

78
zubietaroberto

C'est maintenant un comportement natif qui peut être obtenu en utilisant SwipeRefreshLayout .

Vous pouvez envelopper votre vue défilable avec une SwipeRefreshLayout et il vous suffit ensuite d'écouter les événements 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);
}

Un tutoriel simple et agréable peut être trouvé dans ce blog .

6
AlexGuti

Je n'étais pas entièrement satisfait de la réponse acceptée ci-dessus, j'ai donc fait des recherches supplémentaires moi-même.

Je pense qu'ils ont utilisé le truc suivant: ils ont récupéré la vue de dessus dans la hiérarchie de vues appelée DecorView et y ont ajouté la barre de progression. De cette façon, la barre de progression s'affiche à la fois sur la barre d'action ET sur la zone de contenu. Notez que la réponse de S.D. place la barre de progression dans la zone de contenu et «vole» de l'espace au contenu réel, ce qui peut entraîner des résultats inattendus.

Exemple Captures d'écran de cette implémentation:

ProgressBar

ProgressBarIndeterminate

Code

Il suffit de mettre ce code dans la méthode onCreate de certaines activités et cela devrait fonctionner:

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

Vous pouvez jouer avec l'argument height de LayoutParams pour définir le progressBar plus large ou plus étroit, mais vous devrez peut-être ajuster le décalage -10.

Coiffant

Malheureusement, vous pouvez voir le fond gris moche de la barre de progression. Pour le supprimer, il suffit de rechercher l'arrière-plan par identifiant et d'essayer de le masquer. Pour supprimer l'arrière-plan, je devais créer un dessin identique de la version du système et supprimer l'élément d'arrière-plan.

TL; DR: Créer le fichier progress_horizontal_holo_no_background_light.xml et coller ce dessinable:

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

Copiez les fichiers .png appropriés de sdk/platforms/Android-xx/data/res/drawable-xxx/ dans votre projet, puis dans le code, vous pouvez ajouter:

progressBar.setProgressDrawable(getResources().getDrawable(R.drawable.progress_horizontal_holo_no_background_light));

Extra: barre de progression indéterminée

Les versions de pré-KitKat des barres de progression indéterminées sont plutôt laides et décalées . Vous pouvez télécharger le nouveau ProgressBar lisse appelé ButteryProgressBar. Recherchez-le simplement sur google (je ne peux plus publier de liens, car je suis nouveau ici: [), ajoutez la classe à votre projet et vous pouvez simplement remplacer la barre de progression précédente par ce code et disposer d'une barre de progression indéterminée:

final ButteryProgressBar progressBar = new ButteryProgressBar(this);
progressBar.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 24));

Vous pourriez aussi avoir besoin de simplifier ce code:

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

à ce code:

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

J'espère que j'ai aidé :)

56
Antimonit

Étendez les activités de la classe suivante pour avoir une barre de progression en haut (sous la barre de action) de chacune et une méthode getProgressBar():

Classe parentale:

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

Mise en page (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>
25
S.D.

J'ai compilé du code à partir de ce fil ainsi que d'autres threads sur StackOverflow et créé un projet qui peut être utilisé pour implémenter ButteryProgessbar ainsi que "dérouler pour actualiser". https://github.com/pauldmps/Gmail-like-Pull-Down-tofRefresh

N'hésitez pas à utiliser le code dans votre application.

Un grand merci à vous les gars.

4
Shantanu Paul

Veuillez utiliser le code ci-dessous. il suffit d'utiliser un style par défaut dans la barre de progression comme 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>
2
Rank

Eh bien, j'ai fait quelque chose de similaire pour l'une de mes applications pour animaux de compagnie et je ne suis pas sûr que ce soit la seule ou la meilleure façon de le faire, mais cela fonctionne définitivement.

Pour commencer, utilisez une barre d’action de superposition, puis définissez l’arrière-plan sur "null" afin que la barre d’action de superposition soit transparente.

Maintenant, dans votre présentation d'activité, définissez la marge supérieure de votre vue racine sur "hauteur de la barre d'actions". Vous pouvez le faire comme ceci.

<RelativeLayout
    ...
    Android:layout_marginTop="?android:attr/actionBarSize" />

Maintenant, l'action ne va pas masquer le contenu de votre activité.

La prochaine chose que vous devez faire maintenant est - ajoutez une vue d’en-tête au-dessus de votre vue racine avec une hauteur identique à celle de la barre d’action. Définissez une couleur d'arrière-plan. Ce serait maintenant la couleur de votre barre d’action et puisque celle-ci s’aligne parfaitement au-dessus de cette vue d’en-tête. 

Vous pouvez maintenant facilement placer une barre de progression dans la vue en-tête et l'aligner au bas de la vue en-tête. Pour l’utilisateur, cela donnerait l’impression que la barre de progression se trouve sur la barre d’action, tout comme le chrome. 

0
user2405598