2010-12-03 17 views
15

dos barras que muestra el progreso de un juego. Si el usuario obtiene puntos o el tiempo está activo, etc. progressBars debe actualizarse:android progressBar no actualiza la vista de progreso/dibujable

private TextView tv; 
private ProgressBar levelHoldBar; 
private ProgressBar levelUpBar; 

//... 
private void updateViews() { 

    // ... 
    levelHoldBar.setMax(currentLevel.getThreshold()); 
    levelHoldBar.setProgress(currentPoints > currentLevel.getThreshold() ? currentLevel.getThreshold() : currentPoints); 

    levelUpBar.setMax(nextLevel.getThreshold()); 
    levelUpBar.setProgress(currentPoints > nextLevel.getThreshold() ? nextLevel.getThreshold() : currentPoints); 

    tv.setText(currentPoints+"/"+currentLevel.getThreshold()); 

    Log.d(TAG, "hold prog/max "+levelHoldBar.getProgress()+"/"+levelHoldBar.getMax()); 
    Log.d(TAG, "up prog/max "+levelUpBar.getProgress()+"/"+levelUpBar.getMax()); 
} 

ie. Salidas:

12-03 17:48:33.918: DEBUG/MainActivity(6829): hold prog/max 20/20 
12-03 17:48:33.918: DEBUG/MainActivity(6829): up prog/max 20/50 

El Log.d (...) al final muestra SIEMPRE los valores correctos, pero VECES las barras visuales de los ProgressBars no muestran los progesses correctas. Muestran los progresos que se habían establecido previamente incluso si los captadores para "máximo" y "progreso" devuelven los valores correctos (en el ejemplo, la barra muestra aproximadamente 20% (en lugar de 100%) para el nivelHoldBar y aproximadamente 2% (en lugar de 40 %) para el nivel Arriba-barra). No puedo entender, ¿por qué la salida de registro es correcta, pero los datos descartables son incorrectos? ¡TextView (tv) se actualiza correctamente! ¿Que está pasando aqui? ¿Cómo puedo arreglar eso?

+0

Bien, preguntas tontas primero - 1) estás actualizando en el hilo de la interfaz de usuario, y 2) no tienes funciones de dibujo personalizadas en ninguna parte para nada? – EboMike

+0

sí, estoy ejecutándolo en el hilo de la interfaz de usuario y no tengo ningún dibujo personalizado. Utiliza siempre la misma pila de llamadas para actualizar y, a veces, las barras se actualizan y otras no. Esto es extraño ^^ – Stuck

+0

Bien. Algo es sospechoso ¿Qué sucede cuando simplificas tu actividad para, por ejemplo, modificar la barra de progreso a "valor anterior + 1" cada vez que presionas un botón? ProgressBars es muy simple, por lo que debemos pasar de una configuración simple a la que tiene actualmente y averiguar en qué punto se rompe. – EboMike

Respuesta

36

SOLUCIÓN: ¡Es un error en ProgressBar!

finalmente ... Creo que he encontrado la solución ...

esto no funciona como cabría esperar:

bar.setMax(50); 
bar.setProgress(20); 
bar.setMax(20); 
bar.setProgress(20); 

El setProgress (...) no parece desencadenar la actualización en el dibujable si el mismo valor se pasa de nuevo. Pero no se desencadena durante el setMax, también. Entonces la actualización falta. ¡Parece un error en la ProgressBar de Android! Esto me tomó alrededor de 8 horas ahora ... jajaja: D

Para resolver esto, estoy haciendo un bar.setProgress (0) antes de cada actualización ... esto es solo una solución, pero funciona para mí como Esperado:

bar.setMax(50); 
bar.setProgress(20); 
bar.setProgress(0); // <-- 
bar.setMax(20); 
bar.setProgress(20); 
+0

¿Podría informar un error en http://b.android.com? – pjv

+2

Ya está allí desde entonces: http://code.google.com/p/android/issues/detail?id=12945 – Stuck

+0

¿Estás seguro de que el segundo setMax es 20? ¿O debería ser 50? – taxeeta

10

Se puede utilizar un controlador para actualizar progressbar

Handler progressBarHandler = new Handler(); 

ProgressBar bar = (ProgressBar) findViewById(R.id.progressBar1);; 

progressBarHandler .post(new Runnable() { 

     public void run() { 
      bar.setProgress(progress); 
     } 
}); 
+0

¿Por qué sería útil? Dice que ya se está actualizando desde el hilo de la interfaz de usuario – Ixx

+1

@ Ixx También tuve este problema similar. Esto resolvió mi problema. Pensé que podría ayudar aquí. – SKT

+0

Entonces es probablemente porque lo está llamando en crear(). Entonces esto también ayuda. – Ixx

7

En mi caso, creo VerticalSeekBar, y la solución de pegado no funciona. Después de horas, he encontrado una solución:

@Override 
public synchronized void setProgress(int progress) { 
    super.setProgress(progress); 
    onSizeChanged(getWidth(), getHeight(), 0, 0); 
} 

Espero que ayudes a alguien.

+0

Gracias, salvó mi día! Trabajando en Nougat. – Herman

2

Crear updateThumb(); método en VerticalSeekbar

public void updateThumb(){ 
    onSizeChanged(getWidth(), getHeight(), 0, 0); 
} 

Y luego llame al método update thumb después de establecer el progreso.

seekBar.setProgress((int) progress); 
seekBar.updateThumb(); 

su trabajo para mí en calss verticalseekbar

+1

¿Cómo crear un método dentro de una clase existente? – Daniel

+1

La clase VerticalSeekbar no es un calss predeterminado de android es un calss personalizado que se creará por ti solo quiere el código calss .. – saravanan

13

pude conseguir que esto funcione con View.post():

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 

    // ... 

    mSeekBar.post(new Runnable() { 
     @Override 
     public void run() { 
      mSeekBar.setProgress(percentOfFullVolume); 
     } 
    }); 
} 

Al igual que con SKTS contestan que no está claro para mí por qué esto debería funcionar cuando esto no es

mSeekBar.setProgress(percentOfFullVolume); 

Sin embargo, parece ser cierto hasta e incluyendo Android Chupete.

1

Gracias Pegado a la publicación que indica que hay un error de Android. También tengo una barra de búsqueda vertical.

El problema fue cuando estaba cambiando el dibujo dibujable. El dibujable se actualizaría pero la barra se establecería en 0 y sería de un tamaño muy pequeño. Pude hacer que cambiara el tamaño con updateThumb(), pero el progreso seguía siendo 0.

Para establecer el progreso en el valor original, agregué mylayer.setLevel (...) ;. Encontré esto leyendo el código fuente de ProgressBar.doRefreshProgress (...). Es posible que pueda hacer seekBar.getProgressDrawable.setLevel(...).

LayerDrawable mylayer = //new LayerDrawable() 
seekBar.setProgressDrawable(mylayer); 
seekBar.updateThumb(); 
seekBar.setProgress((int) chLevel); 
mylayer.setLevel((int) (chLevel/MAX_LEVEL * 10000)); 
8

Para mí, llamando setMax()antessetProgress() trabajaron por alguna razón.

0

Esto funcionó para mí ...

OneFragmen.java

public class OneFragment extends Fragment{ 

public OneFragment() { 
    // Required empty public constructor 
} 
private Toolbar toolbar; 
private TabLayout tabLayout; 
private ViewPager viewPager; 

int progress=0; 
private Handler handler = new Handler(); 
TextView txtProgress; 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
} 

@Override 
public View onCreateView(
    LayoutInflater inflater, 
    ViewGroup container, 
    Bundle savedInstanceState) { 

    View view = inflater.inflate(R.layout.fragment_one, container, false); 
    getActivity().setTitle(R.string.app_name); 

    final ProgressBar spinner = 
     (ProgressBar) view.findViewById(R.id.outerProgressBar); 
    Resources res = getResources(); 
    Drawable drawable = res.getDrawable(R.drawable.circular); 
    txtProgress = (TextView)view.findViewById(R.id.txtProgress); 
    spinner.setProgressDrawable(drawable); 
    spinner.setSecondaryProgress(100); 
    spinner.setMax(100); 
    spinner.setProgress(0); 

    new Thread(new Runnable() { 

     @Override 
     public void run() { 
      while (progress < 100) { 
       progress += 1; 
       handler.post(new Runnable() { 
        @Override 
        public void run() { 
         spinner.setProgress(progress); 
         txtProgress.setText(progress + "%"); 
        } 
       }); 
       try { 
        Thread.sleep(28); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    }).start(); 
    return view; 
    } 
} 
0

Aquí no hay nada funcionó para mí, así que he llegó con una solución poco diferente. Noté que todo funciona bien hasta que trato de cambiar el valor máximo (llamando al setMax con un valor diferente).

Mi código:

class FixedSeekBar : SeekBar { 

    constructor(context: Context) : super(context) 
    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) 
    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) 

    companion object { 
     private const val PROGRESS_MAX = 1000000.toDouble() 
    } 

    private var mLastMaxValue: Int = 100 

    override fun setMax(max: Int) { 
     mLastMaxValue = max 
     super.setMax(PROGRESS_MAX.toInt()) 
    } 

    fun setProgressFixed(progress: Int) { 
     setProgress((PROGRESS_MAX/mLastMaxValue * progress).toInt()) 
    } 

    fun getProgressFixed(): Int { 
     return (getProgress()/PROGRESS_MAX * mLastMaxValue).toInt() 
    } 

} 

Esto funciona perfectamente para mí. Puedo llamar setMax como suele y yo sólo tenga que sustituir getProgress y setProgress con getProgressFixed y setProgressFixed.

No invalide setProgress y getProgress. Se llaman internamente.

Mi solución no cuenta con setMin. Si lo necesita, cambie el código en consecuencia.

1

Asegúrese de estilo para el progressBar está dispuesto a ser style = "@ android: estilo/Widget.ProgressBar.Horizontal" de lo contrario, se mostrará el progreso indeterminada

(Sólo en caso de que ayudará a alguien)

Cuestiones relacionadas