I'm using a child class which extends from main to setup some buttons. I am able to change variables created in main, such as TotalMoney from within child.
The problem is findViewById is giving a nullpointer exception. The code within buildthem() works fine when used in the main class.
I am using setContentView(R.layout.main); from within OnCreate in main. The Child class is instantiated and called from OnResume in main class.
Do I need to setContentView in the child aswell, or pass the content view from the main class somehow?
package com.chewyapps.markettrader;
class child extends main {
void buildthem(){
TotalMoney = TotalMoney + 9999;
Button MenuButton = (Button) findViewById(R.id.Menu);
//etc
}
}
I can't findViewById in Oncreate because the full code will use
for(i=0; i<buttonIDs.length; i++) {
Button b = (Button) findViewById(buttonIDs[i]);
//do other stuff
}
The for loop is needed for other things relating to each button. If I can get the basic example working though I assume the full code will work.
It hadn't occured to me before to mention this, but the child class is in a seperate file called child.java, from my main.java file in onResume I use:
child childObject = new child ();
childObject.buildthem();
Why not put this line:
Button MenuButton = (Button) findViewById(R.id.Menu);
in onCreate(), then you can either pass MenuButton into buildthem() as a parameter or reference it directly, depending on your design.
Please note that Java convention is to have variable names start with a lowercase letter, so menuButton not MenuButton.
EDIT
Then why not create an array of Buttons in onCreate() that you can later iterate through?
Button myButtons[] = new Button[buttonIDs.length];
for(int i=0; i<buttonIDs.length; i++) {
myButtons[i] = (Button) findViewById(buttonIDs[i]);
}
Then just iterate over the myButtons array in your child class.
What about:
Button MenuButton = (Button) this.findViewById(R.id.Menu);
or
Button MenuButton = (Button) Child.this.findViewById(R.id.Menu);
Related
I have a small problem releated to accessing data in other views so here is the code.
Button
Button button2 = FindViewById<Button>(Resource.Id.addExpereince);
Button Click
button2.Click += (sender, e) =>{
EditText addCompany = FindViewById<EditText>(Resource.Id.addCompanyName);
EditText addDate = FindViewById<EditText>(Resource.Id.addDate);
EditText addPosition = FindViewById<EditText>(Resource.Id.addPosition);
AddExpreince(1, addCompany.Text, addPosition.Text, addDate.Text);
SetContentView(Resource.Layout.Main);
};
I want to learn, how I can solve this problem. The button and EditText are on other views, and I actually don't need them to work in the main view, I just need the code to be initialized in the MainActivity so that they can be used in the other view.
The error I'm receiving for better reference:
System.NullReferenceException: Object reference not set to an instance of an object.
System.NullReferenceException: Object reference not set to an instance of an object.
You should use SetContentView() first, as per the document :
Set the activity content from a layout resource. The resource will be inflated, adding all top-level views to the activity.
If you didn't add a layout to your Activity first, your Activity is basically an empty window. As a result, when you use FindViewById method you will get a NullReferenceException exception.
Solution :
Modify your code like this :
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
// Get our button from the layout resource,
// and attach an event to it
Button button2 = FindViewById<Button>(Resource.Id.addExpereince);
EditText addCompany = FindViewById<EditText>(Resource.Id.addCompanyName);
EditText addDate = FindViewById<EditText>(Resource.Id.addDate);
EditText addPosition = FindViewById<EditText>(Resource.Id.addPosition);
button2.Click += (sender, e) =>
{
AddExpreince(1, addCompany.Text, addPosition.Text, addDate.Text);
};
}
All i want to do is to have a class that creates dynamically a button and fills it with the text 'tarr' automatically. So i generated a new class and wrote the following in it:
import android.widget.Button;
public class FloatButton {
Button button = new Button(this);
button.setText("tarr");
}
in my main activity it should make an object of this class. So i wrote this in the activity (snippet):
...
public void onCreate() {
super.onCreate();
FloatButton myButton = new FloatButton();
}
Sadly this gives me some mistakes marked. The mistake i don't realy understand is why the 'this' is marked. Can you tell me the problem?
When sending this to the Button constructor method, you are not sending a
valid Context, but your FloatButton object.
Android Context
What you can do is :
public class FloatButton {
private Context _context;
public FloatButton(Context context) {
this._context = context;
}
public createButton() {
Button mButton = new Button(_context);
mButton.setText("tarr");
}
}
PS : Why are you trying to create a button in a separate class, and not directly in your activity ?
You are trying to create a button dynamically and then add it to your activity.
The thing you are doing wrong is obviously not providing any context and two, you are not adding it to your activity's layout without which you will not be able to actually 'display' the button.
Here's what you need to do:
Create a function in the FloatButton class which receives a context and returns a button object as:
public Button createNew(Context c){
Button b = new Button(c);
b.setText("tarr");
return b;
}
In your main class, create a FloatButton object and call the createNew function as:
FloatButton fb = new FloatButton();
Button button = fb.createNew(this);
This will give you a button object which you then have to add to your layout
Now you need to declare the mandatory layout parameters which are height and width. Do it as:
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
Get your activity's primary layout (LinearLayout or RelativeLayout) as:
LinearLayout ll = (LinearLayout)findViewById(R.id.layout_main);
where layout_main is the id of your layout
Finally add your button to the layout and set its layout parameters as:
ll.addView(button, lp);
Though I would NOT recommend doing such a thing because you can replace the FloatButton class creation and instantiate using a simple Button button = new Button(this) in your main class itself. So, it is very redundant unless you want to do several customizations to your button in the FloatButton class itself like making it a different color or something and creating the button several times at several places.
I'm currently working in an Activity which saves text from three EditViews and constructs a SQL query. After that, the query is given to another activity to search and display the results.
Right now I've got two buttons, one to save the query, inside an onClickListener and another button to start the second activity:
searchButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//First the data from the editviews is saved
EditText searchName = (EditText) findViewById(com.pedro.books.R.id.search_name);
search_name = searchName.getText().toString();
searchName.setText("");
EditText searchAut = (EditText) findViewById(com.pedro.books.R.id.search_aut);
search_aut = searchAut.getText().toString();
searchAut.setText("");
EditText searchYea = (EditText) findViewById(com.pedro.books.R.id.search_yea);
search_yea = searchYea.getText().toString();
searchYea.setText("");
//here i construct the query
});
And with an onClick in the xml code, I start the activity with another button:
public void ReadResults(View view){
//The query is given to the ReadActivity to display the results
Intent intent = new Intent(this, ReadActivity.class);
intent.putExtra(ReadActivity.EXTRA_QUERY, query);
startActivity(intent);
}
I've tried with the same button for both without changing anything and it obviously doesn't work, and I've also tried to start the activity inside the onClickListener, but I got this error: "The constructor Intent(new View.OnClickListener(){}, Class) is undefined"
Is there a way to start the activity inside the onClickListener or to stop the second activity to start until the query is saved?
Thanks in advance!!
if you are putting the intent in the onClick of a button you cannot use this you need to use YourActivity.this to properly get context.
this in your button is your OnClickListener like the error says
Where/How do you call your ReadResults method? On a side note - does it need to be public? If you call it inside the clickListener handler then that's wrong.
1) Extract your code out of the clickListener handler and have it into a private method within your activity class.
2) Your clickListener should only call that private method.
3) You could have your 3 editboxes as memebers of your activity and instantiate them onCreate() instead of getting them each time you click the button, it's expensive parsing the UI if not necessary.
Here's the situation: I have an activity that dynamically generates a bunch of randomized custom imagebuttons and adds them to TableRows, in a TableView, in my xml. This activity also has a method that I want to call when one/any of these buttons is clicked. The buttons have variables inside them; the method gets these variables and sets them into a TextView (in the same activity) so I figure all the buttons can use this one method. If these buttons were defined in the XML I would just use android:onClick="displayCell" to specify the method, but they aren't. Is there a way to just set onClick for these buttons as I'm generating them in the activity or do I have to use
button.setOnClickListener(new OnClickListener(){....});
and go through a bunch of hassle as I've seen in some of the answers around here? The problem I have with that is that I can't seem to call my method from inside onClick because the argument of the method (the button) is not final (I'm making a bunch of 'button' in a loop so I don't think it can be):
button.setOnClickListener(new OnClickListener(){
public void onClick(View q){
button.getActivity().displayCell(button);//I want to do something like this but this obviously doesn't work
}
});
You can have the Activity implement OnClickListener and then (assuming you are in the activity):
button.setOnClickListener(this);
Yes as comodoro states, or make your onClickLIstener a member variable of your class, don't do a "new" on each button.
private OnClickListener mOnClickListener = new OnClickListener() {...};
and when creating your buttons:
button.setOnClickListener(mOnClickListener);
The onClick() function in your listener will be passed the View of the button itself. You can access the buttons variables, etc, from this function.
public void onClick(View v)
{
ImageButton button = (ImageButton)v;
// and access your button data via button object...
}
A solution to this could be :
Create different instances of buttons .(So you can make them final)
Use setId() method to give them an integer ID (to refer to them later).You can store the ID's in an a Listto refer them later on.
Define their onClickListeners right after you create it.
Try using a class that inherits from button and add there the OnClickListener. Like this:
class MyButton extends Button {
OnClickListener clicker = new OnClickListener() {
public void onClick(View v) {
displayCell(v);
}
};
}
Th question: Can I re-use RadioButton objects over and over again in an child activity?
I have a parent activity and a child activity. In the child activity, I have a large number of radio button displayed in a UI. In order to provide databinding from the parent down to the child, I have created a class (below) which contains a collection of RadioButtons. To populate the child activity, I pass a reference to this class down to the child which then groups the radioButtons into RadioGroups and displays them. I do this because the checked status of each button is now automatically available in the parent class, without the need to transfer any data through bundles.
public class GeneralAttribute{
Activity mThis;
public class Gender { // Mutually exclusive members
String categoryDesc = "Gender of user";
RadioButton isUnspecified = initRadioButton("Unspecified", true);
RadioButton isMale = initRadioButton("Male" , false);
RadioButton isFemale = initRadioButton("Female" , false);
} ;
<....more subclasses....>
RadioButton initRadioButton(String str, Boolean b) { // Factory
float cLayoutWeight = 0.5f;
RadioButton rb = new RadioButton(mThis);
rb.setText (str);
rb.setChecked(b);
rb.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, cLayoutWeight));
return rb;
}
GeneralAttribute(Activity localThis){ // Constructor
mThis = localThis;
gender = new Gender();
handedness = new Handedness();
location = new Location();
}
}
In the parent activity i have:
public class Parent(...)
public GeneralAttribute mGeneralAttribute; // Member class of RadioButtons
public static SPIGestureLoggerActivity TopLevelActivity;// Reference to the parent activity
public void onCreate(Bundle savedInstanceState) {
TopLevelActivity = this; // Assign this to the reference
mGeneralAttribute = new GeneralAttribute(this); // Initialize the class of RBs
startActivity(child); // Start the child
In the child activity i have this:
radiogroup = new RadioGroup(this);
radiogroup.setOrientation(RadioGroup.VERTICAL);
radiogroup.addView(Parent.TopLevelActivity.mGeneralAttribute.gender.isUnspecified);
radiogroup.addView(Parent.TopLevelActivity.mGeneralAttribute.gender.isMale);
radiogroup.addView(Parent.TopLevelActivity.mGeneralAttribute.gender.isFemale);
Parent.TopLevelActivity.mGeneralAttribute.gender.isUnspecified.setChecked(true);
mLinearLayout.addView(radiogroup);
This works fine....the first time the child activity is displayed. The second time it is displayed I get an exception.
In summary, here is the chain of events:
create the class of RadioButtons,
pass them to the child,
add them to a new RadioGroup
collect user choices
finish the child acitivty (which should destroy the RadioGroups)
use the data in the parent,
start the child activity again,
attempt to add the RadioButtons to new RadioGroups...
...Exception.
I can avoid this problem, if I null the class and reconstruct it. However, I would like to re-show the choices made from the first viewing with the second viewing.
Ideas:
Are the radioButtons saving pointers to the non-existant RadioGroups from the first viewing?
Is there a way to re-assign the view parent on each radio button in the class?
P.S. You may ask why I'm not using XML. For one, I will have 100+ of these radio buttons and I think it will be too painful to manage through XML. For another, I just like working programmatically on these things.
make sure you remove all the radiobuttons from the all radiogroups. Basically your right the radiobuttons are saving pointers to the non-existant raidogroups and no there isn't isn't a way to reassigned without calling removeAllViews on all the radiogroups. The best place to do that will be the onDestroy if your sure thats being called.