30

I am writing a media player and i would like to have a progress bar showing the progress of the song. I found the ProgressBar class, but all i can get on the screen is a circular spinning icon. what im looking for is an actual bar.

How do i change the style of the ProgressBar to be a bar (not a circle) and how would i use it with MediaPlayer?

thanks

Mahozad
  • 18,032
  • 13
  • 118
  • 133
mtmurdock
  • 12,756
  • 21
  • 65
  • 108

3 Answers3

66

use the style ?android:attr/progressBarStyleHorizontal

for example:

  <ProgressBar android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleHorizontal"

and this is an example with MediaPlayer:

package com.playerpgbar;

import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

public class Player extends Activity implements Runnable, OnClickListener {

    private TextView status;
    private ProgressBar progressBar;
    private Button startMedia;
    private Button stop;
    private MediaPlayer mp;      

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        status = (TextView) findViewById(R.id.status);
        progressBar = (ProgressBar) findViewById(R.id.progressBar);
        startMedia = (Button) findViewById(R.id.startMedia);
        stop = (Button) findViewById(R.id.stop);

        startMedia.setOnClickListener(this);
        stop.setOnClickListener(this);                
    }        

    @Override
    public void onClick(View v) {
        if (v.equals(startMedia)) {
            if (mp != null && mp.isPlaying()) return;
            mp = MediaPlayer.create(Player.this, R.raw.exodus_piranha);
            mp.start();               
            status.setText(R.string.PlayingMedia);         
            progressBar.setVisibility(ProgressBar.VISIBLE);
            progressBar.setProgress(0);
            progressBar.setMax(mp.getDuration());
            new Thread(this).start();
        }

        if (v.equals(stop) && mp!=null) {
            mp.stop();
            mp = null;            
            status.setText(R.string.Stopped);
            progressBar.setVisibility(ProgressBar.GONE);
        }
    }

    @Override
    public void run() {
        int currentPosition= 0;
        int total = mp.getDuration();
        while (mp!=null && currentPosition<total) {
            try {
                Thread.sleep(1000);
                currentPosition= mp.getCurrentPosition();
            } catch (InterruptedException e) {
                return;
            } catch (Exception e) {
                return;
            }            
            progressBar.setProgress(CurrentPosition);
        }
    }
}
Jorgesys
  • 124,308
  • 23
  • 334
  • 268
  • Thanks this works well, it's just missing one line: you need to set the max position (setMax(total)) before you start the while loop or the bar will go straight to 100%. thankyou! – mtmurdock Jun 03 '10 at 18:53
  • hello i can't see the bar at 100% at the start, I set progressBar.setMax(mp.getDuration()); and then Execute the thread that contains the while loop to update the progressBar, new Thread(this).start(); =) – Jorgesys Jun 03 '10 at 20:53
  • 29
    No, this is NOT valid threading model for Android. DO NOT create your own thread and then modify the UI from within that thread. You MUST follow the android rules, or you'll create a bug that is difficult to find... Instead do this... http://developer.android.com/resources/articles/painless-threading.html – Trenton D. Adams Jul 24 '11 at 06:23
  • 2
    @TrentonD.Adams the link is dead – SQLiteNoob Jan 19 '14 at 20:38
8

Programmatically:

progressBar = new ProgressBar(activity, null, android.R.attr.progressBarStyleHorizontal);
progressBar.setIndeterminate(false);
nmr
  • 16,625
  • 10
  • 53
  • 67
3

In newer versions of material design library, the circular progress bar could be determinate too:

<com.google.android.material.progressindicator.CircularProgressIndicator
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

Also, if your progress bar is initially indeterminate, both linear and circular progress indicators can smoothly switch from indeterminate mode to determinate mode:

int progress = getLoadingProgress()
indicator.setProgressCompat(progress, true)

Source

Mahozad
  • 18,032
  • 13
  • 118
  • 133