Android: Set Widgets Once Only using FindViewById - android

Right now, every time I want to access a widget I use:
mEditText1 = (EditText) findViewById(R.id.edittext1);
And then perform the action I would like to on the widget.
However, I am wondering if I am able to store a reference to a widget and use that reference multiple times in different methods within the activity, without having to always call findViewById...
I've tried the following:
public class MyActivity extends Activity {
public static String ACTIVITY_NAME = "MyActivity";
EditText mEditText1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v(this.APP_NAME, "In " + ACTIVITY_NAME);
mEditText1 = (EditText) findViewById(R.id.edittext1);
setContentView(R.layout.main);
prefillFieldsIfNecessary();
}
private void prefillFieldsIfNecessary(){
if(AppPreferences.checkExistence(MyActivity.this, AppPreferences.Name)) {
mEditText1.setText(AppPreference.Name);
}
However, my app just crashes and I get a NullPointerException, which I know speaks to the mEditText1.setText() line, because when I comment that out, my app runs fine.

Asha, this should work and is completely valid. How do you know it's not working? Are you getting an error? Is textToSave not being populated appropriately?

Check if you're declaring "EditText mEditText1;" after your import statements and before your class declaration. Also specify an access modifier, not specifying an access modifier to a class field is not good. It would be nice if you can post a full example of your Activity, so that we can see if you're declaring "EditText mEditText1;" as a class member or variable.
Edit:
Move
setContentView(R.layout.main);
right after
super.onCreate(savedInstanceState);
and you'll be fine. Generally try to have those 2 lines
on top of your onCreate() and do all logic, after those 2 lines.

Related

Android Studio - getting input from EditText View

Inside of my enteredName method, I want to be able to check to make sure the user has entered their name inside of the name text box. I know that I already made the input equal to name by using findViewById. What I'm having trouble with is how do you get that input so you can use in the enteredName method as well? Do I need to use findViewById each time I'm referring to what the user entered into the box?
public class MainActivity extends AppCompatActivity {
EditText name;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
name = findViewById(R.id.name);
}
public boolean enteredName(){
}
Your first question.
how do you get that input so you can use in the enteredName method as
well?
We can get their input by using this one.
name.getText().toString();
So you want to use in method boolean enteredName(). You can do something like this.
public boolean enteredName(){
if (name.getText().toString().isEmpty()) return false;
return true;
}
your 2nd qestion.
Do I need to use findViewById each time I'm referring to what the user
entered into the box?
Yes. it really necessary to link using findViewById. If you don't want to use it, you can use butterKnife lib.

Simple increment counter doesn't work in android app

sounds stupid but a simple increment counter doesn't work in my android app.
I have two activities in the app and one counter in each, which is incremented each time when onCreate method is called. When I'm switching between the activities the first one works well, but the other one just doesn't count.
I'm using the same line to create the variable like this:
private int mCreate;
Then I'm just incrementing it in the same way in each class in the onCreate method:
mCreate++;
This variable is used in two different classes, so it shouldn't be a problem. This is my first android app, so I need some help.
The whole code of the second activity. I'm not showing the first one because the only difference is in the setOnClickListener method.
public class ActivityTwo extends Activity {
private final static String TAG = "Lab-ActivityTwo";
private int mCreate;
private TextView mTvCreate;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_two);
mTvCreate = (TextView) findViewById(R.id.create);
Button closeButton = (Button) findViewById(R.id.bClose);
closeButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
Log.i(TAG, "Entered the onCreate() method"); // to check if the inCreate method was called
mCreate++;
mTvCreate.setText("onCreate() calls: " + mCreate);
Log.i(TAG, "mCreate = " + mCreate); // just to check if I implemented the TextView worng
displayCounts();
}
The reason your second counter doesn't work because after finishing an activity all the variables and objects are destroyed and make free by GC. The next time you call for that activity it is created from scratch and your count remain same everytime.
Like #Opoo said if you want to get count you should define static variable in Application class.

Pass reference of one Activity to another Activity

I know that I can pass some values between Activities using intent.
However, if I want to pass whole Activity to another Activity I think it is not good approach.
Is there another way to do that?
I have Settings Activity in which I am changing some Colors. So after I come back to my Main Activity I would like to apply those colors. To do this, I need access to MainActivity fields after I change Color value, so inside PreferenceActivity. In other words, I want to have access to Main activity fields from PreferenceActivity class. Any ideas?
You should be using a SharedPreference and then accessing that in your main activity. I recommend you reading up at http://developer.android.com/guide/topics/ui/settings.html because it seems like you are implementing your settings activity incorrectly. The part you might be specifically interested in is the "Read Preferences" section. However, I strongly suggest you read through the whole thing and then implement your settings the proper way.
Updated answer with the 3 different ways (that I can think of):
1) Start your preference activity using startActivityForResult(), then in your onActivityResult() access the SharedPreference and make your necessary changes. See here
2) Register a SharedPreferenceChangeListener with your MainActivity, which will be called when any changes happen to your SharedPreference. See here for a detailed discussion. Also see my initial response.
3) In your MainActivity's onResume(), access the SharedPreference and then make your changes there. I do not like this method because you will be cluttering onResume() with more logic and you will also probably have to have a variable that keeps track of the state of the variable you are interested in.
I would personally go with option 2 because the callback was created for this exact purpose.
I think you could pass the value by using method putExtra(name, value).
And after you start new activity you can get the value you pass before by using method getStringExtra(name).
Shared preferences can be used. If you want your changes to be reflected right away add listener. Refer to SharedPreferences.onSharedPreferenceChangeListener. Its an easy way to do.
If you want to lots of changes required in many activity from you change in any one.
And access last modify data from all Activity and modify also.
for example.
Constants.java
public class Constants
{
public static String name;
}
In your MainActivity you have an editText.
MainActivity.java
public class MainActivity extends Activity {
private EditText yourName;
private Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
yourName = (EditText) findViewById(R.id.yourName);
btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
Constants.name = yourname.getText().toString();
Intent intent = new Intent(getApplicationContext(),Activity2.class);
startActivity(intent);
}
});
}
In your Activity2 you have an TextView and that getting value which you enter in MainActivity.java without pass in Intent.
Activity2.java
public class Activity2 extends Activity {
private TextView yourName;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
yourName = (TextView) findViewById(R.id.tv_yourName);
// directly use ferom serializable class
yourname.setText(Constants.name);
}
like that you use many values from all activity and modify from all activity.

How do I save the content view of my activity?

Alright so in my activity i changed my content view from one to another as you can see. so i was wondering how to save the content view that was there last when my activity was closed.
public class Levels extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(android.R.style.Theme_NoTitleBar_Fullscreen);
setContentView(R.layout.levels);
final EditText anstext1 = (EditText) findViewById(R.id.anstext1);
Button button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String result = anstext1.getText().toString();
if(result.equals("they"))
setContentView(R.layout.social);
else
Toast.makeText(getApplicationContext(), "Wrong", Toast.LENGTH_LONG).show();
}
});
}
}
setContentView
You should call this method only once in the Activity lifecycle.
Saving State
Most of the time you will save your models using onSaveInstanceState and restore them using the bundles generated from that method. Activity, Fragment and Views have these kind of methods build in.
Persisting state
If you are required to use the data for a longer period than the current app lifecycle you can use one of the following mechanisms:
SharedPreferences
SQL-lite DB
File I/O
Create a variable that has the type of R.layout.levels. Assuming R.layout.levels is a RelativeLayout: RelativeLayout rl;
Initialize it like this:
rl = (RelativeLayout) getLayoutInflater().inflate(R.layout.levels,null);
setContentView (rl);
If you want to save the variable for when the activity is destroyed you can put it in a custom Application class and retrieve it from there. You find here how to do it at "maintaining global state" : http://www.intridea.com/blog/2011/5/24/how-to-use-application-object-of-android
I don't know if it is good or bad to do this, but it could be a solution for what you're asking.

Android (student cw) in need of direction

public class Menu extends Activity {
/** Called when the activity is first created. */
public void onCreate(Bundle icicle) {
//myIntent.setClassName("hello.World", "hello.World.mybuttonclick");
// myIntent.putExtra("com.android.samples.SpecialValue", "Hello, Joe!"); // key/value pair, where key needs current package prefix.
//startActivity(myIntent);
//Button myButton = (Button) findViewById(R.id.my_button);
super.onCreate(icicle);
setContentView(R.layout.main);
}
public void updateLayout(){
Intent myIntent = new Intent(Menu.this, mybuttonclick.class);
startActivity(myIntent);
// TextView sayHello = (TextView) findViewById(R.id.Hello);
}
}
Hey guys, I am a new android java student and we have to develop a simple hello world app.. I am finding some difficulty getting my onClick() activity to work, using android:Onclick in xml.. what i am trying to do is change the content view do display a simply a different layout and saying hello.. i am using setContentLayout to do this, every time i click said button tho the android app crashes out.. am i doing something wrong?
regards,
Stefan
When you set a click listener in xml you must have the method defined inside the activity you are clicking in. Lets say you set the onClick in xml to be "buttonClicked", you must create a method looking exactly like the one below.
public void buttonClicked(View view)
{
//Your code here
}
The thing to notice is that the method is a public void with only a single parameter of type View. XML defined click listeners must be like this to work. The view object in the example above is the view that was clicked.
You update layout function needs to read
public void updateLayout(View view)
In response to your question, there are a number of things that are issues causing the complication that you described. Let it first be said, that you don't have to do anything any particular way, provided that you make concessions for certain things. Android is a very flexible platform and Java, as an OOP language allows you to do things that many non OOP languages do not.
Whenever you create a "clickable" item, like a Button, if you want to have your program respond, you must have something "listen" to it. This is known as a Listener. In your case, you are looking for an OnClickListener. The OnClickListener does not have to be a part of the Activity necessarily. It just has to be a class that implements View.OnClickListener. Then, you have tell the setOnClickListener() method of the Button who its listener is. The following example shows what is necessary without your declaration in XML (but it is important).
class Menu extends Activity implements View.OnClickListener
{
public void onCreate(Bundle icicle)
{ setContentView(R.layout.main);
Button btn = (Button)findViewById(R.id.BUTTON_ID_AS_DEFINED_BY_YOUR_XML);
btn.setOnClickListener(this);
}
public void onClick(View view)
{ int id = view.getId();
if (id == R.id.BUTTON_ID_AS_DEFINED_BY_YOUR_XML)
updateLayout()//Do your Click event here
}
public void updateLayout()
{ //updateLayout code...
}
}
Something that needs to be noted is the OnClick() above. Every OnClickListener must use the same signature as theOnClick() That means itmust have the same return and same arguments even if it has a different name. For what you are trying to do (in XML), you have set your android:OnClick to updateLayout. This means that `updateLayout() must be declared as follows:
public void updateLayout(View view)
Now, getting the update method to actually work: While you provide your code, we don't actually know what errors you are getting. It is always much easier to solve a problem if we have a copy of the Logcat output that includes the error you are receiving. Once, we have that we can target your error specifically and I can edit my answer to include what you may additionally need.
FuzzicalLogic

Categories

Resources