Hello I'm writing a little Android app (Version 2.3.3). Now i get this strange NullPointer Exception in this very basic code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainmenu);
newDeck = (Button) findViewById(R.id.newDeckB);
loadDeck = (Button) findViewById(R.id.loadDeckB);
viewEdition = (Button) findViewById(R.id.viewEditionB);
newDeck.setOnClickListener(this);
loadDeck.setOnClickListener(this);
viewEdition.setOnClickListener(this);
}
Im using this simple layout at the moment in main menu.xml:
<?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">
<Button android:id="#+id/newDeckB"
android:text="New Deck"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<Button android:id="#+id/loadDeckB"
android:text="Load Deck"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<Button android:id="#+id/viewEditionB"
android:text="View Edition"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<TextView android:id="#+id/currentDeckTextView"
android:text="Default Deck"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Now my problem is a nullpointexception in line 25, which is the line where i set the first clickListener
newDeck.setOnClickListener(this);
Using the debugger i figured out that the button newDeck is null. I searched a lot in the web but the only answer to such kind of problem was to check that the setContentView is set before the findViewById. This is obviously the case here.
I would be very glad for any kind of advice.
Thx in Before!
Get your views and set the listeners in onPostCreate() method.
There are two events that the App expects, onCreate(), and onStart()
Which one you put this function in, matters.
I had to move "findViewByID" from onCreate() to onStart()
#Override
protected void onStart() {
// use findViewById() here instead of in onCreate()
}
Related
I want use android:onClick to access the functions at MainActivity from activity_main.xml but it's deprecated. Is there another way or replacement for onClick?
Here the code:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="horizontal">
<Button
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:textSize="30dp"
android:id="#+id/btn00"
android:onClick="click"></Button></LinearLayout>
and my function at MainActivity
fun click(view: View){
Toast.makeText(applicationContext,"Clicked",Toast.LENGTH_SHORT).show
}
There is an error saying "Corresponding method handler 'public void click(android.view.View)' not found.
The XML error is because there is no context specified for your layout file. you can specify it in the root element of layout XML file as
tools:context="yourpackage.MainActivity"
This basically tells the XML to look for click function in MainActivity.
Other than that this code should run correctly, given that you have specified the correct XML layout in your Activity setContentView.
point worth noting is that there is always an option to do it
programmatically in your Activity onCreate
val button = findViewById<Button>(R.id.btn00)
button.setOnClickListener{
Toast.makeText(applicationContext,"Clicked",Toast.LENGTH_SHORT).show()
}
Thanks all for the help,
Turns out I place my function at the wrong place.
I'm sorry for the trouble.
Turn out it's just a petty mistake :D
Edit: Turns out i placed my fuction outside of the class
I have a list view that is populated through a string-array in the xml, not run time and I'm trying to set the background color of specific items in the list using:
listView.getChildAt(x).setBackgroundColor(Color.BLACK);
I need this to happen before it's visible, but it gives an error when I use it in onCreate() or onStart(), but works if I run it on a button press. I've tried searching for an answer but can't seem to find any event that happens late enough for it to work.
getView() would be the best place to do this, but you don't have access with the way you are doing this with android:entries=.... Instead, you can post a runnable to the message queue to change the color after layout occurs like the following:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.layout).post(new Runnable() {
#Override
public void run() {
findViewById(R.id.view).setBackgroundResource(android.R.color.holo_red_dark);
}
});
}
Here I have used a simple View for demonstration but the same technique should work for your ListView.
Here is the XML I used if you want to work with it:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<View
android:id="#+id/view"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#android:color/holo_blue_light" />
</LinearLayout>
Here's a link to post. The runnable kicks off before onStart(). So, if that's a requirement, then this way may not work for you.
I'm using a button to call a method that just places input text into a textview. Whenever I use findViewById, it returns null.
public void encode(View view){
TextView out = (TextView) view.findViewById(R.id.encoderout);
EditText in = (EditText) view.findViewById(R.id.encoderin);
out.setText(in.getText().toString());
out.setTypeface(font);
}
My xml is here
<?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"
>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
>
<EditText android:id="#+id/encoderin"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="wrap_content"
android:hint="Text to encode"/>
<Button android:id="#+id/encoderbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="encode"
android:text="Encode!"/>
</LinearLayout>
<TextView android:id="#+id/encoderout"
android:text="test"
android:layout_width="fill_parent"
android:layout_weight="1"
android:gravity="center"
android:layout_height="wrap_content"/>
</LinearLayout>
Almost every post I could find said that cleaning the project helped solve the problem but not in this case.
EDIT: ADDITIONAL INFO
I'm using Fragments, and this is my fragment code
public static class Encoder extends Fragment{
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.encoder, container, false);
return view;
}
}
It's calling up into the Activity because of the way buttons work. I can call the find methods fine in the fragment, but not when I have to go back to the activity.
I can verify the view is not null, it prints out fine when the toString is called in the method.
Solution: Never realized that I had to use the main view, thought I was SUPPOSE to use the button view. I'm very new to this (started today) thankyou everyone for the input!
<Button android:id="#+id/encoderbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="encode"
android:text="Encode!"/>
The parameter view in callback method encode(View view) in the Java code is supplied with the Button view itself but not the Activity.
See Reference below:
http://developer.android.com/reference/android/widget/Button.html
Fragments don't receive onClicks methods that are declared in the XML. You need to define encode in your Activity instead, then direct the desired behavior to the appropriate Fragment. Annoying, but that's the way it's done. I suggest you just implement the OnClickListener programatically in your Fragment code to avoid intertwining the behavior of your fragment and activity.
I am trying to specify a progress spinner as I have done in my testLayout.xml file, and then programmatically display and hide it as I have done in my activity code below. Whats happening however is that the progress wheel will display, but it never goes away even though I have setProgressBarVisibility(false); at the end. Any ideas? Thanks for input
layout/testLayout.xml
<Button android:layout_width="fill_parent"
android:layout_height="wrap_content" android:id="#+id/ButtonNew"
android:text="New" android:layout_alignParentBottom="true" />
<ListView android:layout_width="fill_parent"
android:layout_height="fill_parent" android:id="#+id/list"
android:layout_alignParentTop="true" android:layout_above="#id/ButtonNew" />
<ProgressBar style="?android:attr/progressBarStyleLarge" android:layout_width="wrap_content" android:id="#+id/progressBar1" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true"></ProgressBar>
</RelativeLayout>
TestActivity.java
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_PROGRESS);
setContentView(R.layout.testLayout);
setProgressBarVisibility(true);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
setProgressBarVisibility(false);
}
Well there is a problem in your code because your Thread.sleep call will cause the onCreate to wait 5 seconds before continuing. You should never perform a Thread.sleep call on the main UI thread as it will cause the application to not respond for that amount of time. Now with regards to the ProgressBar, it seems that you are not correctly using the setProgressBarVisibility with your xml file. Those functions should be used for ProgressBar's that are contained in the title bar. You should just use findViewById(R.id.progressBar1).setVisibility(View.Gone) to hide or View.Visible to show. But if both of these calls are done inside of the onCreate you will only see the one that was called last. This is because no ui is actually shown to the user until the activity has returned from onResume and onCreate.
I have a basic calculator app I'm making. Two activities, the main one and ResultView.
I've made it where I click a button on activity A to go to activity B. The log says activity B is started and "displayed" successfully, the title for the new activity loads, but the body does NOT show. I added a simple Text view with static text.. see the result.xml at the bottom. I also tried inserting information programmatically, but that didn't do.
When I debug the program, I tried putting breakpoints as the activity is called with startActivity() as well as on the first line of the onCreate method within the ResultView class (my activity "B") but the program never hits the second breakpoint. In fact, it looks as if Looper.class is called in the end.
This bit of code is placed in the button handler on acitivity A:
i.putExtra("test1",34);
i.putExtra("test2",35);
this.startActivity(i);
This in the onCreate function in activity B:
public void OnCreate(Bundle
savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.result);
}
The activity is in the manifest, within the "application" tag:
<activity
android:name="ResultView"></activity>
If I didn't supply enough info, let me know.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/llParent"
android:orientation="vertical"
android:padding="10dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:text="HELLO WORLD"
/> </LinearLayout>
If more info is needed, let me know...in short, "HELLO WORLD" does not display at all.
It's not OnCreate, it's onCreate (lowercase o). Otherwise the method won't be overriden. The #override annotation has no effect if it's omitted, it's just for readability for the programmer.
Are you sure that the public void line or the line before that contains #Override? If not, you're not overriding the OnCreate method. The code should read
#Override public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.result);
}
EDIT
Of course the "O" must not be a capital "O"...