I've been learning some java for android by reading and trying codes, and whenever I start the application on android it crashes. In the LogCat, this shows:
08-09 16:13:24.033: E/AndroidRuntime(839): ... 11 more
Here is my activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dip">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="Brews: " />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="None"
android:gravity="end"
android:textSize="20sp"
android:id="#+id/brew_count_label" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:padding="10dip">
<Button
android:id="#+id/brew_time_down"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="-"
android:textSize="40sp" />
<TextView
android:id="#+id/brew_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0:00"
android:textSize="40sp"
android:padding="10dip" />
<Button
android:id="#+id/brew_time_up"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="+"
android:textSize="40sp" />
</LinearLayout>
<Button
android:id="#+id/brew_start"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="Start" />
</LinearLayout>
And here is my MainActivity.java:
package com.example.basketball;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends ActionBarActivity implements OnClickListener {
/** Properties **/
protected Button brewAddTime;
protected Button brewDecreaseTime;
protected Button startBrew;
protected TextView brewCountLabel;
protected TextView brewTimeLabel;
protected int brewTime = 3;
protected CountDownTimer brewCountDownTimer;
protected int brewCount = 0;
protected boolean isBrewing = false;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
// Connect interface elements to properties
brewAddTime = (Button) findViewById(R.id.brew_time_up);
brewDecreaseTime = (Button) findViewById(R.id.brew_time_down);
startBrew = (Button) findViewById(R.id.brew_start);
brewCountLabel = (TextView) findViewById(R.id.brew_count_label);
brewTimeLabel = (TextView) findViewById(R.id.brew_time);
// Setup ClickListeners
brewAddTime.setOnClickListener(this);
brewDecreaseTime.setOnClickListener(this);
startBrew.setOnClickListener(this);
// Set the initial brew values
setBrewCount(0);
setBrewTime(3);
}
/** Methods **/
/**
* Set an absolute value for the number of minutes to brew. Has no effect if a brew
* is currently running.
* #param minutes The number of minutes to brew.
*/
public void setBrewTime(int minutes) {
if(isBrewing)
return;
brewTime = minutes;
if(brewTime < 1)
brewTime = 1;
brewTimeLabel.setText(String.valueOf(brewTime) + "m");
}
/**
* Set the number of brews that have been made, and update the interface.
* #param count The new number of brews
*/
public void setBrewCount(int count) {
brewCount = count;
brewCountLabel.setText(String.valueOf(brewCount));
}
/**
* Start the brew timer
*/
public void startBrew() {
// Create a new CountDownTimer to track the brew time
brewCountDownTimer = new CountDownTimer(brewTime * 60 * 1000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
brewTimeLabel.setText(String.valueOf(millisUntilFinished / 1000) + "s");
}
#Override
public void onFinish() {
isBrewing = false;
setBrewCount(brewCount + 1);
brewTimeLabel.setText("Brew Up!");
startBrew.setText("Start");
}
};
brewCountDownTimer.start();
startBrew.setText("Stop");
isBrewing = true;
}
/**
* Stop the brew timer
*/
public void stopBrew() {
if(brewCountDownTimer != null)
brewCountDownTimer.cancel();
isBrewing = false;
startBrew.setText("Start");
}
/** Interface Implementations **/
/* (non-Javadoc)
* #see android.view.View.OnClickListener#onClick(android.view.View)
*/
public void onClick(View v) {
if(v == brewAddTime)
setBrewTime(brewTime + 1);
else if(v == brewDecreaseTime)
setBrewTime(brewTime -1);
else if(v == startBrew) {
if(isBrewing)
stopBrew();
else
startBrew();
}
}
}
Anyone knows how to fix this error?
Please help.
Please uncomment setContentView(R.layout.main); and change that line to setContentView(R.layout.activity_main); in
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
Related
Hi i'm a beginner in android app development.
I need help making my app. so my app is a simple Timer with progress bar which works fine.
Now i need to make that "progress bar's" to draw over other apps even if the app is minimized or closed until the timer expires.
So for this I tried many things in many ways like i used Window Manager and other things in a service class, i even separated progress bar into different layout.
help me with code. the following contains code which works fine within app.
1)Main Activity.java
import android.animation.ObjectAnimator;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.concurrent.TimeUnit;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private long timeCountInMilliSeconds = 1 * 60000;
private enum TimerStatus {
STARTED,
STOPPED
}
private TimerStatus timerStatus = TimerStatus.STOPPED;
private ProgressBar progressBar;
private ProgressBar progressBar1;
private EditText editTextMinute;
private TextView textViewTime;
private ImageView imageViewReset;
private ImageView imageViewStartStop;
private CountDownTimer countDownTimer;
private ObjectAnimator smoothAnimation;
private ObjectAnimator smoothAnimation1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// method call to initialize the views
initViews();
// method call to initialize the listeners
initListeners();
}
/**
* method to initialize the views
*/
private void initViews() {
progressBar = findViewById(R.id.progress_bar);
progressBar1 = findViewById(R.id.progress_bar1);
editTextMinute = findViewById(R.id.editTextMinute);
textViewTime = findViewById(R.id.textViewTime);
imageViewReset = findViewById(R.id.imageViewReset);
imageViewStartStop = findViewById(R.id.imageViewStartStop);
}
/**
* method to initialize the click listeners
*/
private void initListeners() {
imageViewReset.setOnClickListener(this);
imageViewStartStop.setOnClickListener(this);
}
/**
* implemented method to listen clicks
*
* #param view
*/
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.imageViewReset:
reset();
break;
case R.id.imageViewStartStop:
startStop();
break;
}
}
/**
* method to reset count down timer
*/
private void reset() {
stopCountDownTimer();
startCountDownTimer();
}
/**
* method to start and stop count down timer
*/
private void startStop() {
if (timerStatus == TimerStatus.STOPPED) {
// call to initialize the timer values
setTimerValues();
// call to initialize the progress bar values
setProgressBarValues();
// showing the reset icon
imageViewReset.setVisibility(View.VISIBLE);
// changing play icon to stop icon
imageViewStartStop.setImageResource(R.drawable.icon_stop);
// making edit text not editable
editTextMinute.setEnabled(false);
// changing the timer status to started
timerStatus = TimerStatus.STARTED;
// call to start the count down timer
startCountDownTimer();
} else {
// hiding the reset icon
imageViewReset.setVisibility(View.GONE);
// changing stop icon to start icon
imageViewStartStop.setImageResource(R.drawable.icon_start);
// making edit text editable
editTextMinute.setEnabled(true);
// changing the timer status to stopped
timerStatus = TimerStatus.STOPPED;
stopCountDownTimer();
}
}
/**
* method to initialize the values for count down timer
*/
private void setTimerValues() {
int time = 0;
if (!editTextMinute.getText().toString().isEmpty()) {
// fetching value from edit text and type cast to integer
time = Integer.parseInt(editTextMinute.getText().toString().trim());
} else {
// toast message to fill edit text
Toast.makeText(getApplicationContext(), getString(R.string.message_minutes), Toast.LENGTH_LONG).show();
}
// assigning values after converting to milliseconds
timeCountInMilliSeconds = time * 1000;
}
/**
* method to start count down timer
*/
private void startCountDownTimer() {
//left side Progress Bar
smoothAnimation = ObjectAnimator.ofInt(progressBar, "progress", progressBar.getProgress(), progressBar.getMax());
smoothAnimation.setDuration(5);
smoothAnimation.setInterpolator(new AccelerateInterpolator());
//right side Progress Bar
smoothAnimation1 = ObjectAnimator.ofInt(progressBar, "progress", progressBar1.getProgress(), progressBar1.getMax());
smoothAnimation1.setDuration(5);
smoothAnimation1.setInterpolator(new AccelerateInterpolator());
countDownTimer = new CountDownTimer(timeCountInMilliSeconds, 10) {
#Override
public void onTick(long millisUntilFinished) {
Log.d("TAG", "ON Tick Called "+millisUntilFinished);
textViewTime.setText(hmsTimeFormatter(millisUntilFinished+1000));
progressBar.setProgress((int) (timeCountInMilliSeconds / 10 - millisUntilFinished / 10));
progressBar1.setProgress((int) (timeCountInMilliSeconds / 10 - millisUntilFinished / 10));
}
#Override
public void onFinish() {
textViewTime.setText(hmsTimeFormatter(timeCountInMilliSeconds));
// call to initialize the progress bar values
setProgressBarValues();
// hiding the reset icon
imageViewReset.setVisibility(View.GONE);
// changing stop icon to start icon
imageViewStartStop.setImageResource(R.drawable.icon_start);
// making edit text editable
editTextMinute.setEnabled(true);
// changing the timer status to stopped
timerStatus = TimerStatus.STOPPED;
smoothAnimation.end();
}
}.start();
smoothAnimation.start();
countDownTimer.start();
}
/**
* method to stop count down timer
*/
private void stopCountDownTimer() {
countDownTimer.cancel();
}
/**
* method to set circular progress bar values
*/
private void setProgressBarValues() {
progressBar.setMax((int) (timeCountInMilliSeconds / 10));
progressBar.setProgress((int) (timeCountInMilliSeconds / 10));
progressBar1.setMax((int) (timeCountInMilliSeconds / 10));
progressBar1.setProgress((int) (timeCountInMilliSeconds / 10));
}
/**
* method to convert millisecond to time format
*
* #param milliSeconds
* #return HH:mm:ss time formatted string
*/
private String hmsTimeFormatter(long milliSeconds) {
String hms = String.format("%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(milliSeconds),
TimeUnit.MILLISECONDS.toMinutes(milliSeconds) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(milliSeconds)),
TimeUnit.MILLISECONDS.toSeconds(milliSeconds) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(milliSeconds)));
return hms;
}
}
2)activity.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorBackground">
<ProgressBar
android:id="#+id/progress_bar"
android:animationResolution="6000"
style="#android:style/Widget.ProgressBar.Horizontal"
android:layout_width="14dp"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:max="100"
android:progress="0"
android:progressDrawable="#drawable/progressbar_vertical" />
<ProgressBar
android:id="#+id/progress_bar1"
style="#android:style/Widget.ProgressBar.Horizontal"
android:layout_width="14dp"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:animationResolution="6000"
android:max="100"
android:progress="0"
android:progressDrawable="#drawable/progressbar_vertical" />
<EditText
android:id="#+id/editTextMinute"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/textViewTime"
android:layout_centerHorizontal="true"
android:layout_marginBottom="10dp"
android:gravity="center"
android:hint="#string/hint_minute"
android:inputType="number"
android:maxLength="15"
android:maxLines="1"
android:minEms="5"
android:text=""
android:textColor="#color/colorYellow"
android:textColorHint="#color/colorYellow" />
<TextView
android:id="#+id/textViewTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="00:01:00"
android:textColor="#color/colorYellow"
android:textSize="40sp" />
<ImageView
android:id="#+id/imageViewStartStop"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_below="#+id/textViewTime"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:src="#drawable/icon_start" />
<ImageView
android:id="#+id/imageViewReset"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_below="#+id/imageViewStartStop"
android:layout_centerInParent="true"
android:layout_marginTop="30dp"
android:src="#drawable/icon_reset"
tools:visibility="visible"
android:visibility="gone" />
</RelativeLayout>
The following contains some screenshots please take a look.
Timer pic
Timer pic 2
The Above code works
Now i added service code that i am trying
-ProgressBarService.java (In this i don't know which code should i move from main activity to this and HOW??)
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import static android.view.Gravity.END;
public class ProgressBarService extends Service {
private WindowManager mWindowManager;
private View mProgressView;
public ProgressBarService() {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#SuppressLint("InflateParams")
#Override
public void onCreate() {
super.onCreate();
mProgressView = LayoutInflater.from(this).inflate(R.layout.progressbar_view, null);
final WindowManager.LayoutParams paramsProgress = getLayoutParams();
paramsProgress.gravity=END;
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
if (mWindowManager != null) {
mWindowManager.addView(mProgressView, paramsProgress);
}
}
private WindowManager.LayoutParams getLayoutParams() {
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
return params;
}
#Override
public void onDestroy() {
super.onDestroy();
if (mProgressView != null) mWindowManager.removeView(mProgressView);
}
}
-progressbar_view (seperated from activity_main)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:id="#+id/progress_bar"
android:animationResolution="6000"
style="#android:style/Widget.ProgressBar.Horizontal"
android:layout_width="14dp"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:max="100"
android:progress="100"
android:progressDrawable="#drawable/progressbar_vertical" />
<!-- <ProgressBar
android:id="#+id/progress_bar1"
style="#android:style/Widget.ProgressBar.Horizontal"
android:layout_width="14dp"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:animationResolution="6000"
android:max="100"
android:progress="100"
android:progressDrawable="#drawable/progressbar_vertical" />-->
</RelativeLayout>
this is the part of concern-------
public void incrementQ(View view) {
int variableI = 2;
variableI = variableI + 1;
display(variableI);
}
this question is regarding the Udacity's Basics Android Development Program Lesson no. 1 Making an app interactive: part 1.......18. Quiz:Update quantity variable
this is the complete code of MainActivity.java below-----
package com.example.user1.a1;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
import java.text.NumberFormat;
/**
* This app displays an order form to order coffee.
*/
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
* This method is called when the order button is clicked.
*/
public void submitOrder(View view) {
int variableC = 2;
display(variableC);
displayPrice(variableC * 5);
}
public void incrementQ(View view) {
int variableI = 2;
variableI = variableI + 1;
display(variableI);
}
public void decrementQ(View view){
int variableD = 2;
variableD = variableD - 1;
display(variableD);
}
/**
* This method displays the given quantity value on the screen.
*/
private void display(int number) {
TextView quantityTextView = (TextView) findViewById(
R.id.quantity_text_view);
quantityTextView.setText("" + number);
}
/**
* This method displays the given price on the screen.
*/
private void displayPrice(int number) {
TextView priceTextView = (TextView) findViewById(R.id.pricein$);
priceTextView.setText(NumberFormat.getCurrencyInstance().format(number));
}
this is the xml code..just in case
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
tools:context="com.example.user1.a1.MainActivity"
android:weightSum="1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="#string/quantity"
android:textAllCaps="true" />
<Button
android:id="#+id/button2"
android:layout_width="48dp"
android:layout_height="48dp"
android:onClick="incrementQ"
android:text="#string/goonakar" />
<TextView
android:id="#+id/quantity_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/_0"
android:textColor="#000000"
android:textSize="16sp" />
<Button
android:id="#+id/button3"
android:layout_width="48dp"
android:layout_height="48dp"
android:onClick="decrementQ"
android:text="#string/bhagakar" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/price"
android:textColor="#000000"
android:textSize="16sp" />
<TextView
android:id="#+id/pricein$"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/$0"
android:textColor="#000000"
android:textSize="16sp" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:onClick="submitOrder"
android:text="#string/order"
android:textAllCaps="true" />
</LinearLayout>
It seems really weird that you are reinitializing the variableI in every call. You should try to put all variables outside of the function:
int variableI = 2;
public void incrementQ(View view) {
variableI = variableI + 1;
display(variableI);
}
This could possibly be required to be applied in multiple locations in your code.
i do array list with images thet i want them to run with 2 buttons thet go next pic and beck pic i dont know the code for this i thx all for the time you spend for help.
ackage com.example.hanansanag.mytourneyccreator;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import java.util.ArrayList;
/**
* Created by ssh on 25/12/2016.
*/
public class Players extends AppCompatActivity implements View.OnClickListener {
protected Button btnNext, btnBack;
protected String fname;
protected String Lname;
protected String team;
protected ImageView iv;
protected ArrayList array_image;
int i = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.team_pic);
ArrayList<Integer> array_image = new ArrayList<Integer>();
array_image.add(R.drawable.bacelona);
array_image.add(R.drawable.athlethiko);
array_image.add(R.drawable.arsenak);
array_image.add(R.drawable.chelsea);
array_image.add(R.drawable.dortmond);
array_image.add(R.drawable.city);
array_image.add(R.drawable.bayernunchen);
array_image.add(R.drawable.intermilan);
array_image.add(R.drawable.psj);
array_image.add(R.drawable.realmadrid);
array_image.add(R.drawable.leverpool);
array_image.add(R.drawable.milan);
array_image.add(R.drawable.juventus);
array_image.add(R.drawable.ashkelon);
array_image.add(R.drawable.macabiheifa);
array_image.add(R.drawable.macabitelaviv);
array_image.add(R.drawable.beitaryeroshlaim);
array_image.add(R.drawable.apoelbersheva);
iv = (ImageView) findViewById(R.id.imageView);
btnNext = (Button) findViewById(R.id.btnNextPic);
btnBack = (Button) findViewById(R.id.btnBeckPic);
btnBack.setOnClickListener(this);
btnNext.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (i <= 0 || i >= array_image.length) {
return;
}
if (btnNext == v) {
iv.setImageResource(array_image.get(i++));
} else if (btnBack == v) {
iv.setBackgroundResource(array_image.get(i--));
}
}
}
**what can i do here in this line of code thet the pic will move : **
#Override
public void onClick(View v) {
if (i <= 0 || i >= array_image.length) {
return;
}
if (btnNext == v) {
iv.setImageResource(array_image.get(i++));
} else if (btnBack == v) {
iv.setBackgroundResource(array_image.get(i--));
}
}
this is the xml;
<?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"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/teamimage">
<GridLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:text="Fname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toEndOf="#+id/imageView"
android:layout_marginTop="12dp"
android:id="#+id/textView2" />
<ImageView
android:layout_height="80dp"
android:id="#+id/imageView"
android:layout_width="80dp"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true" />
<TextView
android:text="Lname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:id="#+id/Lname"
android:layout_below="#+id/textView2"
android:layout_toEndOf="#+id/imageView" />
<TextView
android:text="Fname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toEndOf="#+id/imageView"
android:layout_marginTop="12dp"
android:id="#+id/textView3" />
<GridLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textView2"
android:layout_centerHorizontal="true">
<Button
android:layout_width="20dp"
android:layout_height="15dp"
android:id="#+id/btnBeckPic"
android:background="#drawable/btnbeck"
android:layout_marginStart="30dp"
android:layout_alignBottom="#+id/Lname"
android:layout_toEndOf="#+id/textView2" />
<Button
android:background="#drawable/btnnext"
android:layout_width="20dp"
android:layout_height="15dp"
android:id="#+id/btnNextPic"
android:layout_below="#+id/imageView"
android:layout_toEndOf="#+id/btnBeckPic"
android:layout_marginStart="14dp" />
</GridLayout>
</RelativeLayout>
int currentImage = 0;
String[] strArr = new String[array_image.size()];
strArr = array_image.toArray(stockArr);
#Override
public void onClick(View v) {
if (btnNext == v) {
currentImage++;
currentImage = currentImage % strArr .length;
iv.setImageResource(strArr .length[currentImage]);
} else if (btnBack == v) {
currentImage--;
currentImage = (currentImage + strArr .length) % strArr .length;
iv.setImageResource(strArr[currentImage]);
}
}
Im trying to create a dice rolling tool as part of a larger application. However if i try to roll more than 1 dice in my dice roll function the application crashes. Howver as im new to Java i cant seem to find the cause of the index out of bounds error.
DiceActvity.Java
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.RadioButton;
import java.util.ArrayList;
import java.util.List;
public class DiceActivity extends AppCompatActivity
{
ListView LVDiceList;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dice);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//Radio button
final RadioButton rbGreater = (RadioButton) findViewById(R.id.greaterThanRadioB);
final RadioButton rbLess = (RadioButton) findViewById(R.id.lessThanRadioB);
//Edit boxes
final EditText txtDiceType = (EditText) findViewById(R.id.diceTypeEdTxt);
final EditText txtNumberDice = (EditText) findViewById(R.id.numDiceEdTxt);
final EditText txtFilterNum = (EditText) findViewById(R.id.filterNumEdTxt);
//Buttons
Button btnRoll = (Button) findViewById(R.id.rollButton);
Button btnDiscard = (Button) findViewById(R.id.discardButton);
//Display Array
final List<Integer> diceList = new ArrayList<Integer>(10);
//Array Adapter
final ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(this, android.R.layout.simple_spinner_item, diceList);
//Set adapter
LVDiceList = (ListView) findViewById(R.id.diceResultListV);
LVDiceList.setAdapter(adapter);
//Roll the dice
btnRoll.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
//Hide soft keyboard
Utils.hideKeyboard(DiceActivity.this);
//Validation of fields
//If both fields >0
if (Integer.valueOf(txtDiceType.getText().toString()) > 0 && Integer.valueOf(txtNumberDice.getText().toString()) > 0)
{
int number = Integer.valueOf(txtNumberDice.getText().toString());
int sides = Integer.valueOf(txtDiceType.getText().toString());
//Populate array
for (int i=0;i <number; i++)
{
diceList.add(i, rollDice(sides,number).get(i));
}
//Update the list view
adapter.notifyDataSetChanged();
}
return;
}
});
//Clear the list of results
btnDiscard.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
diceList.clear();
adapter.notifyDataSetChanged();
}
});
//Radio Button Validation
rbGreater.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
if(rbGreater.isChecked() == true)
{
rbLess.setChecked(false);
}
}
});
rbLess.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
if(rbLess.isChecked() == true)
{
rbGreater.setChecked(false);
};
}
});
}
//Returns a list of rolled dice results
private List<Integer> rollDice(int chance, int amount)
{
final List<Integer> rollArray = new ArrayList<Integer>(amount);
int result;
//Gives a random number between 1 and X,Y number of times
{
//BASE Equation||Min + (int)(Math.random() * ((Max - Min) + 1))
//1 = minimum roll
result = 1 + (int) (Math.random() * ((chance - 1) + 1));
rollArray.add(result);
}
return rollArray;
}
}
content_dice.xml
<?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="fill_parent"
android:layout_height="fill_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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="garethgriffiths.tabletopcompanion.DiceActivity"
tools:showIn="#layout/activity_dice">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="#string/textView_NumDice"
android:id="#+id/numDiceTextV"
android:layout_alignBottom="#+id/numDiceEdTxt"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:textSize="25dp"
android:textStyle="bold"
android:textAlignment="gravity"/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="number"
android:ems="4"
android:id="#+id/numDiceEdTxt"
android:maxLength="3"
android:text="#string/edText_NumDice"
android:gravity="right"
android:selectAllOnFocus="true"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/numDiceTextV"
android:layout_toEndOf="#+id/numDiceTextV"
android:numeric="integer"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="#string/textView_DiceType"
android:id="#+id/diceTypeTextV"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="#+id/numDiceTextV"
android:layout_alignBottom="#+id/diceTypeEdTxt"
android:layout_toLeftOf="#+id/diceTypeEdTxt"
android:layout_toStartOf="#+id/diceTypeEdTxt"
android:textSize="25dp"
android:textStyle="bold"
android:textAlignment="gravity"/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="number"
android:ems="4"
android:id="#+id/diceTypeEdTxt"
android:maxLength="2"
android:text="#string/edText_DiceType"
android:layout_below="#+id/numDiceEdTxt"
android:layout_alignLeft="#+id/numDiceEdTxt"
android:layout_alignStart="#+id/numDiceEdTxt"
android:gravity="right"
android:selectAllOnFocus="true"
android:numeric="integer"/>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/radioB_LessThan"
android:id="#+id/lessThanRadioB"
android:layout_above="#+id/discardButton"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginBottom="36dp"/>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/radioB_GreaterThan"
android:id="#+id/greaterThanRadioB"
android:layout_alignTop="#+id/lessThanRadioB"
android:layout_toRightOf="#+id/lessThanRadioB"
android:layout_toEndOf="#+id/lessThanRadioB"/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="number"
android:ems="4"
android:maxLength="3"
android:id="#+id/filterNumEdTxt"
android:layout_alignTop="#+id/greaterThanRadioB"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:text="#string/edText_NumFilter"
android:gravity="center"
android:selectAllOnFocus="true"
android:numeric="integer"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_Discard"
android:id="#+id/discardButton"
android:layout_alignTop="#+id/rollButton"
android:layout_toLeftOf="#+id/rollButton"
android:layout_toStartOf="#+id/rollButton"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_Roll"
android:id="#+id/rollButton"
android:layout_marginTop="108dp"
android:layout_below="#+id/diceTypeTextV"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"/>
<ListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/diceResultListV"
android:scrollIndicators="right"
android:visibility="visible"
android:layout_below="#+id/discardButton"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"/>
</RelativeLayout>
Heres a small Class used to hide softkeyboard thats called in DiceActivity
import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
/**
* http://stackoverflow.com/questions/1109022/close-hide-the-android-soft-keyboard
* Used to close soft keyboard
*/
public class Utils
{
public static void hideKeyboard(Activity activity)
{
// Check if no view has focus:
View view = activity.getCurrentFocus();
if (view != null)
{
InputMethodManager inputManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
}
Your method private List<Integer> rollDice(int chance, int amount) returns a list of Integer. And according to your comment inside the method it should have multiple numbers in it.
But this method always returns only one number.
Now you invoke this method here:
for (int i=0;i <number; i++)
{
diceList.add(i, rollDice(sides,number).get(i));
}
You are invoking this method in a loop. Storing the results in a NEW list.
You get an exception because in the second loop get(i) is 1 and there is only 1 entry in this list on index 0.
To correct this is should read: .get(0)
Also this kind of implementation is very messy. Please take a paper and a pencil to figure it out.
I have a textview timer, i want it stops after 10 seconds of showing on display and after 10 seconds that my current activity jumps to an other activity
Runnable runnable = new Runnable()
{
#Override
public void run()
{
while(Running)
{
try{
Thread.sleep(1000);
}catch(InterruptedException e)
{
e.printStackTrace();
}
handler.post(new Runnable()
{
#Override
public void run()
{
number+=1;
tvTimer.setText(String.valueOf(number)); //With setting value of number on textfield ITS POSSIBLE TO SEE THE TIMER
if(number==10)
{
Running = false;
handler.removeCallbacks(this);//that does not works for me to stop
Intent i = new Intent(getApplicationContext(), SonucMenu.class);
startActivity(i); //Starting my second class
}
}
});
}
}
My Second activity starts but the layout from second activity comes more than one time, what i want is that it comes only one time, and i think this problem depends on that i cant stop runnable
Here My Complete original Code
MainActivity.class
package com.marburg.leftright;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import com.marburg.leftright.R;
import android.support.v7.app.ActionBarActivity;
import android.app.Activity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
static Random rnd=new Random();
static int rndN = rnd.nextInt(2);
TextView inf,tvSc, tvTimer;
Button btnL, btnR;
int ScoreRhtg = 0;
int ScoreFls = 0;
String right = "RIGHT";
String left = "LEFT";
private int number;
private Handler handler;
private boolean Running = true;
MediaPlayer mySound;
public void sendData()
{
String rData = Integer.toString(ScoreRhtg); //Score Of Right Answer Data setting
String wData = Integer.toString(ScoreFls);
Intent i = new Intent(getApplicationContext(), SonucMenu.class);
i.putExtra("DATA", rData);
i.putExtra("DATA2", wData);
startActivity(i);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.lr);
Intent intent = getIntent(); //Get Intent from SonucMenu.class to turn back MainActivity.java from New Button (This Class)
inf = (TextView)findViewById(R.id.tvInfo);
btnL = (Button)findViewById(R.id.btnL);
btnR = (Button)findViewById(R.id.btnR);
tvSc = (TextView)findViewById(R.id.tvScore);
//Set text left or right according new random number
if(rndN==1){
inf.setText(right);
}
else
{
inf.setText(left);
}
//Set 0 for Left
btnL.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{ //Set 0 for Left
if(rndN==0)
{
ScoreRhtg++;
tvSc.setText(ScoreRhtg+" Right");
rndN=rnd.nextInt(2); //Renew the random number
}
else
{
ScoreFls++;
tvSc.setText(ScoreFls+" False");
rndN=rnd.nextInt(2); //Renew the random number
}
//Set text left or right according new random number
if(rndN==1){
inf.setText(right);
}
else
{
inf.setText(left);
}
}
});
//Set 1 For Right
btnR.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if(rndN==1)
{
ScoreRhtg++;
tvSc.setText(ScoreRhtg+" Right");
rndN=rnd.nextInt(2); //Renew the random number
}
else
{
ScoreFls++;
tvSc.setText(ScoreFls+" False");
rndN=rnd.nextInt(2); //Renew the random number
}
//Set text left or right according a new random number
if(rndN==1){
inf.setText(right);
}
else
{
inf.setText(left);
}
}
});
//FOR TIMER RESPONSIBLE PART OF CODE
tvTimer = (TextView)findViewById(R.id.tvTimer);
handler = new Handler();
Runnable runnable = new Runnable()
{
#Override
public void run()
{
while(Running)
{
try{
Thread.sleep(1000);
}catch(InterruptedException e)
{
e.printStackTrace();
}
handler.post(new Runnable()
{
#Override
public void run()
{
number+=1;
tvTimer.setText(String.valueOf(number)); //With setting value of number on textfield ITS POSSIBLE TO SEE THE TIMER
if(number==9)
{
mySound=MediaPlayer.create(MainActivity.this, R.raw.click);
mySound.start();
Running = false;
handler.removeCallbacks(this);//Doesnt works for me
sendData(); //sendData function startActivity(i) included
}
}
});
}
}
};
new Thread(runnable).start();
//END OF FOR TIMER RESPONSIBLE PART OF CODE
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
And my Second Class SonucMenu.java
package com.example.timerdeneme2;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class SonucMenu extends MainActivity {
public TextView tvCorr, tvWro;
public Button btnNew, btnCls;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.sonuc_menu);
Intent i = getIntent();
Bundle dataBundle = i.getExtras();
String dataRString = dataBundle.getString("DATA");
String dataWString = dataBundle.getString("DATA2");
TextView tv = (TextView)findViewById(R.id.tvCorr);
TextView tvW = (TextView)findViewById(R.id.tvWro);
tv.setText(dataRString);
tvW.setText(dataWString);
btnNew = (Button)findViewById(R.id.btnNew);
btnNew.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Toast.makeText(getApplicationContext(), "this is my Toast message!!! =)",
Toast.LENGTH_LONG).show();
Intent myIntent = new Intent(SonucMenu.this, MainActivity.class);
//myIntent.putExtra("key", value); //Optional parameters
SonucMenu.this.startActivity(myIntent);
}
});
btnCls=(Button)findViewById(R.id.btnEx);
btnCls.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(1);
}
});
}
}
And XML Layouts lr.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginTop="10dp"
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.marburg.leftright.MainActivity" >
<TextView
android:id="#+id/tvResCorr"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TableLayout
android:id="#+id/tableLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/tvResCorr"
android:layout_marginTop="14dp"
android:layout_toRightOf="#+id/tvResCorr" >
<TableRow
android:id="#+id/tableRow1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<Button
android:id="#+id/btnL"
android:layout_width="100dp"
android:layout_height="100dp"
android:text="L"
android:textSize="70dp" />
<Button
android:id="#+id/btnR"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginLeft="50dp"
android:text="R"
android:textSize="70dp" />
</TableRow>
<TableRow
android:id="#+id/tableRow2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</TableRow>
<TableRow
android:id="#+id/tableRow3"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</TableRow>
</TableLayout>
<TextView
android:id="#+id/tvInfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/tableLayout1"
android:layout_alignRight="#+id/tableLayout1"
android:layout_below="#+id/tableLayout1"
android:layout_marginLeft="10dp"
android:layout_marginTop="200dp"
android:gravity="center"
android:text="Info"
android:textSize="24dp" />
<TextView
android:id="#+id/tvScore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/tableLayout1"
android:layout_alignRight="#+id/tableLayout1"
android:layout_below="#+id/tvInfo"
android:layout_marginLeft="10dp"
android:layout_marginTop="20dp"
android:gravity="center"
android:text="Score"
android:textSize="24dp" />
<TextView
android:id="#+id/tvTimer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/tableLayout1"
android:layout_centerHorizontal="true"
android:text="Time" />
</RelativeLayout>
And sonuc_menu.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
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.marburg.leftright.MainActivity" >
<TableLayout
android:id="#+id/tableLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginTop="36dp" >
<TableRow
android:id="#+id/tableRow1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/tvResCorr"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Correctness:" />
<TextView
android:id="#+id/tvCorr"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20sp"
android:text="X" />
</TableRow>
<TableRow
android:id="#+id/tableRow2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/tvResWro"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Wrongness" />
<TextView
android:id="#+id/tvWro"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20sp"
android:text="X" />
</TableRow>
</TableLayout>
<TableLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/tableLayout1"
android:layout_below="#+id/tableLayout1"
android:layout_marginTop="113dp" >
<TableRow
android:id="#+id/tableRow3"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<Button
android:id="#+id/btnNew"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:text="NEW" />
</TableRow>
<TableRow
android:id="#+id/tableRow4"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BEST SCORES" />
</TableRow>
<TableRow
android:id="#+id/tableRow5"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</TableRow>
<Button
android:id="#+id/btnEx"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:text="EXIT" />
<TableRow
android:id="#+id/tableRow6"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</TableRow>
</TableLayout>
</RelativeLayout>
I think for this you can use following code , It worked for me.
It will start your activity after 10 seconds.
new Handler().postDelay(new Runnable() {
#Override
public void run() {
Start Your activity here.
}
}, 10000);
but one of the best solution will be (I just found it from develoer site):
new CountDownTimer(10000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
strat your activity here.
}
}.start();
Use View.post(Runnable) and View.postDelayed(Runnable, long), no need to create additional thread.
private TextView tvTimer;
private final Runnable mCountDownRunnable = new Runnable() {
private int mCount = 0;
#Override
public void run() {
mCount++;
if (mCount < 10) {
tvTimer.setText(Integer.toString(mCount));
tvTimer.postDelayed(this, 1000);
} else {
Intent i = new Intent(YourActivity.this, SonucMenu.class);
YourActivity.this.startActivity(i);
}
}
};
to start runnable, call tvTimer.post(mCountDownRunnable);