基于int值更改textswitcher / viewswitcher的textColor?

时间:2014-08-05 20:47:24

标签: android performance android-fragments timer

我有一个从60000毫秒开始的倒数计时器,并希望在时间为10000毫秒时将文本颜色从Color.BLUE更改为Color.RED。我没有成功地尝试过以下几点;尝试设置TextSwitcher的TextTolor并添加将根据int值timerState改变颜色的IF语句。我不知道如何使其工作除了可能停止计时器并创建另一个一毫秒UntilFinished达到10000实际领先到我的第二个问题:

我点击了一个imageButton,它启动了一个对话框片段(PauseFragment),并通过timerCDT.cancel()在我的CountDownTimer上调用cancel()。我遇到了一些nullpointer问题,因此if语句在我的代码中检查null,但是现在一旦PauseFragment解散我的新计时器就会从60000开始,而不是最后一次停止。我希望long timerState = 60000会更新到每次onTick()被调用的millisUntilFinished但是我不确定我哪里出错了!

因此,有人可以帮助我动态更改TextSwitcher文本颜色,并协助弄清楚为什么我的CountDownTimer不会从预期值开始。非常感谢任何帮助。

提前感谢!

 public class GameActivity extends FragmentActivity  implements PauseFragment.FragmentCommunicator,{

 public static long timerState = 60000;
    public static boolean isTimerOn = false;
    private String modeChoice = ModesActivity.mode;
    private TextSwitcher timerTextSwitcher;
    CountDownTimer timerCDT;


  @Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

//...more code

 timerTextSwitcher = (TextSwitcher) findViewById(R.id.timerTextSwitcher);
        timerTextSwitcher.setFactory(new ViewSwitcher.ViewFactory() {

            public View makeView() {
                // Create a new TextView and set properties
                TextView textView = new TextView(getApplicationContext());
                textView.setLayoutParams(new TextSwitcher.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
                textView.setTextSize(20);
                textView.setTextColor(Color.BLUE);
                if (timerState < 10001) {
                    textView.setTextColor(Color.RED);
                }
                return textView;
            }
        });

  // Declare the animations and initialize them
        Animation in = AnimationUtils.loadAnimation(this, android.R.anim.slide_in_left);
        Animation out = AnimationUtils.loadAnimation(this, android.R.anim.slide_out_right);
        // set the animation type to textSwitcher
        timerTextSwitcher.setInAnimation(in);
        timerTextSwitcher.setInAnimation(out);
    }
    timerCDT = new CountDownTimer(timerState, 1000) {
        public void onTick(long millisUntilFinished) {
            isTimerOn = true;
            timerTextSwitcher.setText(String.valueOf(millisUntilFinished / 1000));
            timerState = millisUntilFinished;
        }

        //TODO: assign highscores for players to beat
        public void onFinish() {
            timerTextSwitcher.post(new Runnable() {
                @Override
                public void run() {
                    createToast("GAME OVER!");
                }
            });
            isTimerOn = false;

            DialogFragment endDialog = new EndGameFragment();
            endDialog.show(getSupportFragmentManager(), "EndGameDialogFragment");
        }
    };
    timerCDT.start();


 @Override
public void onPause() {
    super.onPause();
    Bundle args = new Bundle();
    args.putInt(ARG_SCORE, scoreINT);
    args.putLong(ARG_TIMER, timerState);
    args.putString(GameActivity.ARG_MODE, modeChoice);
    if (timerCDT != null) {
        timerCDT.cancel();
    }
    else{
        createToastExtended("onPause() - timerCDT is null; attempt to cancel");
    }
}

 //.!.other fun code here.!.

 @Override
 protected void onStop() {
    super.onStop();
    if (timerCDT != null) {
        timerCDT.cancel();
    }
    else{
        createToastExtended("onStop() - timerCDT is null; attempt to cancel");
    }

 }

 //Player Response information
 @Override
 public void pauseFragmentResponse() {
    if (timerCDT != null) {
        timerCDT.start();
    }
    else{
        createToastExtended("pauseFragmenResponse() - timerCDT is null; attempt to start");
    }
}

 public void pauseStartFrag(View view) {
    DialogFragment dialog = new PauseFragment();
    if (timerCDT != null) {
        timerCDT.cancel();
    }
    else{
        createToastExtended("pauseStartFrag() - timerCDT is null;attempt to cancel");
    }
    dialog.show(getSupportFragmentManager(), "PauseDialogFragment");
 }


 // Code for PauseFragment

 //TODO: remove unuses imports on all files within project; 

 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.os.Bundle;
 import android.support.v4.app.DialogFragment;
 import android.view.LayoutInflater;

 public class PauseFragment extends DialogFragment {

public static boolean isPaused = false;
public FragmentCommunicator fComm;


@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        fComm = (FragmentCommunicator) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement FragmentCommunicator");
    }
}

@Override
public void onDetach() {
    super.onDetach();
    fComm = null;
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    isPaused = true;
    // Use the Builder class for convenient dialog construction
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

    // Get the layout inflater
    LayoutInflater inflater = getActivity().getLayoutInflater();

    // Inflate and set the layout for the dialog
    // Pass null as the parent view because its going in the dialog layout
    builder.setView(inflater.inflate(R.layout.fragment_pause, null))
           .setMessage(R.string.dialog_pause)
           .setPositiveButton(R.string.action_main_menu, new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int id) {
                   Intent i4 = new Intent(getActivity(), StartActivity.class);
                   startActivity(i4);
               }
           })
           .setNeutralButton(R.string.action_restart, new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int id) {
                   Intent i4 = new Intent(getActivity(), ModesActivity.class);
                   startActivity(i4);                   }
           })
           .setNegativeButton(R.string.action_resume, new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int id) {
                   // User cancelled the dialog
                   fComm.pauseFragmentResponse();
                   dismiss();
               }
           });
    // Create the AlertDialog object and return it
    return builder.create();
}

@Override
public void onDismiss(DialogInterface dialog) {
    super.onDismiss(dialog);
    isPaused = false;
}

public interface FragmentCommunicator {
    public void pauseFragmentResponse();
}
 }

最后,Idk如果有任何帮助,但我也尝试启动CountDownTimer timerCDT而没有FragmentCommunicator接口,但系统无法找到计时器?如果有人能够了解为什么会发生这种情况,我也会感激它。

说真的,最后一件事,如果计时器适用于游戏并且需要经常停止和更新,最好是使用CountDownTimer,TimerTask,实现Runnable的newThread还是处理程序或某种类型?我已经尝试了所有这些但是当我向应用程序添加组件和功能时,我需要更多的灵活性来改变时间,并且不太确定我是否走上了正确的道路。希望这篇文章不要太模糊。如果我需要分成多个帖子或其他东西,请告诉我......

一如既往地谢谢!

3 个答案:

答案 0 :(得分:2)

在这里看一下开发者网站http://developer.android.com/reference/android/os/CountDownTimer.html,看起来你可能应该在onTick方法中放置if语句,所以对于每个tick都要进行检查。

修改

好的,这对我来说很完美

private TextSwitcher TextSw;
private TextView TextSwTextView;

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(com.game.test.R.layout.sample);


    TextSw = (TextSwitcher) findViewById(R.id.TextSwitchView);
    TextSw.setFactory(new ViewSwitcher.ViewFactory() 
    {

        public View makeView() 
        {
            // Create a new TextView and set properties
            TextView textView = new TextView(getApplicationContext());
            textView.setLayoutParams(new TextSwitcher.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            textView.setTextSize(20);
            textView.setTextColor(Color.BLUE);

            return textView;
        }
    });
    mtimer = new CountDownTimer(60000, 1000) 
    {

        public void onTick(long millisUntilFinished) 
        {
            TextSwTextView = (TextView) TextSw.getChildAt(0); 
            if(millisUntilFinished < 10001)
                TextSwTextView.setTextColor(Color.RED);
            TextSwTextView.setText("seconds remaining: " + millisUntilFinished / 1000);
        }

        public void onFinish()
        {
            TextSwTextView.setText("done!");
        }
     }.start();

}

所以上面是你的简单版本,当计时器达到1000时,显示计时器的文本将变为红色。你应该可以将它构建到你的。

但你要做的主要是检查计时器在onTick方法中剩余多少,并将此处的文本颜色更改为 - 见上文

答案 1 :(得分:1)

这个帖子帮助我更轻松地解决了我的问题:

https://groups.google.com/forum/#!topic/android-developers/jdlUp_RlP2w

你可以像这样对textSwitcher中的textviews进行处理:

TextView t1 = (TextView) mSwitcher.getChildAt(0); 
TextView t2 = (TextView) mSwitcher.getChildAt(1); 

然后根据代码逻辑设置所需的颜色。

答案 2 :(得分:0)

TextView t1,t2;

textSwitcher = (TextSwitcher) findViewById(R.id.textView99);
textSwitcher.setInAnimation(this, R.anim.slide_in_right);
textSwitcher.setOutAnimation(this, R.anim.slide_out_left);
t1 = new TextView(this);
t2 = new TextView(this);
t1.setTextSize(20);
t2.setTextSize(20);
textSwitcher.addView(t1);
textSwitcher.addView(t2);