Cannot launch DialogPreference programmatically (Null Pointer Exception thrown) - java

I have a custom class that extends DialogPreference. It works perfectly if launched from the Preference menu. I want to be able to launch it from an Activity as well. Below is my DialogPreference class in which I exposed the showDialog() method suggested by this thread. When I call it I get a Null Pointer Exception but haven't been able to figure out why.
The error is thrown at line 27 which is in onBindDialogView() where hText.setText() is called.
package com.jumptuck.recipebrowser;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.DialogPreference;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
// Pop-up dialog used to set and modify host and login credentials
public class HostCredentialsDialogPreference extends DialogPreference {
static final String TAG = "HostCredentialsDialogPreference";
EditText hText, uText, pText;
public HostCredentialsDialogPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setDialogLayoutResource(R.layout.dialog_host_credentials);
}
#Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
Log.d(TAG,"onBindDialogView");
SharedPreferences sp = getSharedPreferences();
hText.setText(sp.getString("host", ""));
uText.setText(sp.getString("username", ""));
pText.setText(sp.getString("password", ""));
}
#Override
protected View onCreateDialogView() {
// Guide for this technique found at:
// http://alexfu.tumblr.com/post/23683149440/android-dev-custom-dialogpreference
Log.d(TAG,"onCreateDialogView");
View root = super.onCreateDialogView();
hText = (EditText) root.findViewById(R.id.host);
uText = (EditText) root.findViewById(R.id.username);
pText = (EditText) root.findViewById(R.id.password);
return root;
}
#Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if (positiveResult){
Log.d(TAG,"Clicked Save");
SharedPreferences sp = getSharedPreferences();
SharedPreferences.Editor editor = sp.edit();
editor.putString("host", hText.getText().toString());
editor.putString("username", uText.getText().toString());
editor.putString("password", pText.getText().toString());
editor.commit();
}
else {
Log.d(TAG,"Clicked Cancel");
}
}
void show() {
showDialog(null);
}
}
I'm using a "Testing" button try to launch the dialog from another Activity:
public boolean onOptionsItemSelected(MenuItem item) {
Log.d(TAG, "onOptionsItemSelected");
switch (item.getItemId()) {
case R.id.item_prefs:
startActivity(new Intent(this, PrefsActivity.class));
return true;
case R.id.refresh:
if (credentialsExist()) {
refreshListView();
}
return true;
case R.id.recipe_dir:
startActivity(new Intent(this, RecipeDisplayActivity.class));
return true;
case R.id.testing:
HostCredentialsDialogPreference hc = new HostCredentialsDialogPreference(this, null);
hc.show();
return true;
default:
return false;
}
}
Here are the xml files for my Preference and the Dialog Preference:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<com.jumptuck.recipebrowser.HostCredentialsDialogPreference
android:key="dialog_credentials"
android:title="Server Address and Login"
android:summary="Set Host, Username and Password" />
</PreferenceScreen>
and
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/dialog_hostname_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/dialog_hint_uri" />
<EditText
android:id="#+id/host"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textUri" />
<TextView
android:id="#+id/dialog_username_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/dialog_hint_user" />
<EditText
android:id="#+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text" />
<TextView
android:id="#+id/dialog_password_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/dialog_hint_password" />
<EditText
android:id="#+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif"
android:inputType="textPassword" />
</LinearLayout>
And finally the Logcat:
D/RecipeListActivity( 5894): onOptionsItemSelected
D/HostCredentialsDialogPreference( 5894): onCreateDialogView
D/HostCredentialsDialogPreference( 5894): onBindDialogView
D/AndroidRuntime( 5894): Shutting down VM
W/dalvikvm( 5894): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
E/AndroidRuntime( 5894): FATAL EXCEPTION: main
E/AndroidRuntime( 5894): java.lang.NullPointerException
E/AndroidRuntime( 5894): at com.jumptuck.recipebrowser.HostCredentialsDialogPreference.onBindDialogView(HostCredentialsDialogPreference.java:27)
E/AndroidRuntime( 5894): at android.preference.DialogPreference.showDialog(DialogPreference.java:289)
E/AndroidRuntime( 5894): at com.jumptuck.recipebrowser.HostCredentialsDialogPreference.show(HostCredentialsDialogPreference.java:62)
E/AndroidRuntime( 5894): at com.jumptuck.recipebrowser.RecipeListActivity.onOptionsItemSelected(RecipeListActivity.java:192)
E/AndroidRuntime( 5894): at android.app.Activity.onMenuItemSelected(Activity.java:2534)
E/AndroidRuntime( 5894): at com.android.internal.policy.impl.PhoneWindow.onMenuItemSelected(PhoneWindow.java:958)
E/AndroidRuntime( 5894): at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:735)
E/AndroidRuntime( 5894): at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:149)
E/AndroidRuntime( 5894): at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:874)
E/AndroidRuntime( 5894): at com.android.internal.view.menu.ListMenuPresenter.onItemClick(ListMenuPresenter.java:166)
E/AndroidRuntime( 5894): at android.widget.AdapterView.performItemClick(AdapterView.java:298)
E/AndroidRuntime( 5894): at android.widget.AbsListView.performItemClick(AbsListView.java:1086)
E/AndroidRuntime( 5894): at android.widget.AbsListView$PerformClick.run(AbsListView.java:2859)
E/AndroidRuntime( 5894): at android.widget.AbsListView$1.run(AbsListView.java:3533)
E/AndroidRuntime( 5894): at android.os.Handler.handleCallback(Handler.java:615)
E/AndroidRuntime( 5894): at android.os.Handler.dispatchMessage(Handler.java:92)
E/AndroidRuntime( 5894): at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime( 5894): at android.app.ActivityThread.main(ActivityThread.java:4745)
E/AndroidRuntime( 5894): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 5894): at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime( 5894): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
E/AndroidRuntime( 5894): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
E/AndroidRuntime( 5894): at dalvik.system.NativeStart.main(Native Method)
W/ActivityManager( 148): Force finishing activity com.jumptuck.recipebrowser/.RecipeListActivity
W/WindowManager( 148): Failure taking screenshot for (246x410) to layer 21025
W/ActivityManager( 148): Activity pause timeout for ActivityRecord{412097e0 com.jumptuck.recipebrowser/.RecipeListActivity}
I/Choreographer( 281): Skipped 39 frames! The application may be doing too much work on its main thread.
W/ActivityManager( 148): Activity destroy timeout for ActivityRecord{412097e0 com.jumptuck.recipebrowser/.RecipeListActivity}
Anyone idea what I'm doing wrong? Thanks!

The best answer can be found here but I think it needs just a bit of clarification because that answer wrongly suggests two different style declarations for the manifest.
If you want to launch one dialog from an Activity and still be able to launch it form a Preference you just need to create an Activity that launches the Dialog. That Activity can then be launched as an intent in the Preference XML or from another Activity. The trick comes in how you style it. You want to style the Activity as a Dialog. This way the dialog that your Activity launches will looks right. The side effect of this approach is that a floating Action Bar will be show in the middle of the screen behind your Dialog. The fix for that is to use a Dialog style with no ActionBar. I'm using Holo.Light theme so I put this in my AndroidManifest
<activity android:name=".DemoDialogActivity"
android:theme="#android:style/Theme.Holo.Light.Dialog.NoActionBar" />
The other part of the puzzle is to make sure you call finish(); when you're done (It's the last thing I did in the OnClickListener for both of my buttons). If you don't, the dialog will close but the Activity will still be open, leaving a small blank rectangle in the middle of a darkened screen.
Here's a working example of the Activity:
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
public class DemoDialogActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LayoutInflater lf = LayoutInflater.from(this);
// This adds XML elements as a custom view (optional):
final View customElementsView = lf.inflate(
R.layout.activity_credentials, null);
AlertDialog alert = new AlertDialog.Builder(this)
// This adds the custom view to the Dialog (optional):
.setView(customElementsView)
.setTitle("This is the Title")
.setMessage("This is the AlertDialog message (optional)")
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
// Cancel was clicked; do something
// Close Activity
finish();
}
})
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// OK was clicked; do something
// Close Activity
finish();
}
}).create();
// Show the dialog
alert.show();
}
}
Launch it programmatically:
Intent launch_dialog = new Intent(getApplicationContext(),
DemoDialogActivity.class);
startActivity(launch_dialog);
Or as a Preference in XML:
<Preference
android:key="demo_dialog"
android:title="Title of item on Prefs screen"
android:summary="This will be small text below the title">
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.example.package.DemoDialogActivity"
android:targetPackage="com.example.package" />
</Preference>

I've been working on this for some time now. There is one workaround which I find entirely inelegant. I can just use the xml layout to build a DialogFragment by making changes in the Activity:
class HCDialog extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// TODO Auto-generated method stub
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.dialog_host_credentials, null);
builder.setView(view);
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
})
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
});
builder.setTitle(R.string.dialog_title);
return builder.create();
}
}
The DialogFragment can be launched from a button like this (case statement is from the code pasted as part my original question):
case R.id.testing:
FragmentManager fm = getFragmentManager();
HCDialog hack_dialog = new HCDialog();
hack_dialog.show(fm, null);
return true;
This works. But to me it seems rather silly and I imagine I'm taking the long way around. Especially because now I'll be coding to handle persistent preference values for two versions of what appears to be the exact same dialog.
Is there a better way?

Related

Crash when adding a OnClickListener to a Button

I'm a total newbie with Android, and I'm trying to switch between two activities ("MainActivity" and "LoginDisplayActivity") and adding the "OnClickListener" seem to make my app crash on startup.
Here is my code :
package info.dremor.kronos;
import android.app.Activity;
import android.app.ActionBar;
import android.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.os.Build;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState == null) {
getFragmentManager().beginTransaction().add(R.id.container, new MainFragment()).commit();
}
final Button loginButton = (Button) findViewById(R.id.connect);
loginButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, LoginDisplayActivity.class);
startActivity(intent);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class MainFragment extends Fragment {
public MainFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
}
}
trace :
05-26 15:48:11.286: D/AndroidRuntime(947): Shutting down VM
05-26 15:48:11.286: W/dalvikvm(947): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
05-26 15:48:11.296: E/AndroidRuntime(947): FATAL EXCEPTION: main
05-26 15:48:11.296: E/AndroidRuntime(947): java.lang.RuntimeException: Unable to start activity ComponentInfo{info.dremor.kronos/info.dremor.kronos.MainActivity}: java.lang.NullPointerException
05-26 15:48:11.296: E/AndroidRuntime(947): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
05-26 15:48:11.296: E/AndroidRuntime(947): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
05-26 15:48:11.296: E/AndroidRuntime(947): at android.app.ActivityThread.access$600(ActivityThread.java:130)
05-26 15:48:11.296: E/AndroidRuntime(947): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
05-26 15:48:11.296: E/AndroidRuntime(947): at android.os.Handler.dispatchMessage(Handler.java:99)
05-26 15:48:11.296: E/AndroidRuntime(947): at android.os.Looper.loop(Looper.java:137)
05-26 15:48:11.296: E/AndroidRuntime(947): at android.app.ActivityThread.main(ActivityThread.java:4745)
05-26 15:48:11.296: E/AndroidRuntime(947): at java.lang.reflect.Method.invokeNative(Native Method)
05-26 15:48:11.296: E/AndroidRuntime(947): at java.lang.reflect.Method.invoke(Method.java:511)
05-26 15:48:11.296: E/AndroidRuntime(947): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
05-26 15:48:11.296: E/AndroidRuntime(947): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
05-26 15:48:11.296: E/AndroidRuntime(947): at dalvik.system.NativeStart.main(Native Method)
05-26 15:48:11.296: E/AndroidRuntime(947): Caused by: java.lang.NullPointerException
05-26 15:48:11.296: E/AndroidRuntime(947): at info.dremor.kronos.MainActivity.onCreate(MainActivity.java:31)
05-26 15:48:11.296: E/AndroidRuntime(947): at android.app.Activity.performCreate(Activity.java:5008)
05-26 15:48:11.296: E/AndroidRuntime(947): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
05-26 15:48:11.296: E/AndroidRuntime(947): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
05-26 15:48:11.296: E/AndroidRuntime(947): ... 11 more
activity_main.xml :
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="info.dremor.kronos.MainActivity"
tools:ignore="MergeRootFrame" />
fragment_main.xml :
<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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="info.dremor.kronos.MainActivity$PlaceholderFragment" >
<Button
android:id="#+id/connect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="35dp"
android:text="#string/connect" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="35dp"
android:text="#string/login_greeting" />
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textView1"
android:layout_centerHorizontal="true"
android:layout_marginTop="35dp"
android:text="#string/login" />
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textView3"
android:layout_centerHorizontal="true"
android:layout_marginTop="35dp"
android:ems="10" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/editText1"
android:layout_centerHorizontal="true"
android:layout_marginTop="35dp"
android:text="#string/password" />
<EditText
android:id="#+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/editText1"
android:layout_below="#+id/textView2"
android:layout_marginTop="35dp"
android:ems="10"
android:inputType="textPassword" />
</RelativeLayout>
Can someone help me?
In your activity, you set the layout file like this:
setContentView(R.layout.activity_main);
This means, when you write findViewById, it will look within the activity_main.xml file.
Your button on the other hand is within another layout file.
Just move the click event into your fragment, and access the context using getActivity like so:
final Button loginButton = (Button) rootView.findViewById(R.id.connect);
loginButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), LoginDisplayActivity.class);
startActivity(intent);
}
});
your button is in the fragment layout, you're "finding" it from the activity layout. Setup button onclick in the fragment onCreateView
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
final Button loginButton = (Button) rootView.findViewById(R.id.connect);
loginButton.setOnClickListener(new OnClickListener(){...})
return rootView;
}
Remove the button and code from onCreate and shift the button and clicklistener code to onCreateView like this:
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
final Button loginButton = (Button) rootView.findViewById(R.id.connect);
loginButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, LoginDisplayActivity.class);
startActivity(intent);
}
});
return rootView;
As your button is in fragment_main, not activity_main. The button is not found.

Android My First App Tutorial android:onClick issues

I am currently trying to get the basic My First App tutorial of Android (created by google) to work, but I'm having some issues. Currently how the app is made no errors show up in Eclipse, but when I run the app and click the Send button, the app crashes displaying Unfortunately, My First App has stopped.
Looking in the Log cat for the error it states that
java.lang.IllegalStateException: Could not find a method sendMessage(View)
in the activity class com.example.myfirstapp.MainActivity for onClick handler
on view class android.widget.Button.
sendMessage does exist in the MainActivity class, but it is a nested class inside a function PlaceholderFragment. Originally I thought that this was an indexing error so I tried calling sendMessage like a nested class android:onClick="PlaceholderFragment.sendMessage" with no success. I have included the fragment_main and MainActivity class as well as my full logcat error. Thanks for any help.
MainActivity:
package com.example.myfirstapp;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
public class MainActivity extends ActionBarActivity {
public final static String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
/** Called when the user clicks the Send button */
public void sendMessage(View view) {
Intent intent = new Intent(getActivity(), DisplayMessageActivity.class);
EditText editText = (EditText)getActivity(). findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
}
}
Fragment Main:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="horizontal">
<EditText android:id="#+id/edit_message"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="#string/edit_message" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_send"
android:onClick="sendMessage" />
</LinearLayout>
LogCat:
04-25 12:04:07.220: D/(1274): HostConnection::get() New Host Connection established 0xb8e4f238, tid 1274
04-25 12:04:07.330: W/EGL_emulation(1274): eglSurfaceAttrib not implemented
04-25 12:04:07.340: D/OpenGLRenderer(1274): Enabling debug mode 0
04-25 12:04:10.620: D/AndroidRuntime(1274): Shutting down VM
04-25 12:04:10.620: W/dalvikvm(1274): threadid=1: thread exiting with uncaught exception (group=0xb2a6bba8)
04-25 12:04:10.750: E/AndroidRuntime(1274): FATAL EXCEPTION: main
04-25 12:04:10.750: E/AndroidRuntime(1274): Process: com.example.myfirstapp, PID: 1274
04-25 12:04:10.750: E/AndroidRuntime(1274): java.lang.IllegalStateException: Could not find a method sendMessage(View) in the activity class com.example.myfirstapp.MainActivity for onClick handler on view class android.widget.Button
04-25 12:04:10.750: E/AndroidRuntime(1274): at android.view.View$1.onClick(View.java:3810)
04-25 12:04:10.750: E/AndroidRuntime(1274): at android.view.View.performClick(View.java:4438)
04-25 12:04:10.750: E/AndroidRuntime(1274): at android.view.View$PerformClick.run(View.java:18422)
04-25 12:04:10.750: E/AndroidRuntime(1274): at android.os.Handler.handleCallback(Handler.java:733)
04-25 12:04:10.750: E/AndroidRuntime(1274): at android.os.Handler.dispatchMessage(Handler.java:95)
04-25 12:04:10.750: E/AndroidRuntime(1274): at android.os.Looper.loop(Looper.java:136)
04-25 12:04:10.750: E/AndroidRuntime(1274): at android.app.ActivityThread.main(ActivityThread.java:5017)
04-25 12:04:10.750: E/AndroidRuntime(1274): at java.lang.reflect.Method.invokeNative(Native Method)
04-25 12:04:10.750: E/AndroidRuntime(1274): at java.lang.reflect.Method.invoke(Method.java:515)
04-25 12:04:10.750: E/AndroidRuntime(1274): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
04-25 12:04:10.750: E/AndroidRuntime(1274): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
04-25 12:04:10.750: E/AndroidRuntime(1274): at dalvik.system.NativeStart.main(Native Method)
04-25 12:04:10.750: E/AndroidRuntime(1274): Caused by: java.lang.NoSuchMethodException: sendMessage [class android.view.View]
04-25 12:04:10.750: E/AndroidRuntime(1274): at java.lang.Class.getConstructorOrMethod(Class.java:472)
04-25 12:04:10.750: E/AndroidRuntime(1274): at java.lang.Class.getMethod(Class.java:857)
04-25 12:04:10.750: E/AndroidRuntime(1274): at android.view.View$1.onClick(View.java:3803)
04-25 12:04:10.750: E/AndroidRuntime(1274): ... 11 more
04-25 12:04:12.720: I/Process(1274): Sending signal. PID: 1274 SIG: 9
It looks like your problem is that the sendMessage function should be included in your MainActivity instead of nested in your fragment.
The debug line:
java.lang.IllegalStateException: Could not find a method sendMessage(View) in the activity class com.example.myfirstapp.MainActivity for onClick handler on view class android.widget.Button
shows that the application is looking in your MainActivity class for this method.
place sendMessage(View view) method inside MainActivity class instead of PlaceholderFragment class
Handling clicklistener from xml is not always a good idea. Set a clicklistener in the fragment for the button and call sendMessage method from onClick method of clicklistener.
First set a ID for your button (Example : sendButton).
Then,
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
Button b = (Button) rootView.findViewByID(R.id.sendButton);
//Here set the clickListener and call sendMessage method
return rootView;
}
/** Called when the user clicks the Send button */
public void sendMessage(View view) {
Intent intent = new Intent(getActivity(), DisplayMessageActivity.class);
EditText editText = (EditText)getActivity(). findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
}
Or implement View.OnClickListener in the fragment then have a case statement like:
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.sendButton:
sendMessage();
break;
default:
Log.i(TAG, "Unknown: " + view.getId());
break;
}
}
Do it programmatically:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
Button b = (Button) rootView.findViewById(R.id.my_button);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// handle click here
}
});
return rootView;
}
and insert this into Button section in your main activity layout:
android:id="#+id/my_button"
android:onClick="sendMessage"
button onClick attribute search the corresponding method in the Activity. but you define that method in the Fragment that's why you get the exception
method could not find exception.
Android Recommended way to do handle the onClick for button inside the fragment is
First Assign id to Button
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="horizontal">
<EditText android:id="#+id/edit_message"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="#string/edit_message" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_send"
/>
</LinearLayout>
your Fragment then register the button with onClick listener
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment implements OnItemClickListener{
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
Button b = (Button) rootView.findViewById(R.id.button1);
b.setOnClickListener(this);
return rootView;
}
/** Called when the user clicks the Send button */
public void sendMessage(View view) {
Intent intent = new Intent(getActivity(), DisplayMessageActivity.class);
EditText editText = (EditText)getActivity(). findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
public void onClick(View view)
{
sendMessage(view);
}
}

I have just written my first android app, and after 3 hours it still doesn't work

I have just started writing my first piece of code in an android app, however when I run it with the following section uncommented it crashes (anything else I tell you would be a useless guess):
public void onButton1Click(View v){
if(v.getId() == R.id.button1){
StringBuilder str = new StringBuilder("");
if (pepBox.isChecked()) {
str.append("Pepperoni"+" ");
}
if (cheeseBox.isChecked()) {
str.append("Extra Cheese");
}
if (str.length() == 0) {
str.append("Plain");
}
textView.setText(str);
}
}
With the following error log:
04-07 17:45:30.897: E/AndroidRuntime(15210): FATAL EXCEPTION: main
04-07 17:45:30.897: E/AndroidRuntime(15210): Process: com.ollieapps.helloworld, PID: 15210
04-07 17:45:30.897: E/AndroidRuntime(15210): java.lang.IllegalStateException: Could not execute method of the activity
04-07 17:45:30.897: E/AndroidRuntime(15210): at android.view.View$1.onClick(View.java:3823)
04-07 17:45:30.897: E/AndroidRuntime(15210): at android.view.View.performClick(View.java:4438)
04-07 17:45:30.897: E/AndroidRuntime(15210): at android.view.View$PerformClick.run(View.java:18422)
04-07 17:45:30.897: E/AndroidRuntime(15210): at android.os.Handler.handleCallback(Handler.java:733)
04-07 17:45:30.897: E/AndroidRuntime(15210): at android.os.Handler.dispatchMessage(Handler.java:95)
04-07 17:45:30.897: E/AndroidRuntime(15210): at android.os.Looper.loop(Looper.java:136)
04-07 17:45:30.897: E/AndroidRuntime(15210): at android.app.ActivityThread.main(ActivityThread.java:5017)
04-07 17:45:30.897: E/AndroidRuntime(15210): at java.lang.reflect.Method.invoke(Native Method)
04-07 17:45:30.897: E/AndroidRuntime(15210): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
04-07 17:45:30.897: E/AndroidRuntime(15210): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
04-07 17:45:30.897: E/AndroidRuntime(15210): Caused by: java.lang.reflect.InvocationTargetException
04-07 17:45:30.897: E/AndroidRuntime(15210): at java.lang.reflect.Method.invoke(Native Method)
04-07 17:45:30.897: E/AndroidRuntime(15210): at android.view.View$1.onClick(View.java:3818)
04-07 17:45:30.897: E/AndroidRuntime(15210): ... 9 more
04-07 17:45:30.897: E/AndroidRuntime(15210): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.widget.CheckBox.isChecked()' on a null object reference
04-07 17:45:30.897: E/AndroidRuntime(15210): at com.ollieapps.helloworld.MainActivity.onButton1Click(MainActivity.java:59)
04-07 17:45:30.897: E/AndroidRuntime(15210): ... 11 more
I'm sorry if I have included to much or too little, this is my first question, also I have already searched for 3 hours.
Full Code:
package com.ollieapps.helloworld;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.TextView;
public class MainActivity extends ActionBarActivity {
TextView textView; CheckBox pepBox, cheeseBox;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pepBox = (CheckBox) findViewById(R.id.checkBox1);
cheeseBox = (CheckBox) findViewById(R.id.checkBox2);
textView = (TextView) findViewById(R.id.textView1);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void onButton1Click(View v){
if(v.getId() == R.id.button1){
StringBuilder str = new StringBuilder("");
if (pepBox.isChecked()) {
str.append("Pepperoni"+" ");
}
if (cheeseBox.isChecked()) {
str.append("Extra Cheese");
}
if (str.length() == 0) {
str.append("Plain");
}
textView.setText(str);
}
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
}
}
xml:
fragment:
<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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.ollieapps.helloworld.MainActivity$PlaceholderFragment" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:orientation="vertical" >
<CheckBox
android:id="#+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pepperoni" />
<CheckBox
android:id="#+id/checkBox2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ExtraCheese" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onButton1Click"
android:text="Show" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Plain" />
</LinearLayout>
</RelativeLayout>
Main:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.ollieapps.helloworld.MainActivity"
tools:ignore="MergeRootFrame" />
It seems you built your views inside fragment_main.xml and not activity_main.xml.
When you first create a new android project, you have these files which are automatically created and opened:
Then, when you begin, you add views (e.g: a TextView) inside fragment_main.xml file. Finally, you tried to do a basically event with this view inside your Activity, something like this:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); // Using layout activity_main.xml
// You try to set a simple text on the view (TextView) previously added
TextView text = (TextView) findViewById(R.id.textView1);
text.setText("Simple Text"); // And you get an error here!
/*
* You do an fragment transaction to add PlaceholderFragment Fragment
* on screen - this below snippnet is automatically created.
*/
if(savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
You cannot run your app or sometimes you have only a white screen, because the views that you tried to call/display are into the wrong layout..
Solution: Move all your stuff inside onCreateView method into the Fragment class.
As DoctororDrive said in his comment
Call views and do something in the related fragment and not the parent activity.
For example, in your case, these following lines:
pepBox = (CheckBox) findViewById(R.id.checkBox1);
cheeseBox = (CheckBox) findViewById(R.id.checkBox2);
textView = (TextView) findViewById(R.id.textView1);
might be inside your fragment because you created it in fragment_main.xml layout. Then:
// start fragment
public static class PlaceholderFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Use the layout which is displayed it's fragment_main.xml
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
// Find your views here!
// Don't forget to findViewById attached to the inflated view "rootView.findView..."
pepBox = (CheckBox) rootView.findViewById(R.id.checkBox1);
cheeseBox = (CheckBox) rootView.findViewById(R.id.checkBox2);
textView = (TextView) rootView.findViewById(R.id.textView1);
/*
* Do something here: click listener, set a text, check a box..
*/
return rootView;
}
/*
* Perform other methods still inside the fragment
*/
public void onButton1Click(View v){
if(v.getId() == R.id.button1){
StringBuilder str = new StringBuilder("");
if (pepBox.isChecked()) {
str.append("Pepperoni"+" ");
}
if (cheeseBox.isChecked()) {
str.append("Extra Cheese");
}
if (str.length() == 0) {
str.append("Plain");
}
textView.setText(str);
}
}
}
// end fragment
if (pepBox.isChecked()) {
This line of code is failing with a NullPointerException because pepBox was declared but it's not being initialized as it should (and is therefore null at this point in the code).
Here is its declaration line:
TextView textView; CheckBox pepBox, cheeseBox;
And here is its initialization:
pepBox = (CheckBox) findViewById(R.id.checkBox1);
The problem is that (a) this line is not be called, or (b) findViewById(R.id.checkBox1) is returning null.
If findViewByID is returning null then you probably want to refer to this question, which addresses exactly this issue. Its "related questions", down the right-hand side, should also be helpful.

android getViewById() NullPointerException

I'm trying to make my app changes its layout when user rotate the screen.
When i launch the app while the screen of virtual machines is in portrait position.
The app is ok when launch but when I rotate the screen to landscape, the app will stops and the logCat shows a nullPointerException at line 40
line 39 btn=(Button)findViewById(R.id.btn);
line 40 btn.setOnClickListener(btnListener);
I think the findViewById() method is returning null, but i dont know why.
Also, if i launch the app while screen in landscape position, the same error occured.
SOLVED: the problem might be the arrangement of nested if, add braces for every if and else-if do solve this problem
Here are the codes:
MainActivity.java
package com.example.test;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
SharedPreferences preference;
Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
preference = getSharedPreferences("preferences", MODE_PRIVATE);
if(getResources().getConfiguration().orientation == 1)
if(preference.getInt("THE_CHECKED", 0) == 0)
setContentView(R.layout.portrait_black);
else if(preference.getInt("THE_CHECKED", 0) == 1)
setContentView(R.layout.portrait_white);
else if(getResources().getConfiguration().orientation == 2)
if(preference.getInt("THE_CHECKED", 0) == 0)
setContentView(R.layout.landscape_black);
else if(preference.getInt("THE_CHECKED", 0) == 1)
setContentView(R.layout.landscape_white);
btn=(Button)findViewById(R.id.btn);
btn.setOnClickListener(btnListener);
}
private Button.OnClickListener btnListener = new Button.OnClickListener()
{
public void onClick(View v)
{
Toast toast1 = Toast.makeText(MainActivity.this, "HI", Toast.LENGTH_LONG);
toast1.show();
}
};
private DialogInterface.OnClickListener theDialogListener = new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
SharedPreferences.Editor editor = preference.edit();
switch(which)
{
case 0: //Black
editor.putInt("THE_CHECKED", 0);
break;
case 1: //White
editor.putInt("THE_CHECKED", 1);
break;
}
editor.commit();
((Dialog)dialog).dismiss();
onCreate(new Bundle());
}
};
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
SharedPreferences.Editor editor = preference.edit();
switch (item.getItemId())
{
case R.id.theme:
Builder theDialog = new AlertDialog.Builder(this);
theDialog.setTitle("Theme");
theDialog.setSingleChoiceItems(R.array.theme_menu, preference.getInt("THE_CHECKED", 0), theDialogListener);
theDialog.show();
break;
}
editor.commit();
return super.onOptionsItemSelected(item);
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
onCreate(new Bundle());
}
}
Layouts
portrait_white.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LinearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:orientation="vertical" >
<Button
android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="portrait"
android:textSize="30sp"
android:textColor="#000000" />
</LinearLayout>
portrait_black.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LinearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:orientation="vertical" >
<Button
android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="portrait"
android:textSize="30sp"
android:textColor="#000000" />
</LinearLayout>
landscape_white.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LinearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:orientation="vertical" >
<Button
android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="landscape"
android:textSize="30sp"
android:textColor="#000000" />
</LinearLayout>
landscape_black.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LinearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:orientation="vertical" >
<Button
android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="landscape"
android:textSize="30sp"
android:textColor="#000000" />
</LinearLayout>
LogCat(when i launch the app while screen is in landscape position)
02-21 01:26:53.895: D/AndroidRuntime(1836): Shutting down VM
02-21 01:26:53.925: W/dalvikvm(1836): threadid=1: thread exiting with uncaught exception (group=0x41465700)
02-21 01:26:53.935: E/AndroidRuntime(1836): FATAL EXCEPTION: main
02-21 01:26:53.935: E/AndroidRuntime(1836): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.test/com.example.test.MainActivity}: java.lang.NullPointerException
02-21 01:26:53.935: E/AndroidRuntime(1836): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
02-21 01:26:53.935: E/AndroidRuntime(1836): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
02-21 01:26:53.935: E/AndroidRuntime(1836): at android.app.ActivityThread.access$600(ActivityThread.java:141)
02-21 01:26:53.935: E/AndroidRuntime(1836): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
02-21 01:26:53.935: E/AndroidRuntime(1836): at android.os.Handler.dispatchMessage(Handler.java:99)
02-21 01:26:53.935: E/AndroidRuntime(1836): at android.os.Looper.loop(Looper.java:137)
02-21 01:26:53.935: E/AndroidRuntime(1836): at android.app.ActivityThread.main(ActivityThread.java:5103)
02-21 01:26:53.935: E/AndroidRuntime(1836): at java.lang.reflect.Method.invokeNative(Native Method)
02-21 01:26:53.935: E/AndroidRuntime(1836): at java.lang.reflect.Method.invoke(Method.java:525)
02-21 01:26:53.935: E/AndroidRuntime(1836): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
02-21 01:26:53.935: E/AndroidRuntime(1836): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
02-21 01:26:53.935: E/AndroidRuntime(1836): at dalvik.system.NativeStart.main(Native Method)
02-21 01:26:53.935: E/AndroidRuntime(1836): Caused by: java.lang.NullPointerException
02-21 01:26:53.935: E/AndroidRuntime(1836): at com.example.test.MainActivity.onCreate(MainActivity.java:40)
02-21 01:26:53.935: E/AndroidRuntime(1836): at android.app.Activity.performCreate(Activity.java:5133)
02-21 01:26:53.935: E/AndroidRuntime(1836): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
02-21 01:26:53.935: E/AndroidRuntime(1836): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
02-21 01:26:53.935: E/AndroidRuntime(1836): ... 11 more
Thanks.
You don't have setContentView() in your Activity, hence, there's actually no View referenced to your activity and no views to find using findViewById() method, make sure the setContentView() was actually called...
Regards!
Use it this way. You have written nested if else and the second condition will never be executed in landscape mode i.e. orientation==2
package com.example.test;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
SharedPreferences preference;
Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
preference = getSharedPreferences("preferences", MODE_PRIVATE);
if(getResources().getConfiguration().orientation == 1)
{
if(preference.getInt("THE_CHECKED", 0) == 0)
setContentView(R.layout.portrait_black);
else if(preference.getInt("THE_CHECKED", 0) == 1)
setContentView(R.layout.portrait_white);
}
else if(getResources().getConfiguration().orientation == 2)
if(preference.getInt("THE_CHECKED", 0) == 0)
setContentView(R.layout.landscape_black);
else if(preference.getInt("THE_CHECKED", 0) == 1)
setContentView(R.layout.landscape_white);
btn=(Button)findViewById(R.id.btn);
btn.setOnClickListener(btnListener);
}
private Button.OnClickListener btnListener = new Button.OnClickListener()
{
public void onClick(View v)
{
Toast toast1 = Toast.makeText(MainActivity.this, "HI", Toast.LENGTH_LONG);
toast1.show();
}
};
private DialogInterface.OnClickListener theDialogListener = new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
SharedPreferences.Editor editor = preference.edit();
switch(which)
{
case 0: //Black
editor.putInt("THE_CHECKED", 0);
break;
case 1: //White
editor.putInt("THE_CHECKED", 1);
break;
}
editor.commit();
((Dialog)dialog).dismiss();
onCreate(new Bundle());
}
};
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
SharedPreferences.Editor editor = preference.edit();
switch (item.getItemId())
{
case R.id.theme:
Builder theDialog = new AlertDialog.Builder(this);
theDialog.setTitle("Theme");
theDialog.setSingleChoiceItems(R.array.theme_menu, preference.getInt("THE_CHECKED", 0), theDialogListener);
theDialog.show();
break;
}
editor.commit();
return super.onOptionsItemSelected(item);
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
onCreate(new Bundle());
}
}
Could you print the getResources().getConfiguration().orientation, I think it may be others values than 1 and 2
Infact, we have 4 value of getResources().getConfiguration().orientation: Configuration.ORIENTATION_PORTRAIT = 1, Configuration.ORIENTATION_LANDSCAPE =2, Configuration.ORIENTATION_SQUARE =3, Configuration.ORIENTATION_UNDEFINED =0

How do I make the back button I created in the activity change the text in the textView to the previous text created by the random generator?

When I start the activity on my phone, it says that the app is not responding. The problem is the back button which I can't seem to program to make it gather the previous text from the textView.
Xml code for activity
<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:background="#drawable/background"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".Author" >
<TextView
android:id="#+id/textView1"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:background="#drawable/button_shape"
android:text="#string/Getstarted"
android:textColor="#FFFFFF"
android:textSize="23sp" />
<ImageButton
android:id="#+id/next"
android:layout_width="90dp"
android:layout_height="50dp"
android:layout_alignRight="#+id/textView1"
android:layout_below="#+id/textView1"
android:layout_marginTop="14dp"
android:background="#drawable/button_shape"
android:contentDescription="#string/Next"
android:onClick="NextQuote"
android:src="#drawable/navigationnextitem" />
<ImageButton
android:id="#+id/share"
android:layout_width="90dp"
android:layout_height="50dp"
android:layout_alignTop="#+id/next"
android:layout_centerHorizontal="true"
android:background="#drawable/button_shape"
android:contentDescription="#string/share"
android:onClick="Sharing"
android:src="#drawable/socialshare" />
<ImageButton
android:id="#+id/back"
android:layout_width="90dp"
android:layout_height="50dp"
android:layout_alignLeft="#+id/textView1"
android:layout_alignTop="#+id/next"
android:background="#drawable/button_shape"
android:contentDescription="#string/Back"
android:onClick="PreviousQuote"
android:src="#drawable/navigationpreviousitem" />
</RelativeLayout>
Java code for activity
package com.android.motivateme3;
import java.util.Random;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
import android.support.v4.app.NavUtils;
import android.annotation.TargetApi;
import android.content.Intent;
import android.os.Build;
public class Author extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_author);
// Show the Up button in the action bar.
setupActionBar();
}
/**
* Set up the {#link android.app.ActionBar}, if the API is available.
*/
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setupActionBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
getActionBar().setDisplayHomeAsUpEnabled(true);
Button NextQuote = (Button)findViewById(R.id.next);
final TextView display = (TextView) findViewById(R.id.textView1);
NextQuote.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
Random numGen = new Random();
int rNumber = numGen.nextInt(10);
if (rNumber == 0)
{
display.setText(R.string.Author1);
}
else if (rNumber == 1)
{
display.setText(R.string.Author2);
}
else if (rNumber == 2)
{
display.setText(R.string.Author3);
}
else if (rNumber == 3)
{
display.setText(R.string.Author4);
}
else if (rNumber == 4)
{
display.setText(R.string.Author5);
}
else if (rNumber == 5)
{
display.setText(R.string.Author6);
}
else if (rNumber == 6)
{
display.setText(R.string.Author7);
}
else if (rNumber == 7)
{
display.setText(R.string.Author8);
}
else if (rNumber == 8)
{
display.setText(R.string.Author9);
}
else if (rNumber == 9)
{
display.setText(R.string.Author10);
} }
});
}
ImageButton Sharing = (ImageButton)findViewById(R.id.share);
Sharing.setOnClickListener(new View.OnClickListener() {
public void onClick(View v){
TextView text = (TextView)findViewById(R.id.textView1);
String quote = text.getText().toString();{
Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
shareIntent.setType("plain/text");
shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "This is a great quote (from the Motivate Me! app)");
shareIntent.putExtra(android.content.Intent.EXTRA_TEXT, quote);
startActivity(Intent.createChooser(shareIntent, "Share via:"));}}});
Button BackQuote = (Button)findViewById(R.id.back);
final TextView display = (TextView) findViewById(R.id.textView1);
BackQuote.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String prev = (String) display.getText();
display.setText(prev);
}
});}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.author, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. Use NavUtils to allow users
// to navigate up one level in the application structure. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
//
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
}
This is the stack trace
04-03 14:29:34.174: E/AndroidRuntime(17383): at android.app.ActivityThread.main(ActivityThread.java:4441)
04-03 14:29:34.174: E/AndroidRuntime(17383): at java.lang.reflect.Method.invokeNative(Native Method)
04-03 14:29:34.174: E/AndroidRuntime(17383): at java.lang.reflect.Method.invoke(Method.java:511)
04-03 14:29:34.174: E/AndroidRuntime(17383): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:823)
04-03 14:29:34.174: E/AndroidRuntime(17383): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:590)
04-03 14:29:34.174: E/AndroidRuntime(17383): at dalvik.system.NativeStart.main(Native Method)
04-03 14:29:34.174: E/AndroidRuntime(17383): Caused by: java.lang.ClassCastException: android.widget.ImageButton cannot be cast to android.widget.Button
04-03 14:29:34.174: E/AndroidRuntime(17383): at com.android.motivateme3.Author.setupActionBar(Author.java:36)
04-03 14:29:34.174: E/AndroidRuntime(17383): at com.android.motivateme3.Author.onCreate(Author.java:25)
04-03 14:29:34.174: E/AndroidRuntime(17383): at android.app.Activity.performCreate(Activity.java:4465)
04-03 14:29:34.174: E/AndroidRuntime(17383): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
04-03 14:29:34.174: E/AndroidRuntime(17383): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1931)
04-03 14:29:34.174: E/AndroidRuntime(17383): ... 11 more
04-03 14:29:41.664: I/Process(17383): Sending signal. PID: 17383 SIG: 9
It seems to me that R.id.next refers to an ImageButton, which cannot be cast into a Button, since it is not a subclass of a Button
Do you happen to see a ClassCastException?
To fix that particular issue, replace:
Button NextQuote = (Button)findViewById(R.id.next);
with
ImageButton NextQuote = (ImageButton)findViewById(R.id.next);

Categories