the app runs the way I want I can see that in the Logcat
but the text view is not changing and keeps the default value
i also tried to change button enable status programmatically but stayed in the same , nothing get changed !!
I tried in the setText method both
String.valueof(int)
and
Integer.toString(int)
java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
play =(Button) findViewById(R.id.button4);
Pause =(Button) findViewById(R.id.button5);
hourstext =(TextView) findViewById(R.id.textView1);
mintext =(TextView) findViewById(R.id.textView2);
sectext =(TextView) findViewById(R.id.textView3);
}
void playb(View v) {
while (!ispause) {
sec = 0 ;
while (sec < 60) {
SystemClock.sleep(1000);
sec++;
sectext.setText(Integer.toString(sec));
Log.d("this", "sec value=" + sec);
}
sec = 0;
min++;
Log.d("this","min value ="+min);
mintext.setText(String.valueOf(min));
}
}
XML
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="#+id/textView3"
android:layout_width="114dp"
android:layout_height="94dp"
android:layout_marginTop="159dp"
android:layout_marginEnd="16dp"
android:layout_x="274dp"
android:layout_y="120dp"
android:gravity="center|center_horizontal"
android:text="00"
android:textSize="40sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/pauseButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="72dp"
android:layout_marginTop="116dp"
android:layout_marginEnd="93dp"
android:layout_x="217dp"
android:layout_y="296dp"
android:enabled="false"
android:onClick="playb"
android:text="Pause"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/playbutton"
app:layout_constraintTop_toBottomOf="#+id/textView3" />
<Button
android:id="#+id/playbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="70dp"
android:layout_marginTop="116dp"
android:layout_x="63dp"
android:layout_y="293dp"
android:onClick="playb"
android:text="playb"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView2" />
<TextView
android:id="#+id/textView2"
android:layout_width="120dp"
android:layout_height="97dp"
android:layout_marginTop="156dp"
android:layout_marginEnd="17dp"
android:layout_x="139dp"
android:layout_y="117dp"
android:gravity="center|center_horizontal"
android:text="00"
android:textSize="40sp"
app:layout_constraintEnd_toStartOf="#+id/textView3"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView1"
android:layout_width="103dp"
android:layout_height="94dp"
android:layout_marginStart="16dp"
android:layout_marginTop="159dp"
android:layout_x="11dp"
android:layout_y="117dp"
android:gravity="center_horizontal|center_vertical"
android:text="00"
android:textSize="40sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
i get no error message ! the app keeps working but no updated textView
i've included my XML Code
It's likely to do with running everything on the main thread. You should never call sleep on the main thread or you will block the UI.
When the button is clicked you should start the counter on a background thread. You will then need to update the TextView on the main thread.
It can be achieved quite easily with RxJava:
private Disposable disposable;
disposable = Observable.interval(1, 1, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(value -> {
// Update UI
});
To stop the counter:
disposable.dispose();
If you want make counter up for 60 sec you can use this code
long time=60;
new CountDownTimer(time*1000, 1000)
{
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds : " + (time-millisUntilFinished /1000));
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
Before trying to fix this problem, let first understand why it happens
CAUSE
When you call View.setText(), Android doesn't actually set the text immediately. It pushes all of these set-text works to a queue on main thread to do LATER whenever it has free time.
Let's try to run this block, you will notice that until this while loop finish, View.setText() will not be done.
void playb(View v) {
min = 0
while (min < 1000000) {
min++
Log.d("this", "min value =$min")
mintext.setText(String.valueOf(min))
}
}
So in your situtation, actually the TextView will still be set, but you will not see the change until the while loop finishes.
SOLUTION
You should move this while loop to another thread, you can simply use an AsyncTask or a HandlerThread for that
Ex. Use a HandlerThread:
void playb() {
// Start a new background thread
HandlerThread thread = new HandlerThread("");
thread.start();
// Obtain the handler of new background thread
Handler handler = new Handler(thread.getLooper());
// Obtain the handler of main thread (UI Thread)
final Handler mainHandler = new Handler(this.getMainLooper());
// Create a runnable and send it to background thread to execute
handler.post(new Runnable() {
public final void run() {
// Do the job
int min = 0;
while(true) {
int sec = 0;
while(sec < 60) {
SystemClock.sleep(1000L);
sec ++;
final int currentSec = sec;
// Send the update-text job to main thread to execute
mainHandler.post(new Runnable() {
public final void run() {
secText.setText(currentSec);
}
});
}
sec = 0;
min++;
final int currentMin = min;
// Send the update-text job to main thread to execute
mainHandler.post(new Runnable() {
public final void run() {
minText.setText(currentMin);
}
});
}
}
});
}
Related
I am trying to familiarize myself with Java Conditions.
Purpose:
Using the following code, I created a simple counter app that races to the stars after clicking start. You can start/stop, pause/resume the counter.
The intended purpose is (for me) to allow a function(s) to run as long as the lock is not locked. The moment the lock is locked, the incrementing should stop until resume is clicked.
Looking over this example and this SO question, I tried to implement my own version - this is not successful.
Problem:
Clicking start, the counter runs. The moment I hit pause, the lock locks correctly but an java.lang.IllegalMonitorStateException occurs when the executor runnable hits the waitCondition.await(); line.
Stack Trace:
E/AndroidRuntime: FATAL EXCEPTION: ForkJoinPool-1-worker-1
Process: nmu.wrpv302.myapplication, PID: 11744
java.lang.IllegalMonitorStateException
at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:156)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1291)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.fullyRelease(AbstractQueuedSynchronizer.java:1752)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2064)
at com.example.myapplication.MainActivity.lambda$start$2$MainActivity(MainActivity.java:61)
^ --------------------- PROBLEM -----------------------
at com.example.myapplication.-$$Lambda$MainActivity$te94WnCx7dwprXfxnjJZuoEc1_8.run(Unknown Source:4)
at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1411)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:285)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1155)
at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1993)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1941)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Activity Code:
public class MainActivity extends AppCompatActivity {
private TextView lblCounter;
private Button btnStartStop, btnPauseResume;
private ReentrantLock pauseLock = new ReentrantLock();
private Condition waitCondition = pauseLock.newCondition();
private ExecutorService executorService = Executors.newWorkStealingPool(4);
private AtomicBoolean stopStart = new AtomicBoolean(true);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lblCounter = findViewById(R.id.counter);
btnStartStop = findViewById(R.id.startStop);
btnPauseResume = findViewById(R.id.pauseResume);
btnStartStop.setOnClickListener(v -> {
if (stopStart.get()) {
start();
} else {
stop();
}
});
btnPauseResume.setOnClickListener(v -> {
pauseResume();
});
}
public void start() {
btnStartStop.setText("Stop");
AtomicInteger i = new AtomicInteger(0);
executorService.execute(() -> {
while (true) {
while (pauseLock.isLocked()) {
try {
waitCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int i1 = i.incrementAndGet();
lblCounter.setText(String.valueOf(i1));
}
});
}
public void stop() {
executorService.shutdownNow();
btnStartStop.setText("Start");
}
public void pauseResume() {
if (pauseLock.isLocked()) {
pauseLock.unlock();
waitCondition.signal();
btnPauseResume.setText("Pause");
} else {
pauseLock.lock();
btnPauseResume.setText("Resume");
}
}
}
Activity XML:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="#+id/counter"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="96dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="96dp"
android:text="123"
android:textColor="#000000"
android:textSize="36sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView" />
<Button
android:id="#+id/startStop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="128dp"
android:text="Start"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/pauseResume"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="#+id/pauseResume"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pause"
app:layout_constraintBottom_toBottomOf="#+id/startStop"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="#+id/startStop" />
<TextView
android:id="#+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="96dp"
android:layout_marginTop="128dp"
android:layout_marginEnd="96dp"
android:text="Counter"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
You can’t unlock the lock and then signal using it. The lock has to be held by the thread that calls await or signal on the lock’s conditions. The api doc says:
The current thread is assumed to hold the lock associated with this Condition when this method is called.
Not having that lock held leads to the exception being thrown.
That means you can’t use the isLocked check to decide if you’re done waiting. If you look at the code example on the linked question it shows that put and take each use their own condition, and they test variables indicating the buffer’s current state in order to decide whether to wait or signal.
I am using a progress bar sample from Github however I noticed that the progress bar fill is set to a fixed value. For example, if the step count goal is 10 (.java class) the man should be "10" in the .XML
My goal: when the user inputs their goal step count, the "10" should be variable and change depending on user input.
java snippet:
ProgressBar progressBar = (ProgressBar) this.findViewById(R.id.progressBar);
ObjectAnimator animation = ObjectAnimator.ofInt(progressBar, "progress", lastStep, stepCounter); //animate only from last known step to current step count
animation.setDuration(5000); // in milliseconds
animation.setInterpolator(new DecelerateInterpolator());
animation.start();
lastStep = stepCounter;
XML snippet
<ProgressBar
android:id="#+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="376dp"
android:layout_height="392dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:max="10"
android:progress="0"
android:progressDrawable="#drawable/circular" />
EDIT********************EDIT
Sorry maybe my question wasn't clear. To provide an example...if the users step goal is 500. I need the progress bar to fill respectively. Therefore, IF step_count = 250 then progress bar should be half full, IF step_count = 750 then should be 3/4 full. I need the progression to be respective to a variable value.
Set android:indeterminate="false". See this fully implemented code
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<ProgressBar
android:id="#+id/pBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="100dp"
android:layout_marginTop="200dp"
android:minHeight="50dp"
android:minWidth="200dp"
android:max="100"
android:indeterminate="false"
android:progress="0" />
<TextView
android:id="#+id/tView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/pBar"
android:layout_below="#+id/pBar" />
<Button
android:id="#+id/btnShow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="130dp"
android:layout_marginTop="20dp"
android:text="Start Progress"
android:layout_below="#+id/tView"/>
public class MainActivity extends AppCompatActivity {
private ProgressBar pgsBar;
private int i = 0;
private TextView txtView;
private Handler hdlr = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pgsBar = (ProgressBar) findViewById(R.id.pBar);
txtView = (TextView) findViewById(R.id.tView);
Button btn = (Button)findViewById(R.id.btnShow);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
i = pgsBar.getProgress();
new Thread(new Runnable() {
public void run() {
while (i < 100) {
i += 1;
// Update the progress bar and display the current value in text view
hdlr.post(new Runnable() {
public void run() {
pgsBar.setProgress(i);
txtView.setText(i+"/"+pgsBar.getMax());
}
});
try {
// Sleep for 100 milliseconds to show the progress slowly.
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
});
}
}
How to make an app to count the time since the first time opened? I have no idea which class to use. Is it possible to achieve this with a stopwatch or something similar? Can someone pls share some code? I don't know what to search on the internet just have an idea of what I want to build. Or just tell me an idea with what I can achieve this and how?
statisticLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (plusiliminus==0){
Toast.makeText(getActivity(),R.string.toaststatistic,Toast.LENGTH_SHORT).show();
} else {
Fragment fragmentstatistic=new Statistic();
FragmentTransaction transaction=getActivity().getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frameLayout,fragmentstatistic).commit();
}
}
});
As far as I could understand, you need persistent storage for the time when it was first used. I think SharedPreferences is a good way of storing this in your case.
In the onCreate function of your launcher activity, you might get the System.currentTimeInMillis() and store it in the SharedPreferences as stated here.
Then when you need to reset the time, you just have to clear the value in the SharedPreferences and can set a new value again.
I hope this gives you an idea of your implementation.
You have basically to do two things.
Get the current time when you start the app, or press a button using something like
Date currentTime = Calendar.getInstance().getTime();
This is a good beginning, you get the time, then you have to parse this time in a format you want to show to the user then you manage a stop and reset button as showed for instance in this tutorial
So you build a TextView and you show in real time the seconds, parsed in the way you need
import android.os.Handler;
import android.os.SystemClock;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
TextView timer ;
Button start, pause, reset;
long MillisecondTime, StartTime, TimeBuff, UpdateTime = 0L ;
Handler handler;
int Seconds, Minutes, MilliSeconds ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timer = (TextView)findViewById(R.id.tvTimer);
start = (Button)findViewById(R.id.btStart);
pause = (Button)findViewById(R.id.btPause);
reset = (Button)findViewById(R.id.btReset);
handler = new Handler() ;
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
StartTime = SystemClock.uptimeMillis();
handler.postDelayed(runnable, 0);
reset.setEnabled(false);
}
});
pause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
TimeBuff += MillisecondTime;
handler.removeCallbacks(runnable);
reset.setEnabled(true);
}
});
reset.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
MillisecondTime = 0L ;
StartTime = 0L ;
TimeBuff = 0L ;
UpdateTime = 0L ;
Seconds = 0 ;
Minutes = 0 ;
MilliSeconds = 0 ;
timer.setText("00:00:00");
}
});
}
public Runnable runnable = new Runnable() {
public void run() {
MillisecondTime = SystemClock.uptimeMillis() - StartTime;
UpdateTime = TimeBuff + MillisecondTime;
Seconds = (int) (UpdateTime / 1000);
Minutes = Seconds / 60;
Seconds = Seconds % 60;
MilliSeconds = (int) (UpdateTime % 1000);
timer.setText("" + Minutes + ":"
+ String.format("%02d", Seconds) + ":"
+ String.format("%03d", MilliSeconds));
handler.postDelayed(this, 0);
}
};
}
and the view of activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorPrimary"
tools:context="in.amitsin6h.stopwatch.MainActivity">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:paddingBottom="90dp">
<TextView
android:text="00:00:00"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tvTimer"
android:textSize="50dp"
android:textStyle="bold"
android:textColor="#ffffff"
android:layout_marginTop="120dp"
android:paddingBottom="50dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
<Button
android:text="Start"
android:background="#ffffff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/tvTimer"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="41dp"
android:id="#+id/btStart" />
<Button
android:text="Pause"
android:background="#ffffff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/btPause"
android:layout_alignBaseline="#+id/btStart"
android:layout_alignBottom="#+id/btStart"
android:layout_centerHorizontal="true" />
<Button
android:text="Reset"
android:background="#ffffff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/btPause"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:id="#+id/btReset" />
</RelativeLayout>
</android.support.constraint.ConstraintLayout>
I am trying to use splash screen for my app.
I want to display Count down timer in my splash screen.
So far I am able to achieve the splash screen working but don't know how to display count down timer. I created layout for count down timer. I want splash screen to stay for 5 Hours then take to the next activity.
Splashactivity.java
public class splash_screen extends AppCompatActivity {
private float imageAplha = 1f;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_screen);
//splashScreenUseTimer(5000);
splashScreenUseAsyncTask();
}
// Show splash screen until network load data complete.
private void splashScreenUseAsyncTask()
{
// Create a AsyncTask object.
final RetrieveDateTask retrieveDateTask = new RetrieveDateTask();
retrieveDateTask.execute("", "", "");
// Get splash image view object.
final ImageView splashImageView = (ImageView) findViewById(R.id.logo_id);
// Create a count down timer object.It will count down every 0.1 seconds and last for milliSeconds milliseconds..
CountDownTimer countDownTimer = new CountDownTimer(5000, 100) {
#Override
public void onTick(long l) {
// Reduce the splash screen background image's alpha value for each count down.
splashImageView.setAlpha(imageAplha);
imageAplha -= 0.1;
if(imageAplha <= 0)
{
imageAplha = 1;
}
}
#Override
public void onFinish() {
// When count down complete, set the image to invisible.
imageAplha = 0;
splashImageView.setAlpha(imageAplha);
// If AsyncTask is not complete, restart the counter to count again.
if(!retrieveDateTask.isAsyncTaskComplete()) {
this.start();
}
}
};
// Start the count down timer.
countDownTimer.start();
}
// This is the async task class that get data from network.
private class RetrieveDateTask extends AsyncTask<String, String, String>{
// Indicate whether AsyncTask complete or not.
private boolean asyncTaskComplete = false;
public boolean isAsyncTaskComplete() {
return asyncTaskComplete;
}
public void setAsyncTaskComplete(boolean asyncTaskComplete) {
this.asyncTaskComplete = asyncTaskComplete;
}
// This method will be called before AsyncTask run.
#Override
protected void onPreExecute() {
this.asyncTaskComplete = false;
}
// This method will be called when AsyncTask run.
#Override
protected String doInBackground(String... strings) {
try {
// Simulate a network operation which will last for 10 seconds.
Thread currTread = Thread.currentThread();
for (int i = 0; i < 10; i++) {
currTread.sleep(1000);
}
}catch(Exception ex)
{
ex.printStackTrace();
}finally {
return null;
}
}
// This method will be called after AsyncTask run.
#Override
protected void onPostExecute(String s) {
// Start SplashScreenMainActivity.
Intent mainIntent = new Intent(splash_screen.this,
MainActivity.class);
splash_screen.this.startActivity(mainIntent);
// Close SplashScreenActivity.
splash_screen.this.finish();
this.asyncTaskComplete = true;
}
}
}
Layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0"
android:background="#color/White"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<ImageView
android:id="#+id/logo_id"
android:layout_width="350dp"
android:layout_height="match_parent"
app:srcCompat="#drawable/ts_logo"
android:layout_gravity="center"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:orientation="vertical">
<LinearLayout
android:id="#+id/linear_layout_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/black"
android:visibility="visible">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="#+id/tv_hour"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="00"
android:textColor="#android:color/white"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:id="#+id/tv_hour_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Hour"
android:textColor="#android:color/white"
android:textSize="20dp"
android:textStyle="normal" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="#+id/tv_minute"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="00"
android:textColor="#android:color/white"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:id="#+id/tv_minute_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Minute"
android:textColor="#android:color/white"
android:textSize="20dp"
android:textStyle="normal" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="#+id/tv_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="00"
android:textColor="#android:color/white"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:id="#+id/tv_second_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Second"
android:textColor="#android:color/white"
android:textSize="20dp"
android:textStyle="normal" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
#contact dummy I edited #Dev code with small modification.try this one. Based on your animation requirement increase and decrease imageAlpha size.
private float imageAplha = 1f;
private boolean imageStatus = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
splashScreenUseAsyncTask();
}
// Show splash screen until network load data complete.
private void splashScreenUseAsyncTask()
{
// Create a AsyncTask object.
final RetrieveDateTask retrieveDateTask = new RetrieveDateTask();
retrieveDateTask.execute("", "", "");
// Get splash image view object.
final ImageView splashImageView = (ImageView) findViewById(R.id.logo_id);
final TextView tv_hour = (TextView) findViewById(R.id.tv_hour);
final TextView tv_minute = (TextView) findViewById(R.id.tv_minute);
final TextView tv_second = (TextView) findViewById(R.id.tv_second);
// Create a count down timer object.It will count down every 0.1 seconds and last for milliSeconds milliseconds..
final int time= 3600000*5;
CountDownTimer countDownTimer = new CountDownTimer(time, 1000) {
#Override
public void onTick(long l) {
long Days = l / (24 * 60 * 60 * 1000);
long Hours = l / (60 * 60 * 1000) % 24;
long Minutes = l / (60 * 1000) % 60;
long Seconds = l / 1000 % 60;
//
// tv_days.setText(String.format("%02d", Days));
tv_hour.setText(String.format("%02d", Hours));
tv_minute.setText(String.format("%02d", Minutes));
tv_second.setText(String.format("%02d", Seconds));
splashImageView.setAlpha(imageAplha);
if(imageStatus){
imageAplha += 1;
if(imageAplha >= 1)
{
// imageAplha-= 0.5;
imageStatus = false;
}
}else{
imageAplha -= 1;
if(imageAplha <= 0)
{
imageStatus = true;
}
}
}
#Override
public void onFinish() {
// When count down complete, set the image to invisible.
imageAplha = 0;
splashImageView.setAlpha(imageAplha);
// If AsyncTask is not complete, restart the counter to count again.
if(!retrieveDateTask.isAsyncTaskComplete()) {
this.start();
}
}
};
// Start the count down timer.
countDownTimer.start();
}
// This is the async task class that get data from network.
private class RetrieveDateTask extends AsyncTask<String, String, String> {
// Indicate whether AsyncTask complete or not.
private boolean asyncTaskComplete = false;
public boolean isAsyncTaskComplete() {
return asyncTaskComplete;
}
public void setAsyncTaskComplete(boolean asyncTaskComplete) {
this.asyncTaskComplete = asyncTaskComplete;
}
// This method will be called before AsyncTask run.
#Override
protected void onPreExecute() {
this.asyncTaskComplete = false;
}
// This method will be called when AsyncTask run.
#Override
protected String doInBackground(String... strings) {
try {
// Simulate a network operation which will last for 10 seconds.
Thread currTread = Thread.currentThread();
for (int i = 0; i < 18000000; i++) {
currTread.sleep(1000);
}
}catch(Exception ex)
{
ex.printStackTrace();
}finally {
return null;
}
}
// This method will be called after AsyncTask run.
#Override
protected void onPostExecute(String s) {
// Start SplashScreenMainActivity.
Intent mainIntent = new Intent(splash_screen .this,
MainActvity.class);
splash_screen.this.startActivity(mainIntent);
// Close SplashScreenActivity.
splash_screen.this.finish();
this.asyncTaskComplete = true;
}
}
}
#contact dummy I have edited your code try using this
// Show splash screen until network load data complete.
private void splashScreenUseAsyncTask()
{
// Create a AsyncTask object.
final RetrieveDateTask retrieveDateTask = new RetrieveDateTask();
retrieveDateTask.execute("", "", "");
// Get splash image view object.
final ImageView splashImageView = (ImageView) findViewById(R.id.logo_id);
//for 5 Hours
final int time= 3600000*5;
CountDownTimer countDownTimer = new CountDownTimer(time, 1000) {
#Override
public void onTick(long l) {
long Days = l / (24 * 60 * 60 * 1000);
long Hours = l / (60 * 60 * 1000) % 24;
long Minutes = l / (60 * 1000) % 60;
long Seconds = l / 1000 % 60;
//
tv_days.setText(String.format("%02d", Days));
tv_hour.setText(String.format("%02d", Hours));
tv_minute.setText(String.format("%02d", Minutes));
tv_second.setText(String.format("%02d", Seconds));
splashImageView.setAlpha(imageAplha);
imageAplha -= 0.1;
if(imageAplha <= 0)
{
imageAplha = 1;
}
}
#Override
public void onFinish() {
// When count down complete, set the image to invisible.
imageAplha = 0;
splashImageView.setAlpha(imageAplha);
// If AsyncTask is not complete, restart the counter to count again.
if(!retrieveDateTask.isAsyncTaskComplete()) {
this.start();
}
}
};
// Start the count down timer.
countDownTimer.start();
}
When I click the button my app crashes and I have no idea why. I've looked up my code a lot of times but can't seem to find any "major flaws". The purpose of the app is just clicking the button twice as fast as possible and it displays the amount of time needed from the first tap to the second tap. Some sort of reaction thing. I used a timer because I didn't know what else to use.
(Value of start time) - (value of current timer) = (time between first and second click).
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
tools:context="com.keklabs.reactiontimer.MainActivity">
<TextView
android:id="#+id/scoreText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="78dp"
android:text="Click below to start!"
android:textColor="#39FF14"
android:textSize="30dp" />
<Button
android:id="#+id/startStopButton"
android:layout_width="match_parent"
android:layout_height="350dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="#000000"
android:text="Start / Stop"
android:textSize="25dp"
android:textColor="#39FF14" />
</RelativeLayout>
public class MainActivity extends AppCompatActivity {
private final long startTime = 0;
private final long interval = 100;
private boolean buttonClicked;
private Button startStopButton;
private TextView scoreText;
CountDownTimer timer = new CountDownTimer(30000, 100) {
#Override
public void onTick(long millisUntilFinished) {
scoreText.setText("kek"); //displayed text is value of starttime (30000) - current value of timer,
} //some sort of reaction game thing
#Override
public void onFinish() {
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView scoreText = (TextView) findViewById(R.id.scoreText);
Button startStopButton = (Button) findViewById(R.id.startStopButton);
startStopButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!buttonClicked) {
timer.start();
buttonClicked = true;
}
else {
timer.cancel();
buttonClicked = false;
}
}
});
}
}
EDIT
How do i do it the right way in the line scoreText.setText(startTime - millisUntilFinished); to display startTime-current timer value?
CountDownTimer timer = new CountDownTimer(startTime, interval) {
#Override
public void onTick(long millisUntilFinished) {
scoreText.setText(startTime - millisUntilFinished);
}
#Override
public void onFinish() {
}
};
Actually, you are declaring your TextView scoreText twice. One gloabally and other locally. You can replace TextView scoreText = (TextView) findViewById(R.id.scoreText);
to scoreText = (TextView) findViewById(R.id.scoreText);
in your onCreate()