Using XML along with Activity's setContentView() - java

I'm an amateur developer creating a short app and I'm having trouble using both the XML file for a particular activity along with Activity's Java method "setContentView". I need the method because I am generating numbers from a computation and the number generated is variable depending on different parameters. Therefore, each time I call the computation I have to call:
textView.setText(message + " is " + output);
setContentView(textView);
But I also created several buttons on the Activity's XML page which I would also like to show up on the Activity's page. For example, this is one of the buttons I created:
<Button
android:layout_marginTop="100dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_quit"
android:onClick=".quit" />
However, if I call:
setContentView(R.layout.activity_compute_number);
after the set content view for the variable text message I mentioned earlier, the XML file overrides the text message and the text message never shows up and vice versa if I call the two setContentView methods the other way around. How do I get them both to render on the Activity screen simultaneously?

In your activity_compute_number.xml, you should assign an id to your button and textview. This way you can reference your button and textView.
<Button
android:id="#+id/button_compute"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:onClick=".quit"
android:text="#string/button_quit" />
<TextView
android:id="#+id/textView_answer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp" />
Notice the android:id="#+id/button_compute" and android:id="#+id/textView_answer". This gives this button and textview id's called button_compute and textView_answer respectively.
Then change your onCreate to the following:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnCompute = (Button)findViewById(R.id.button_compute);
TextView tvAnswer = (TextView)findViewById(R.id.textView_answer);
btnCompute.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/*
* DO COMPUTATION here
*/
tvAnswer.setText(answer);
}
});
}
In onCreate() method you set your view to show the layout in your activity_compute_number.xml by calling setContentView() only once. You reference your button and textview by findViewById specifying the id's you have set in your xml.

Please read the docs of the method setContentView(). In onCreate() method you can use setContentView() once only. So, you should add a TestView in your XML file OR can use this,TextView txt = new TextView(this) in your activity.

Related

How to add Strings to a TextView / ScrollView?

I am quiet new to android developing sorry!
I want to add doctor values as Strings (first name, last name, and some others later) as one entry (I was trying to do so with Objects) to my Scroll View via a button. I know that I need a Layout and a Text View to do so but my Virtual Machine crushes.
As far as I understand I have to put my Text View (with the Strings) in the Layout and the Layout in the Scroll View (am I wrong?).
I was trying several things from different websites which all provide similar solutions but nothing worked so far. I am using Android 6.0 with android studio and designed my UI with the Design View and adapted some code in the XML files.
public void addDoctor(View view) {
setContentView(R.layout.activity_main);
// standard java class Doctor
Doctor doc = new Doctor("Foo", "Boo");
// this is the ScrollView I generated with the design
ScrollView sv = (ScrollView) this.findViewById(R.id.ScrollViewDoctor);
TextView tv = new TextView(this);
// trying to fix the parent problem here
if(tv.getParent() != null) {
((ViewGroup)tv.getParent()).removeView(tv); // <- fix
}
//this should be "Foo"
tv.setText(doc.getDocName());
// this is the layout I generated with the design "linlay"
LinearLayout ll = (LinearLayout) this.findViewById(R.id.linlay);
sv.addView(ll);
//only one child object! -> in the error log
ll.addView(tv);
setContentView(view);
}
I expected the Strings of the object to appear in the Scroll View but the error log says that "ScrollView can host only one direct child" which I was trying to fix with the if statement but it does not seem to affect my code.
Can you please help me with this. Do I miss something?
Thank you!
As far as I understand I have to put my Text View (with the Strings) in the Layout and the Layout in the Scroll View (am I wrong?).
You've right.
<ScrollView>
<LinearLayout>
<TextView></TextView>
</LinearLayout>
</ScrollView>
How to Add a doctor in the right way
error log says that "ScrollView can host only one direct child"
You're getting the error because you added already the linear layout inside the <ScrollView>, so you don't have to call, sv.addView(ll); because it's already inside (And you cannot add multiple layout in standard ScrollView)
So you're reference to ScrollView it's useless.
if you're xml is like this:
<ScrollView>
<LinearLayout>
</LinearLayout>
</ScrollView>
You can achieve your result with this:
public class MyActivityDoctors extends Activity {
ScrollView sv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sv = (ScrollView) this.findViewById(R.id.ScrollViewDoctor);
}
public void addDoctor(Doctor doctor)
{
//Linear Layout inside your ScrollView
LinearLayout ll = (LinearLayout) this.findViewById(R.id.linlay);
//Create a new TextView with doctor data
TextView tv = new TextView(this);
tv.setText(doctor.getDocName());
//Adding textView to LinearLayout
ll.addView(tv);
}
}
remove setContentView(view); on the end, you have already set this layout in first line
setContentView in most cases should be called once, inside onCreate method. if you are calling setContentView multiple times you are basically overrriding previous one
also this
if(tv.getParent() != null) {
((ViewGroup)tv.getParent()).removeView(tv); // <- fix
}
is unnecessary, you are creating new TextView line above, it wont have parent for shure
Why don't you use a RecyclerView? And then you don't need a ScrollView. And don't call setContentView(view); multiples times. You have to do only 1 time.
you need to create Multiline TextView
<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="20dp"
android:fillViewport="true">
<TextView
android:id="#+id/txtquestion"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:background="#drawable/abs__dialog_full_holo_light"
android:lines="20"
android:scrollHorizontally="false"
android:scrollbars="vertical"
android:textSize="15sp" />
</ScrollView>

2 (or more) button views for the same onClick method

I'm a novice android developper and was wondering:
Could I have 2 buttons to be linked into the same, 1 onClick method (which i'll presumably override to accept 2 extra parameter, int btnId and View targetTextView for instance) in order to decide which button is calling the method and then which TextView text to update?
For Example:
btn1 will update the text on text_view_1
and btn2 will update text_view_2.
Except they we will be linked to the same method:
public void generalOnClick(View view, String btnId, String textViewId){...}
<?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">
<TextView
android:id="#+id/one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="One"
android:onClick="btnClick"/>
<TextView
android:id="#+id/two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Two"
android:onClick="btnClick"/>
</LinearLayout>
Button Click Function in your Activity
public void btnClick(View view) {
TextView tv = (TextView)view;
int id = tv.getId();
if(id==R.id.one) {
tv.setText("One Clicked");
} else if(id==R.id.two){
tv.setText("Two Clicked");
}
}
set an tag to button and verify it with onClick method that which buttons click event has been triggered , if it doesn't work then follows following trick,
define an common method for the functionality which you are going to execute on button click, make it as common function.
define independent onclick event for both button and then while calling the common function which created above pass some unique param and verify it.
use following code:
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View.OnClickListener clickListener = new View.OnClickListener() {
public void onClick(View v) {
if(v.getId().Equals(btn1.getId())){
//do your work here
}
else{
//work for 2nd button
}
};
btn1 = (Button)findViewById(R.id.btn_1);
btn2 = (Button)findViewById(R.id.btn_2);
btn1.setOnClickListener(clickListener);
btn2.setOnClickListener(clickListener);
}

How to create two android button using android studio

I am just getting into android apps, and I have yet to find a tutorial that explains in detail of how to do anything.Can someone show me the code on how to create two buttons (sign in and sign up) in android ?
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loginButton=(Button)findViewById(R.id.button);
button.setOnClickListener(LogInListener);
signUpButton=(Button)findViewById(R.id.button2);
button2.setOnClickListener(SignUpListener);
}
private OnClickListener LogInListener=new OnClickListener()
{
public void onClick(View v)
{
}
}
Is this the correct way to implement? thanks
activity_main.xml
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Log In"
android:id="#+id/button"
android:layout_marginTop="61dp"
android:layout_below="#+id/textView3"
android:layout_toStartOf="#+id/button2"
android:layout_toLeftOf="#+id/button2" />
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sign UP"
android:id="#+id/button2"
android:layout_alignTop="#+id/button"
android:layout_alignLeft="#+id/editText2"
android:layout_alignStart="#+id/editText2"
android:layout_marginLeft="48dp"
android:layout_marginStart="48dp" />
EDIT:
Now that you have edited your question, you just need to do one more thing to declare your Buttons as instance variables. Declare them outside of all methods (onCreate) but inside the mainActivity.
PRE EDIT:
I'll show you what your main activity (Java class) and what your layout (XML file) should look like:
Main Activity:
public class MainActivity extends AppCompatActivity {
Button signIn, signUp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
signIn = (Button) findViewById(R.id.'idOfButtonFromXMLLayout');
signUp = (Button) findViewById(R.id.'idOfButtonFromXMLLayout');
//Looking at my XML code, the signIn id would be R.id.signInButton
}
The findViewById method is inherited from the AppCompatActivity class, all activities extend the AppCompatActivity class. Older versions of android just extended the Activity class.
The findViewById method takes an int parameter more specifically an id.
The reason a cast is required is because the findViewById method as you would assume returns a type of View, this is then casted to a button.
XML Layout File:
<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:padding="#dimen/activity_vertical_margin"
tools:context=".MainActivity">
<Button
android:id="#+id/signInButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sign In"
<!-- Complete Layout Details--> />
<Button
android:id="#+id/signUpButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/signUpText"
<!-- Complete Layout Details--> />
</RelativeLayout>
In the code above I have represented the text of the buttons in two ways...
1) Hard-coded string "Sign In"
2) String resource "#string/signUpText
It is good practice to change your hard-coded strings to the latter format.
If you're new at Android Development some things are just confusing. I would create buttons by doing this:
Define Button in your XML File.
Add Listener to your Button.
Don't forget to add id attribute to your Button.
i would do it this way.
LAYOUT XML FILE
<Button
android:id="#+id/buttonOne"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button One" />
<Button
android:id="#+id/buttonTwo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 2" />
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.onClickListener {
private Button buttonOne;
private Button buttonTwo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonOne = (Button) findViewById(R.id.buttonOne); // id located in your xml file
buttonOne.setOnClickListener(this);
buttonTwo = (Button) findViewById(R.id.buttonTwo);
buttonTwo.setOnCliclListener(this);
}
private void onClick(View v){
switch(v.getId()) {
case r.id.buttonOne: {
// action when buttonOne is clicked
break;
}
case r.id.buttonTwo: {
// action when buttonTwo is clicked
break;
}
}
}
To create a button, you have to code in your xml file, or drag it in your Design view which will do that for you
Which will auto-magicly do this for you, with auto generated values.
-to name your button edit android: text
-edit android: id to edit the "key" that connects your button design in xml to java
If you want to use your button for things like onclicklisteners and such, you will need to "import" it into your java code, like so. The android: id ="#/<>value"and findViewById(R.id.) should be the same (though its not in the photos)
Now simply do this again for every button you want and change the values to your needs. Hope I helped.

Setting contentview after button click

When my application starts I want to have a start game button. When the button is pressed I want another activity to be shown.
In XML I Setup the button like this:
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Start"
android:id="#+id/bttnStart"
android:onClick="startGame"
/>
And this is the Java function:
public void startGame(View v ){
setContentView(R.layout.activity_start_menue);
}
My app crashes when I click the button.
Calling setContentView() multiple times is dangerous, and doesn't always work. There can be hierarchy conflicts, and inefficiencies that result from instantiating views multiple times. It's also not that helpful, because you're not in control of the container that the layout expands into.
Here is the proper way to do it.
Android provides a built-in mechanism for view-switching called a ViewFlipper. Instead of calling setContentView() for the layout you want to swap in, you can tell the ViewFlipper object to either showNext() or setDisplayedChild(int).
Here's how you would accomplish that in your main.xml.
<?xml version="1.0" encoding="utf-8"?>
<ViewFlipper xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/viewflipper"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- The ViewFlipper can change through its direct children -->
<!-- Child 0 -->
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Start"
android:id="#+id/bttnStart"
android:onClick="startGame"/>
<!-- Child 1 -->
<LinearLayout
android:id="#+id/activity_start_menu"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Here's the menu!"/>
</LinearLayout>
</ViewFlipper>
Note that the views being flipped through are direct children of the <ViewFlipper> that you are using. FYI, you can have more than just two views.
Now onto the Java code in your `MyActivity'.
public class MyActivity extends Activity {
ViewFlipper viewFlipper;
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
viewFlipper = (ViewFlipper) findViewById(R.id.viewflipper);
}
/**
* Switches to the activity_start_menu LinearLayout
* specified in the ViewFlipper.
*/
public void startGame(View v) {
//First way -- use showNext() & showPrevious()
viewFlipper.showNext();
//Second way -- use setDisplayedChild(int) where int is
// the index of the view starting from 0
//In this case, there are two. 0 is the button,
// and 1 is the menu layout.
viewFlipper.setDisplayedChild(1);
//You can also do fancy animations to switch between views.
// Check out the methods accessible and experiment with them!
}
}
You should end up with something like this:
Start activity
Draft:
onCreate()
setContentView(//layout 1);
Button lButton = (Button) findview....
lButton.setOnClickListener(...)
{
onClick()
{
setContentView(//layout 2);
}
}
To start new activity you should use:
Intent intent = new Intent(this, YourActivity.class);
startActivity(intent);
Or if you wouldn't change activity use for eample viewswitcher to switch layout, fragments etc

android setContentView not working

Not a duplicate: my question is simpler than all of the others.
I've been trying to follow the android hello world tutorial, and I can't get the very first example to work.
This is my code:
package com.example.helloandroid;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class HelloAndroid extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
tv.setText("Hello, Android");
setContentView(tv);
}
}
As you can see, I copied and pasted directly out of the tutorial.
The problem is, that instead of displaying Hello, Android, it displays whatever is in the layout/main.xml file. If that file doesn't exist, it closes without displaying anything.
WHY IS THIS NOT WORKING?
As I've copied this directly from the official docs, I have no idea where to even start trying to debug it. Any pointers or suggestions you can give will be greatly appreciated!
Edit: posting my main.xml as requested
<?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"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, HelloAndroid"
/>
</LinearLayout>
Note that this was created automatically when I started the project, I didn't put it there.
Why do you have two TextViews with the same text? You shouldn't be doing this, if you're only going to use one, then only use one.
You XML is fine as is, but your Activity code needs to change:
public class HelloAndroid extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
Heres an explanation of what you were doing...
You were building a TextView dynamically and setting the ContentView to that TextView is fine, but it was not your original intention. Your original intention or the original intention of the sample was to use the layout file and then set the contentview of that activity to that layout file, not just that textview.
Update
In lieu of what the OP said, he does want to build a TextView instance dynamically and apply it to the screen. If this is the case then you have to...:
public class HelloAndroid extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
tv.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,ViewGroup.LayoutParams.FILL_PARENT));
tv.setText("Hello, Android");
setContentView(tv);
}
}
The only difference here is that the TextView has properties that are defining how it will appear on the screen. You can either user FILL_PARENT or WRAP_CONTENT.
you haven't set the xml file or layout in your application. You are directly calling the view.You need to call your view under layout.
Syntax: setContentView(R.layout.your xml file name);
Regarding the question about logcat, you'll find it in the Debug perspective in Eclipse. It's the log of error messages from system and user code.
Try this: You don't need to do setContentView at end. If you do that, it will override with what you have in XML.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.yourxmlfile);
TextView tv = (TextView)findViewById(R.id.helloText);
tv.setText("Hello, Android");
}
<TextView
android:id="#+id/helloText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, HelloAndroid" />

Categories

Resources