I was looking at my code and I realized that there are at least 3 ways of getting widget's reference in code:
First one (before onCreate):
private TextView textView= (TextView) findViewById(R.id.textView);
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
}
Second one (in onCreate):
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
final TextView textView= (TextView) findViewById(R.id.textView);
}
Third one (creating out and setting in onCreate):
private TextView textView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
textView= (TextView) findViewById(R.id.textView);
}
What is the difference between this 3 methods? When should I use them?
You must call setContentView() prior calling findViewById(), therefore on 1st approach will give you null all the times. 2nd and 3rd are the same with the exception for final keyword, but this is Java feature, not Android's.
The first does not guarantee that your widget is actually instantiated, it is not within the onCreate.
Second will be instantiated, but its value can not be changed because it becomes a constant to be the final.
Third, it is a global variable that will be instantiated in onCreate and you can use it in any other part of your code.
If you need to call findViewById() then the call should be anywhere after setContentView. Not before that like in your first option. Your third option creates an instance variable, use it only if the textview will be accessed a lot throughout the class, otherwise just call findViewById wherever you need it.
Related
Quick notice: I am using SharedPreferences so that I can reload data when I re-open the app.
Problem
I have a LinearLayout in the main fragment of my application. Everything runs smoothly until I re-open the app and try to reinitialize the LinearLayout.
I am trying to initialize the LinearLayout with findViewById(). I have put the function in many different places. Currently I am trying to get it to work in onCreate and a function that is called from onCreate. Here is my code so far:
public class MainActivity extends AppCompatActivity {
LinearLayout linearLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
linearLayout = findViewById(R.id.linearLayout);
// this is where is load the SharedPreferences
// this is where I implement them back into the app ('reload' the app)
reload();
}
public void reload() {
// bunch of other irrelevant stuff
linearLayout = findViewById(R.id.linearLayout);
linearLayout.addView(/*other view*/); // this is where it complains
}
// the is for when the button is clicked
public void submitEntry(View view) {
// this is fine according to Logcat
linearLayout = findViewById(R.id.linearLayout);
}
}
I would expect after initializing it twice, or at least trying to, that is would've caught on but no. Logcat complains that linearLayout is a null object reference. I don't know what to do at this point but it's probably something simple that I've overlooked. Any help would be appreciated.
LinearLayout linearLayout= new LinearLayout(context);
Initialize like this it will help you!
Quick notice: I am using SharedPreferences so that I can reload data when I re-open the app.
Problem
I have a LinearLayout in the main fragment of my application. Everything runs smoothly until I re-open the app and try to reinitialize the LinearLayout.
I am trying to initialize the LinearLayout with findViewById(). I have put the function in many different places. Currently I am trying to get it to work in onCreate and a function that is called from onCreate. Here is my code so far:
public class MainActivity extends AppCompatActivity {
LinearLayout linearLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
linearLayout = findViewById(R.id.linearLayout);
// this is where is load the SharedPreferences
// this is where I implement them back into the app ('reload' the app)
reload();
}
public void reload() {
// bunch of other irrelevant stuff
linearLayout = findViewById(R.id.linearLayout);
linearLayout.addView(/*other view*/); // this is where it complains
}
// the is for when the button is clicked
public void submitEntry(View view) {
// this is fine according to Logcat
linearLayout = findViewById(R.id.linearLayout);
}
}
I would expect after initializing it twice, or at least trying to, that is would've caught on but no. Logcat complains that linearLayout is a null object reference. I don't know what to do at this point but it's probably something simple that I've overlooked. Any help would be appreciated.
LinearLayout linearLayout= new LinearLayout(context);
Initialize like this it will help you!
I have a button with a method that is invoked upon clicking.
The method:
public void addToList(View view) {
System.out.println(1);
String str = "";
try{
str = edit.getText().toString();}
catch (Exception ex){
System.out.println( ex );
}
System.out.println(2);
new QueryInList( ).execute(helper, str);
System.out.println(3);
edit.setText(null);
System.out.println(4);
//adapter.notifyDataSetChanged();
}
Well, I always get the exception, it is a Nullpointerexception.
This quite baffles me, because edit IS initalized:
It is declared in the class:
private EditText edit;
and besides, it is initialized in onCreate:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
edit = (EditText)findViewById(R.id.textfield);
setContentView(R.layout.activity_view);
......}
So I wonder why I always get a Nullpointer?
Set the content view, before looking for the items. You dont have a view to find the items in until you set the content view.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view);
edit = (EditText)findViewById(R.id.textfield);
......}
Move edit = (EditText)findViewById(R.id.textfield); after your setContentView statement.
Here is a nice explanation from user #Squonk from another question:
setContentView(...) perfoms something called 'layout inflation'. What that means is it parses the XML in the relevant file (main.xml in your case) and creates instances of all the UI elements within it. It then attaches that view to the Activity. When you call findViewById(...) it doesn't reference your main.xml directly - instead it references the content view attached to the Activity, in other words the one inflated by setContentView(...)
Trying to get started with Android development, and doing some basic work with TextViews..
For some reason TextView's setText() method is causing huge problems for me.. here's a simplified version of my code to show what I mean:
package com.example.testapp;
import android.os.Bundle;
import android.app.Activity;
import android.widget.TextView;
public class MainActivity extends Activity {
TextView text;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
text = (TextView) findViewById(R.id.text1);
setContentView(R.layout.activity_main);
text.setText("literally anything");
}
}
This will cause a crash, and I don't understand why.. if I create the TextView within the onCreate it works just fine, but if I create it outside of it, it doesn't.. why is that? Has the line "TextView text;" not been executed yet or something?
Thanks!
You need to call setContentView() before initializing the TextView so that your Activity has access to all the layout components.
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.text1);
text.setText("literally anything");
switch these 2 lines
text = (TextView) findViewById(R.id.text1);
setContentView(R.layout.activity_main);
you need to set the content first
From docs:
onCreate(Bundle) is where you initialize your activity. Most
importantly, here you will usually call setContentView(int) with a
layout resource defining your UI, and using findViewById(int) to
retrieve the widgets in that UI that you need to interact with
programmatically.
So this means that if you will reference your views in the layout, you must first set the content view and already then call findViewById method to reference child views of the layout resource defining your activity's UI
text = (TextView) findViewById(R.id.text1);
setContentView(R.layout.activity_main);
text.setText("literally anything");
If "literally anything" is a variable, which often may be the case, be sure that it isn't throwing a NullPointerException. I kept having that problem myself. I fixed it to be:
text = (TextView) findViewById(R.id.text1);
setContentView(R.layout.activity_main);
try {
text.setText("literally anything");
} catch (NullPointerException e) {
// Do something
}
Exceptions can be really useful, so if you're a beginning programmer, I suggest you put exception handling on your list of things to learn soon.
Is it possible to add a button to the right corner of the app title?
e.g., adding a "refresh" button to the title of "Feed: my feeds"?
http://www.android.com/market/apps/feedr-lg-01.jpg
The simplest way to do that, IMHO, is to get rid of the standard title bar (android:theme="#android:style/Theme.NoTitleBar" in the <activity> element in the manifest) and put your own "title bar" at the top of the activity.
Note, though, that the "button in the title bar" style is more iPhone-ish. Android would typically have that in the option menu, so the UI is less cluttered (at the cost of two taps to do the refresh).
Why don't you try this
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final boolean customTitle= requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.main);
if ( customTitle ) {
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, Set your layout for title here and mention your button in this layout);
}
final TextView myTitleText = (TextView) findViewById(R.id.myTitle);
if ( myTitleText != null ) {
myTitleText.setText("NEW TITLE");
myTitleText.setBackgroundColor(Color.BLUE);
}
}
yep this solveed an issue i had... trimmed version is below...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.main);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, Set your layout for title here and mention your button in this layout);
final TextView myTitleText = (TextView) findViewById(R.id.myTitle);
if ( myTitleText != null ) {
/* your code here */
}
}
I think a better approach would be to simply refresh the view if it is active by using a Handler. If your pulling content when the activity is resumed then any time you leave and come back to the view it will refresh. If you are expecting users to sit at the top level of the view and need to update the information then you can handle this with a delayed handler which will call your resume method and periodically refresh the view thus negating the need for a button.
Here is a link to the documentation for the handler class. I would start by looking into the basic use of handler. Then test the sendMessageDelayed method so that at the end of every call you restart the handler. Also be sure to only create a new handler if your activity is the top activity and don't bother refreshing the ui if it is not. Adding a simple isActive flag to on pause and on resume is a decent way to check for this.