Need some help debugging my code. I am very new to the Android SDK and am working on learning it. From what I can glean from several posts on SO and other google search results... I formulated this code.
public class MainMenu extends Activity {
private int str = 8, dex = 8, inte = 8, luk = 8, stats = 20;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().setDisplayShowHomeEnabled(false);
getActionBar().setDisplayShowTitleEnabled(false);
setContentView(R.layout.activity_main_menu);
}
As you can see, I have created a few private variables my app is going to use to store data. In order to interact with these values, I will redraw the TextView each time they are modified. *Feel free to correct me here if this is not an ideal strategy.
public void strup(View view) {
if(stats > 0) {
TextView tv = (TextView)findViewById(R.id.textView4);
TextView st = (TextView)findViewById(R.id.textView18);
str++;
stats--;
tv.setText(str);
st.setText(stats);
} else {
Toast.makeText(this, "Out of stats!", Toast.LENGTH_SHORT).show();
}
I use a button with the following format.
Str [X] [+1]
Where Str [X] is TextView with X a dynamic value.
Also where [+1] is a button with an Onclick function preset by the XML file.
<TextView
android:id="#+id/textView9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Str [" />
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="8" />
<TextView
android:id="#+id/textView13"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="]" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="strup"
android:text="+1" />
Now for simplicity, I have altered the "android:text="" " lines to reflect their actual values instead of linking to #string/... I don't think this makes of much difference but I wanted to acknowledge it.
So my question is why does my Application crash when I click the "+1" button? All my app is trying to do is to redraw the TextView with a higher value (under str) and a lower value (under stats).
Thanks for any and all help!
You are passing integer value in settext. Either cast integer to string or you can try changing settext like this:
tv.setText(""+str);
st.setText(""+stats);
You tried to create this object:
TextView st = (TextView)findViewById(R.id.textView18);
where is textView18 in the xml?
u can caste using toString method like this:
tv.setText(str.toString());
st.setText(stats.toString());
Try this change the position of your setContentView(R.layout.activity_main_menu);
public class MainMenu extends Activity {
private int str = 8, dex = 8, inte = 8, luk = 8, stats = 20;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_menu);
getActionBar().setDisplayShowHomeEnabled(false);
getActionBar().setDisplayShowTitleEnabled(false);
}
Related
I'm using Android Studio and trying to show some chosen Street View paths in VR. I already have Street View running well and now I'm trying to show it in VR.
I have put the com.google.vr.sdk.widgets.pano.VrPanoramaView in the layout and, inside onCreate in my class, referenced it to a VrPanoramaView variable through findViewById. Now I'm trying to show an image calling a method which I've defined in this class, loadPanoImage. This method loads an image from the storage and shows it through loadImageFromBitmap.
The problem is that it isn't able to show anything, even though I've followed a guide and I've done everything as showed. I've even tryed calling it in different parts of the code (before doing any other action, on clicking a button, before and after showing streetview) but I can't understand why it isn't working and how will I be able to use it to show images taken from StreetView (I don't know if I will be able to do it dinamically or I should download them and put them in the storage).
I'm putting part of the code for reference:
public class VrExperience extends FragmentActivity {
Button buttonCitta;
Button buttonMare;
Button buttonMontagna;
TextView titleTextView;
// George St, Sydney
private static final LatLng SYDNEY = new LatLng(-33.87365, 151.20689);
// LatLng with no panorama
private static final LatLng INVALID = new LatLng(-45.125783, 151.276417);
//VrPanoramaView is inserted in the layout
private VrPanoramaView panoWidgetView;
//StreetViewPanorama is another class in my project which shows Street View
private StreetViewPanorama mStreetViewPanorama;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_vrexperiences);
panoWidgetView = (VrPanoramaView) findViewById(R.id.pano_view);
panoWidgetView.setEventListener(new VrPanoramaEventListener());
//download image and show it, but it doesn't show anything
loadPanoImage();
titleTextView = (TextView) findViewById(R.id.titleTextView);
buttonCitta = (Button) findViewById(R.id.buttonCitta);
buttonCitta.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!checkReady()) {
return;
}
titleTextView.setVisibility(View.GONE);
buttonCitta.setVisibility(View.GONE);
buttonMare.setVisibility(View.GONE);
buttonMontagna.setVisibility(View.GONE);
loadPanoImage(); //it doesn't show anything
mStreetViewPanorama.setPosition(SYDNEY);
loadPanoImage(); //it doesn't show anything
}
}};
//code for buttonMontagna and buttonMare as well, it's identical
SupportStreetViewPanoramaFragment streetViewPanoramaFragment =
(SupportStreetViewPanoramaFragment)
getSupportFragmentManager().findFragmentById(R.id.streetviewpanorama);
streetViewPanoramaFragment.getStreetViewPanoramaAsync(
new OnStreetViewPanoramaReadyCallback() {
#Override
public void onStreetViewPanoramaReady(StreetViewPanorama panorama) {
mStreetViewPanorama = panorama;
// Only set the panorama to INVALID on startup (when no panoramas have been
// loaded which is when the savedInstanceState is null).
if (savedInstanceState == null) {
mStreetViewPanorama.setPosition(INVALID);
}
}
});
}
/**
* When the panorama is not ready the PanoramaView cannot be used. This should be called on
* all entry points that call methods on the Panorama API.
*/
private boolean checkReady() {
if (mStreetViewPanorama == null)
return false;
return true;
}
/**
* Called when the Animate To Invalid button is clicked.
*/
public void onGoToInvalid(View view) {
if (!checkReady()) {
return;
}
mStreetViewPanorama.setPosition(INVALID);
}
//retrieves image from the assets folder and loads it into the VrPanoramaView
private void loadPanoImage() {
VrPanoramaView.Options options = new VrPanoramaView.Options();
InputStream inputStream = null;
AssetManager assetManager = getAssets();
try {
inputStream = assetManager.open("demo2.jpg");
options.inputType = VrPanoramaView.Options.TYPE_MONO;
panoWidgetView.loadImageFromBitmap(
BitmapFactory.decodeStream(inputStream), options
);
inputStream.close();
} catch (IOException e) {
Log.e("Fail", "Exception in loadPanoImage" + e.getMessage());
}
}
#Override
protected void onPause() {
panoWidgetView.pauseRendering();
super.onPause();
}
#Override
protected void onResume() {
super.onResume();
panoWidgetView.resumeRendering();
}
#Override
protected void onDestroy() {
panoWidgetView.shutdown();
super.onDestroy();
}
}
This is my layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/vrExperienceActivity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.vr.sdk.widgets.pano.VrPanoramaView
android:id="#+id/pano_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:layout_weight="5"
android:scrollbars="none" />
<TextView
android:id="#+id/titleTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/white"
android:text="VR Experience"
android:textAlignment="center"
android:textAppearance="#android:style/TextAppearance.Large"
android:textColor="#0000F0"
android:visibility="visible" />
<Button
android:id="#+id/buttonCitta"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Città " />
<fragment
class="com.google.android.gms.maps.SupportStreetViewPanoramaFragment"
android:id="#+id/streetviewpanorama"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
EDIT: #LucioB
a) those are the places I've tried to call loadPanoImage, but neither of them showed anything. It acts as nothing happens calling that method, the program keeps going to the other tasks. I'd like for images to be shown directly in VR when a button is clicked, or if that isn't possible to add the classic cardboard button in Street View mode to pass to VR view.
b) I mean the code isn't doing what I expected it to do. I thought that once I created VrPanoramaView in the layout and used it to show an image through .loadImageFromBitmap it would have shown the image I loaded from asset (I have an image saved on the virtual SD), and that once I was able to do that for a single image I would have found a way to do it for a whole path.
The code doesn't give any exception, I think I'm making a logic mistake or I didn't understand how VR api work.
EDIT: I've found that the java code is working, the problem was in the layout which didn't permit to see VrPanoramaView because it was obscured by StreetViewPanorama
I have an EditText and when I set it to Empty and Click on my Button, my App crashes.
When I view it in Android Monitor it points to the line:
final int addTm = Integer.parseInt(Teaching);
Here is my code:
LinearLayout
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="2dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:text="" />
<EditText
android:id="#+id/tM"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="24dp"
android:layout_marginRight="50dp"
android:ems="1"
android:inputType="number"
android:maxLength="1"
android:text="0" />
<Button
android:id="#+id/submitBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Submit" />
</LinearLayout>
And my Java Code:
Submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String Teaching = Tm.getText().toString();
final int addTm = Integer.parseInt(Teaching);
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("sub").child("TM");
myRef.runTransaction(new Transaction.Handler() {
#Override
public Transaction.Result doTransaction(MutableData mutableData) {
Integer currentValue = mutableData.getValue(Integer.class);
if (currentValue == null) {
mutableData.setValue(0);
} else {
mutableData.setValue(currentValue + addTm);
}
return Transaction.success(mutableData);
}
#Override
public void onComplete(DatabaseError databaseError, boolean committed, DataSnapshot dataSnapshot) {
System.out.println("Transaction completed");
}
});
}
});
The other answers are good, but I'd recommend wrapping with a try/catch for the NumberFormatException. I know you have the input set to accept numbers only, but always better safe than sorry.
Lowercase the String variable Teaching. In Java we only upper case Type names. (classes, interfaces, etc.) Notice how StackOverflow is highlighting the variable Teaching blue, a bit disorienting no?
Do this for your member fields as well Tm and Submit. They should be written tm and submit. Also, Tm is not a very descriptive name for a variable either. Imagine another programmer coming in and looking at your code, and wondering what a tm is. What is the context of this tm, where does it come from... what does it do? Is it a Teenage Mutant?
Regardless when using Integer.parseInt wrap it in a try/catch:
#Override
public void onClick(View view){
final int addTm;
try {
String teaching = Tm.getText().toString();
addTm = Integer.parseInt(teaching);
} catch (NumberFormatException e) {
addTm = 0;
}
// ...
}
Why should you do this? What if I enter a decimal number into your number input?
Using your accepted answer you will still crash. Integer.parseInt does not parse decimal numbers.
Or how about, if I switch the locale of the device and enter a number with odd characters that Integer.parseInt won't expect.
Gotta catch that exception to be full proof.
When executing Integer.parseInt() on an empty string it throws an NumberFormatException.
First, check the value of Teaching, and verify it's not empty string, or - try/catch for NumberFormatException, and set the value you want for Teaching in that case.
I want to have a multiline text view and adding text to it,
After adding five lines to the TextView I want to start to add to the beginning of the text view.
For example: (numbers as text), 1,2,3,4,5 -> 6,2,3,4,5 -> 6,7,3,4,5 and so on.
I thought about using StringBuilder but I don't see an efficient way to implement this.
The delimiter of each row is "\n\n" maybe it will help to solve the problem.
Or maybe should I just do 5 textView's and have some switch case between them?
Button xml:
<TextView
android:id="#+id/searchesInputTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollHorizontally="false"
android:width="300dp"
android:height="200dp"
android:background="#drawable/border_style"
android:maxLines="5"
android:layout_marginTop="24dp"
/>
in MainActivity.java:
public class MainActivity extends AppCompatActivity {
private TextView searchesTextView;
private ImageButton refreshCurrentLocationButton;
private String myText = "";
refreshCurrentLocationButton = (ImageButton) findViewById(R.id.currentLocationRefreshImageButton);
searchesTextView = (TextView) findViewById(R.id.searchesInputTextView);
refreshCurrentLocationButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Actual code
myText += location.ToString() + "\n\n";
searchesTextView.setText(myText);
});
}
I am creating a times tables app, in which one of the activities allows the user to enter which times tables they would like to view, then the app will bring up that times tables.(e.g. 6x5=30) etc.
Below is the xml layout I have created for the activity:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="15dp">
<TextView
android:id="#+id/tvTop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="I want to see the: "
android:textSize="25dp" />
<EditText
android:id="#+id/etEnterNumber"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Enter Number..."
>
</EditText>
<TextView
android:id="#+id/tvBottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Times tables!"
android:textSize="25dp" />
<Button
android:id="#+id/btnGo"
android:layout_width="50dp"
android:layout_height="50dp"
android:text="Go"
android:layout_gravity="center"/>r
</LinearLayout>
And this it the java class I have created thus far for the classes functionalitiy:
public class ViewTimesTables extends Activity implements View.OnClickListener {
// Declaring Vars
Button go;
EditText enterNumber;
TextView top;
TextView bottom;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setting equal to text layout View
setContentView(R.layout.view);
// calling method to intialise vars
initialiseVars();
}// on create end
/**
* method to initialise all of the buttons, textviews etc used to clean up
* the onCreate.
*/
private void initialiseVars() {
// Setting up (initialising) all the buttons text views etc from the xml
// (vid 25)
go = (Button) findViewById(R.id.btnGo);
enterNumber = (EditText) findViewById(R.id.etEnterNumber);
top = (TextView) findViewById(R.id.tvTop);
bottom = (TextView) findViewById(R.id.tvBottom);
}
/**
* Method with on click listener that adds functionality for all of the
* buttons, text views etc
*
* #param v
*/
public void onClick(View view) {
// switch statement which determines what is clicked
switch ((view).getId()) {
case R.id.etEnterNumber:
// code to read user number (i.e. between 1 and 12)
//And possibly link to go button
break;
case R.id.btnGo:
// code to bring up new activity/screen with times table
// of the number that was entered in edit text
break;
}
}
}
I am unsure how to add the correct functionality (probably within switch statement) so that when e.g. "6" is entered in the edit text box and the "go" button is pressed then the 6 times tables will be brought up in a new activity?
I would begin by looking at Intents to start a new activity and pass data to it.
A relevant tutorial is this Android Intents Tutorial
Getting the text from a edit text is a simple as enterNumber.getText().getString()
You could then use a conditional statement to call the designated class.
Something like this would allow you to pass two values to the SixTimesTables class with the values 5 and 6 passed in.
if(enterNumber.getText().getString().equals("6")){
Intent i = new Intent(this, SixTimesTables.class);
i.putExtra("Value1", 5);
i.putExtra("Value2", 6);
// set the request code to any code you like,
// you can identify the callback via this code
startActivityForResult(i, REQUEST_CODE);
}
You probably want a dynamic layout for next activity.
It may help you.
http://www.dreamincode.net/forums/topic/130521-android-part-iii-dynamic-layouts/
Then you can switch between activities as AndyGable mentioned.
Hopefully it'll help you.
You really dont need the onClick for the editText you can handle if data is entered in the editText or not from the button click only like this:
public void onClick(View view) {
// switch statement which determines what is clicked
switch ((view).getId()) {
case R.id.btnGo:
// code to bring up new activity/screen with times table
// of the number that was entered in edit text
// check if editText has values or not
if(TextUtils.isEmpty(mEditText.getText().toString())) {
mEditText.setError("Please enter a number");
}else {
int number = Integer.parseInt(mEditText.getText().toString());
Intent intent = new Intent(YourCurrentActivity.this, NextActivity.class);
intent.putExtra("value", number);
startActivity(intent);
// it is always good to check if the value entered is a number only or not
// add inputType tag in the xml
// android:inputType="number" for the editText.
}
break;
}
}
Now, in order to get value in the next activity do this:
// write this inside the onCreate of the Activity.
int number;
if(getIntent().getExtras() != null) {
number = getIntent().getIntExtra("value");
}
// use the number then to display the tables
I create simple Android app (https://www.linux.com/learn/docs/683628-android-programming-for-beginners-part-1) with latest Android Studio. Code:
public class test_act extends Activity {
private static final int MILLIS_PER_SECOND = 1000;
private static final int SECONDS_TO_COUNTDOWN = 30;
private android.widget.TextView countdownDisplay;
private android.os.CountDownTimer timer;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.full_act);
countdownDisplay = (android.widget.TextView) findViewById(R.id.time_display_box);
android.widget.Button startButton = (android.widget.Button) findViewById(R.id.startbutton);
startButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
try {
showTimer(SECONDS_TO_COUNTDOWN * MILLIS_PER_SECOND);
} catch (NumberFormatException e) {
// method ignores invalid (non-integer) input and waits
// for something it can use
}
}
});
}
private void showTimer(int countdownMillis) {
if(timer != null) { timer.cancel(); }
timer = new android.os.CountDownTimer(countdownMillis, MILLIS_PER_SECOND) {
#Override
public void onTick(long millisUntilFinished) {
countdownDisplay.setText("counting down: " +
millisUntilFinished / MILLIS_PER_SECOND);
}
#Override
public void onFinish() {
countdownDisplay.setText("KABOOM!");
}
}.start();
}
}
My 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" >
<TextView
android:id="#+id/time_display_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="60dp"
android:text="#string/_00_30"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<Button
android:id="#+id/startbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/time_display_box"
android:layout_centerHorizontal="true"
android:layout_marginTop="41dp"
android:text="#string/start" />
</RelativeLayout>
In emulator it's good working. But on my Galaxy S2 with CyanogenMod10.1(Android 4.2.2) app wrong updating TextView. Screenshot:
How I can resolve this problem?
upd: after screen rotate TextView is updating once.
You might want to try invalidating your layout every time it is updated. I am guessing with how often the text is being updated the phone is not having enough time to redraw the layout. This would also explain why it works when you rotate your phone, because then the layout is forced to update.
countdownDisplay.invalidate();
Let me know if that does not work.
It commonly happens when you put UI updates inside try blocks, try to avoid it or wrap with runOnUiThread.
EDIT:
Another reason - you update it to fast - you code does 1000 updates per second i dont think it can handle it.