1

У меня есть таймер, который начинается, когда пользователь отвечает на вопрос, и мне нужен небольшой круговой пирог, который медленно отсчитывает, чтобы идти вместе с ним. После некоторых исследований я нашел это: Circular Progress Bar (for a countdown timer), который кажется тем, что я хочу, но у меня возникли проблемы с его реализацией.Попытка следовать предыдущему ответу о том, как создать анимацию, но она полностью исчезает

Я скопировал код для строки выполнения xml, и это выглядит нормально, но в java я хочу вызвать метод startTimer всякий раз, когда пользователь получает правильный ответ, чтобы таймер мог начать заново. Но это совсем не работает, и я за последние два часа возился, и это сводит меня с ума.

Вот мой XML файл вытяжке:

<?xml version="1.0" encoding="utf-8"?> 

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" > 
<item android:id="@android:id/progress"> 
    <shape 
     android:innerRadiusRatio="5" 
     android:shape="ring" 
     android:thicknessRatio="10.0" 
     android:useLevel="true"> 
     <gradient 
      android:startColor="#fb0000" 
      android:endColor="#00FF00" 
      android:centerColor="#fbf400" 
      android:type="sweep" /> 
    </shape> 
</item> 
</layer-list> 

Мой activity_color_match файл: (хотя вы, вероятно, только самый нижний "прогресс бар"

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 

xmlns:tools="http://schemas.android.com/tools" 
android:id="@+id/activity_color_match" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:paddingBottom="@dimen/activity_vertical_margin" 
android:paddingLeft="@dimen/activity_horizontal_margin" 
android:paddingRight="@dimen/activity_horizontal_margin" 
android:paddingTop="@dimen/activity_vertical_margin" 
tools:context="com.example.ali.colormatch2.ColorMatch2"> 

<Button 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:id="@+id/blueButton" 
    android:background="@drawable/rounded_blue_button" 
    android:onClick="sendBlue" 
    android:layout_alignParentBottom="true" 
    android:layout_alignParentLeft="true" 
    android:layout_alignParentStart="true" 
    android:layout_toLeftOf="@+id/textView3" 
    android:layout_toStartOf="@+id/textView3" /> 

<Button 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:id="@+id/greenButton" 
    android:background="@drawable/rounded_green_button" 
    android:onClick="sendGreen" 
    android:layout_alignBottom="@+id/redButton" 
    android:layout_alignParentRight="true" 
    android:layout_alignParentEnd="true" 
    android:layout_alignTop="@+id/redButton" 
    android:layout_alignLeft="@+id/yellowButton" 
    android:layout_alignStart="@+id/yellowButton" /> 

<TextView 
    android:text="Score:" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignParentTop="true" 
    android:layout_alignParentLeft="true" 
    android:layout_alignParentStart="true" 
    android:id="@+id/textView4" /> 

<TextView 

    android:text="@string/matchText" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:id="@+id/textView3" 
    android:textAppearance="@style/TextAppearance.AppCompat.Body2" 
    android:textSize="20dp" 
    android:layout_below="@+id/textView4" 
    android:layout_centerHorizontal="true" 
    android:layout_marginTop="26dp" /> 

<TextView 
    android:text="@string/mainColor" 
    android:id="@+id/textView2" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:gravity="center_horizontal" 
    android:textColor="@android:color/holo_blue_dark" 
    android:textSize="80dp" 
    android:textAppearance="@style/TextAppearance.AppCompat.Display3" 
    android:layout_below="@+id/textView3" 
    android:layout_centerHorizontal="true" 
    android:layout_marginTop="114dp" 
    android:shadowColor="#000000" 
    android:shadowDx="10" 
    android:shadowDy="10" 
    android:shadowRadius="10"/> 

<Button 
    android:layout_height="wrap_content" 
    android:id="@+id/yellowButton" 
    android:background="@drawable/rounded_yellow_button" 
    android:elevation="0dp" 
    android:layout_width="wrap_content" 
    android:onClick="sendYellow" 
    android:layout_alignParentBottom="true" 
    android:layout_alignParentRight="true" 
    android:layout_alignParentEnd="true" 
    android:layout_toRightOf="@+id/textView3" 
    android:layout_toEndOf="@+id/textView3" /> 

<Button 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:id="@+id/redButton" 
    android:background="@drawable/rounded_red_button" 
    android:onClick="sendRed" 
    android:elevation="0dp" 
    android:layout_above="@+id/blueButton" 
    android:layout_alignParentLeft="true" 
    android:layout_alignParentStart="true" 
    android:layout_marginBottom="22dp" 
    android:layout_alignRight="@+id/blueButton" 
    android:layout_alignEnd="@+id/blueButton" /> 

<ProgressBar 
    style="?android:attr/progressBarStyleHorizontal" 
    android:layout_width="60dp" 
    android:layout_height="60dp" 
    android:indeterminate="false" 
    android:max="100" 
    android:progress="100" 
    android:id="@+id/progressBar" 
    android:progressDrawable="@drawable/timer" 
    android:layout_below="@+id/textView4" 
    android:layout_toRightOf="@+id/textView2" 
    android:layout_toEndOf="@+id/textView2" /> 


</RelativeLayout> 

И сам монстр, мой ColorMatch2.java файл. Я поставил все это здесь, но метод startTimer() вызывается в checkAnswer(), а сам метод startTimer() находится на самом дне

package com.example.ali.colormatch2; 

import android.content.Intent; 
import android.graphics.Color; 
import android.os.CountDownTimer; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.view.animation.Animation; 
import android.view.animation.RotateAnimation; 
import android.widget.Button; 
import android.widget.ProgressBar; 
import android.widget.TextView; 
import android.app.Activity; 
import android.view.MotionEvent; 
import android.view.View.OnTouchListener; 
import android.widget.ImageView; 
import android.widget.RelativeLayout; 
import java.util.Random; 

import static com.example.ali.colormatch2.R.id.progressBar; 

public class ColorMatch2 extends AppCompatActivity { 

//int answer; //1 = red, 2 = green, 3 = blue, 4 = yellow 
CounterClass timer; 
TextView textView3, textView2, textView4; 
int count = 0; 
int score = 0; 
int correctAnswer; 
boolean matchColor = true, matchText = false; 
boolean firstTime = true; 
boolean correctAnswerGiven = false; 
RelativeLayout relativeLayout; 
//ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar); 
//Animation an = new RotateAnimation(0.0f, 90.0f, 250f, 273f); 
CountDownTimer countDownTimer; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_color_match); 
    textView3 = (TextView) findViewById(R.id.textView3); 
    textView2 = (TextView) findViewById(R.id.textView2); 
    textView4 = (TextView) findViewById(R.id.textView4); 


    relativeLayout = (RelativeLayout) findViewById(R.id.activity_color_match); 

    Button redButton, blueButton, greenButton, yellowButton; 
    redButton = (Button) findViewById(R.id.redButton); 
    blueButton = (Button) findViewById(R.id.blueButton); 
    greenButton = (Button) findViewById(R.id.greenButton); 
    yellowButton = (Button) findViewById(R.id.yellowButton); 

    if (firstTime) { 
     generateNewWord(); 
     firstTime = false; 
    } 
    //ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar); 
    //Animation an = new RotateAnimation(0.0f, 90.0f, 250f, 273f); 

    redButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      checkAnswer(1); 

     } 
    }); 
    greenButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      checkAnswer(2); 
     } 
    }); 
    blueButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      checkAnswer(3); 
     } 
    }); 
    yellowButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      checkAnswer(4); 
     } 
    }); 


} 

public void checkAnswer(int answer) { 


    Random rand = new Random(); 
    int x; 
    //Let's think about this. If the score is less than <10, I want a 1 in 5 
    //chance of it changing. If it's between 10 and 20, 1 in 4, and if it's higher 
    //than 20, 1 in 3 
    if (score < 5) { 
     x = 5; 
    } else if (score >= 5 && score < 15) { 
     x = 4; 
    } else { 
     x = 3; 
    } 
    int randCount = rand.nextInt(x) + 1; 
    if (randCount == x) { 
     if (matchColor) { 
      textView3.setText(getString(R.string.gameSetting2)); // might need to add context with this - check https://stackoverflow.com/questions/10698945/reference-string-resource-from-code 
      matchText = true; 
      matchColor = false; 
      relativeLayout.setBackgroundColor(Color.argb(255, 84, 84, 84)); 
     } else if (matchText) { 
      textView3.setText(getString(R.string.gameSetting1)); 
      matchColor = true; 
      matchText = false; 
      relativeLayout.setBackgroundColor(Color.argb(255, 255, 255, 255)); 
     } 
    } 

    if (answer == correctAnswer) { 
     score++; 
     count++; 
     textView4.setText("Score: " + score); 
     generateNewWord(); 


     //Timer and animation explanation: timer starts first time user gives correct answer. 
     //After that, if they give correct answer again it cancels the timer and starts it over, 
     //resetting it. I am trying to achieve the same effect with the animation. 
     ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar); 
     Animation an = new RotateAnimation(0.0f, 90.0f, 250f, 273f); 
     an.setFillAfter(true); 
     progressBar.startAnimation(an); 
     if (correctAnswerGiven) { 
      timer.cancel(); 
     } 
     //progressBar.setProgress(100); 
     timer = new CounterClass(4000, 1000); 
     timer.start(); //This is the actual timer that if expires will cause user to fail game 
     startTimer(4000); // This is the timer for the progress bar 
     if (!correctAnswerGiven) { 
      correctAnswerGiven = true; 
     } 
    } else { 
     textView3.setText("Wrong"); 
     //quit(); 
    } 

} 


public void generateNewWord() { 

    //randomly select between red, green, blue, yellow 
    Random rand = new Random(); 
    int randomInt1 = rand.nextInt(4) + 1; // assigns randomInt a value between 1 - 4 
    int randomInt2 = rand.nextInt(4) + 1; 

    if (randomInt1 == 1) { 
     textView2.setText(R.string.Red); 
    } else if (randomInt1 == 2) { 
     textView2.setText(R.string.Green); 
    } else if (randomInt1 == 3) { 
     textView2.setText(R.string.Blue); 
    } else if (randomInt1 == 4) { 
     textView2.setText(R.string.Yellow); 
    } 


    //randomly select hex codes between rgby 
    if (randomInt2 == 1) { 
     textView2.setTextColor(0xffcc0000); 
    } else if (randomInt2 == 2) { 
     textView2.setTextColor(0xff669900); 
    } else if (randomInt2 == 3) { 
     textView2.setTextColor(0xff000080); 
    } else if (randomInt2 == 4) { 
     textView2.setTextColor(0xffffff00); 
    } 

    if (firstTime) { 
     textView3.setText(getString(R.string.gameSetting2)); 
     correctAnswer = randomInt1; 
     relativeLayout.setBackgroundColor(Color.argb(255, 84, 84, 84)); 
     firstTime = false; 
    } else { 

     if (matchColor) { 
      correctAnswer = randomInt2; 
      textView3.setText(getString(R.string.gameSetting1)); 
      relativeLayout.setBackgroundColor(Color.argb(255, 255, 255, 255)); 
     } else if (matchText) { 
      correctAnswer = randomInt1; 
      textView3.setText(getString(R.string.gameSetting2)); 
      relativeLayout.setBackgroundColor(Color.argb(255, 84, 84, 84)); 
     } 
    } 

} 

public class CounterClass extends CountDownTimer { 
    public CounterClass(long millsInFuture, long countDownInterval) { 
     super(millsInFuture, countDownInterval); 
    } 

    @Override 
    public void onFinish() { 
     //quit(); 
     // I need something to test if this is happening 
     //textView3.setText("Timer Finished"); 
    } 

    @Override 
    public void onTick(long millisUntilFinished) { 
     //Nothing 
    } 


} 

public void quit() { 
    Intent intent = new Intent(ColorMatch2.this, 
      LoseScreen.class); 
    Bundle b = new Bundle(); 
    b.putInt("score", score); // Your score 
    intent.putExtras(b); // Put your score to your next 
    startActivity(intent); 
    overridePendingTransition(R.anim.slide_in, R.anim.slide_out); 

} 


private void startTimer(final int x) { 
    countDownTimer = new CountDownTimer(x, 500) { 
     // 500 means, onTick function will be called at every 500 milliseconds 
     ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar); 

     @Override 
     public void onTick(long leftTimeInMilliseconds) { 
      long seconds = leftTimeInMilliseconds/1000; 
      double percentage; 
      if(leftTimeInMilliseconds > 0){ 
      percentage = 4000/leftTimeInMilliseconds;} 
      else {percentage = 0.0;} 
      progressBar.setProgress((int) percentage * 100); 
     } 

     @Override 
     public void onFinish() { 
      // Nothing 
     } 
    }.start(); 

} 
} 

Чтобы повторить, индикатор выполнения (хотя и странно не повернут, но я почти не беспокоюсь об этом прямо сейчас) до тех пор, пока не будет вызван метод checkAnswer, и в этом случае он исчезнет. Спасибо. Кроме того, мне не нужны какие-либо фактические числа внутри, только сам маленький бар, поэтому я удалил код, который был в исходном сообщении.

ответ

0

В итоге я получил его на работу, выбросив метод в этот ответ. Я посмотрел в комментариях этого блога http://mrigaen.blogspot.it/2013/12/create-circular-progress-bar-in-android.html и использовали следующий метод:

//class to create progressbar circular animation 
private class ProgressBarAnimation extends Animation{  
    private float from; 
    private float to; 

    public ProgressBarAnimation(float from, float to) { 
     super();    
     this.from = from; 
     this.to = to; 
    } 

    @Override 
    protected void applyTransformation(float interpolatedTime, Transformation t) { 
     super.applyTransformation(interpolatedTime, t); 
     float value = from + (to - from) * interpolatedTime; 
     String prg = String.valueOf((int)value);   
     } 

     pb.setProgress((int) value);       
     tv_today.setText(prg); 
    } 
} 

И назвать это таким образом: // анимировать 100
ProgressBarAnimation Аним = новый ProgressBarAnimation (0, 100); anim.setDuration (2000); pb.startAnimation (anim);

Если вы натыкаетесь на это в будущем, pb - это то, что они называли индикатором прогресса в этом сообщении в блоге.