Null Pointer Exception when using LayoutInflator()? - java

I'm using the LayoutInflator to try and get the user's text to display in a TableLayout (Which is a child of a scrollView) But so far, it just keeps throwing the Null Pointer Exception. All the IDs are working fine, I tried cleaning the project to see if that would help but to no avail, can anyone help me out?
By the way, it tells me the error is in 2 places, reminderListTextView.setText(text); and in inflate("test");
Code:
public class MainActivity extends ActionBarActivity {
private TableLayout reminderTableScrollView;
// TextView and Button added
EditText reminderEditText;
Button addReminderButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
reminderTableScrollView = (TableLayout) findViewById(R.id.reminderTableScrollView);
reminderEditText = (EditText) findViewById(R.id.reminderEditText);
addReminderButton = (Button) findViewById(R.id.enterButton);
addReminderButton.setOnClickListener(reminderClickListener);
}
private OnClickListener reminderClickListener = new Button.OnClickListener() {
#Override
public void onClick(View v) {
if (reminderEditText.getText().toString() == null || reminderEditText.getText().toString() == "") {
Toast.makeText(getApplicationContext(), "Enter reminder", Toast.LENGTH_SHORT).show();
} else {
inflate("Test");
reminderEditText.setText("");
}
}
};
public void inflate(String text) {
LayoutInflater inflator = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View reminder = inflator.inflate(R.layout.reminder_layout, null);
TextView reminderListTextView = (TextView) findViewById(R.id.reminderListTextView);
reminderListTextView.setText(text);
reminderTableScrollView.addView(reminder);
}
#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.menuAdd) {
return true;
}
return super.onOptionsItemSelected(item);
}
}

It's actually in just one place that you get the exception : reminderListTextView.setText(text);, the 2 lines are the trace to tell you that you get the error at reminderListTextView.setText(text); when inflate("test"); is called.
Try reminder.findViewById(...);, you need to use the view in which you inflated the layout to be able to retrieve elements from it.

Try changing your inflate method to this:
public void inflate(String text) {
LayoutInflater inflator = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View reminder = inflator.inflate(R.layout.reminder_layout, null);
TextView reminderListTextView = (TextView)reminder.findViewById(R.id.reminderListTextView);
reminderListTextView.setText(text);
reminderTableScrollView.addView(reminder);
}
Without seeing your reminder_layout, I'm not certain, but I'm guessing the view with id reminderListTextView is in your reminder_layout.xml and not your activity_main.xml

Related

Failed to pass String object from DialogFragment to MainActivity

I've created a DialogFragment [implemented as AlertDialog with OnCreateDialog(Bundle)].
The DialogFragment asks for the user to input a project name (String) via an EditText box, and I'm trying to pass this back to the MainActivity.
In MainActivity, I use a Toast to check if the String has indeed been passed along. This check fails as nothing is passed. However, if I hardcode the String in my DialogFragment, it works. It leads me to suspect that there is a problem with the way I try to locate the EditText object, but I'm not sure what my mistake is.
MainActivity.java
public class MainActivity extends AppCompatActivity implements NewProjectDialog.NewProjectDialogListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//initialize the two on screen buttons
//onclick listeners are attached to activity_main.xml
Button newProject = (Button) findViewById(R.id.new_project);
Button browseProjects = (Button) findViewById(R.id.browse_projects);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void newProject(View view) {
//Open up the DialogFragment that prompts user for the title
DialogFragment newFragment = new NewProjectDialog();
newFragment.show(getFragmentManager(), "New Project Dialog");
}
#Override
public void onDialogOK(String projectTitle) {
//Toast.makeText(MainActivity.this, projectTitle, Toast.LENGTH_SHORT).show();
}
#Override
public void onDialogCancel() {
//user pressed cancel in NewProjectDialog
Toast.makeText(MainActivity.this, "Cancelled", Toast.LENGTH_SHORT).show();
}
public void browseProjects(View view){
Toast.makeText(MainActivity.this, "Browse Projects", Toast.LENGTH_SHORT).show();
}
NewProjectDialog.java
public class NewProjectDialog extends DialogFragment{
/* The activity that creates an instance of this dialog fragment must
* implement this interface in order to receive event callbacks.
* Each method passes the DialogFragment in case the host needs to query it. */
public interface NewProjectDialogListener {
public void onDialogOK(String projectTitle);
public void onDialogCancel();
}
// Use this instance of the interface to deliver action events
NewProjectDialogListener mListener;
// Override the Fragment.onAttach() method to instantiate the NoticeDialogListener
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Verify that the host activity implements the callback interface
try {
// Instantiate the NoticeDialogListener so we can send events to the host
mListener = (NewProjectDialogListener) activity;
} catch (ClassCastException e) {
// The activity doesn't implement the interface, throw exception
throw new ClassCastException(activity.toString()
+ " must implement NoticeDialogListener");
}
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder newProjectDialog = new AlertDialog.Builder(getActivity());
//prevent dialog from closing
setCancelable(false);
//set dialog title
newProjectDialog.setTitle(R.string.new_project_title);
//inflate view so that findViewbyId on the next line works
View view = View.inflate(getActivity(),R.layout.new_project_dialog, null);
//Link tempEdit object to the text-edit box so we can retrieve data from it below upon button click
final EditText tempEdit = (EditText)view.findViewById(R.id.project_title);
//set the view
newProjectDialog.setView(R.layout.new_project_dialog);
//set OK button
newProjectDialog.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//Toast.makeText(getActivity(), tempEdit.getText().toString(), Toast.LENGTH_SHORT).show();
mListener.onDialogOK(tempEdit.getText().toString());
}
});
//set cancel button
newProjectDialog.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mListener.onDialogCancel();
}
});
// Create the AlertDialog object and return it
return newProjectDialog.create();
}
You're right, the problem is your taking an EditText from a different view. Because your layout is being inflated twice.
Try using setView(View) instead of the one with the layout resource id.

I need to use a list Fragment and adapter to pass and update string data in the form of a to-do list

I am a fairly novice android programmer and I need some help in regards to the use of a List fragmnet.
To begin:
I currently have three main components in my simple To-do List application.
The first is a Main activity that impliments a custom method I made that simply updates the arraylist through the array Adapepter I have made within it.
public class ToDoListActivity extends ActionBarActivity implements OnNewItemAddedListener{public void newItemAdded(String newItem)
{
todoItems.add(newItem);
arrayAdapter.notifyDataSetChanged();
}
public ArrayAdapter<String> arrayAdapter;
public ArrayList<String> todoItems;
#Override
protected void onCreate (Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//Inflate the root view
setContentView(R.layout.to_do_list_activity);
//Get references to the fragments
FragmentManager fragmentManager = getFragmentManager();
ToDoListFragment toDoListFragment = (ToDoListFragment)
fragmentManager.findFragmentById(R.id.ToDoListFragment);
//Create the array list of to do items
todoItems = new ArrayList<>();
//Create the array adapter to bind the array to the listView
arrayAdapter = new ArrayAdapter<>(this,
android.R.layout.simple_list_item_1, todoItems);
//Bind the array adapter to the listView
toDoListFragment.setListAdapter(arrayAdapter);
}
#Override
public boolean onCreateOptionsMenu (Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_to_do_list, 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();
//no inspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
I Also have an edit text fragment that handles the input of text that would be the To-do items. The newItem variable that is fed through the onNewItemListner() method is populated using my edit text fragment.
`public class EditTextFragment extends Fragment{
//This variable stores a reference to the parent ToDoListActivity that implements
//this interface.
#Override
public View onCreateView (LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
//set the key listener on the edit text view on the UI. This handles the taps on the
//Edit text box on the UI
//inflate the view from the XML file
View view = inflater.inflate(R.layout.edit_text_fragment, container, false);
//Create the edit text variable where the reference to the UI XML file is
final EditText myEditText = (EditText)view.findViewById(R.id.myEditText);
//Set a key listener on the edit text field
myEditText.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event)
{
if (event.getAction() == KeyEvent.ACTION_DOWN)
{
if ((keyCode == KeyEvent.KEYCODE_DPAD_CENTER) ||
(keyCode == KeyEvent.KEYCODE_ENTER)) {
String newItem = myEditText.getText().toString();
ToDoListActivity onItemAddedListener = new ToDoListActivity();
onItemAddedListener.newItemAdded(newItem);
myEditText.setText("");
return true;
}
}
return false;
}
});
return view;
}
public void onAttach(ToDoListActivity activity)
{
super.onAttach(activity);
}
}`
Finally I have a List fragment.
public class ToDoListFragment extends ListFragment{
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState){
//Inflate the XML UI component for the
View view = inflater.inflate(R.layout.to_do_list_fragment, container, false);
return view;
}
public void onAttach(ToDoListActivity activity)
{
super.onAttach(activity);
}
}
Now the problem I am running into is a null point exception. on the todoitems (arraylist) and the arrayAdapeter. They are for whatever reason not being instantiated. SO I can't pass any strings from my edit text field to them without crashing the app. I need to get them working and I would also like to use the list fragment to do so. Any help would be greatly appriciated. Any more information can be provided if needed.
Thank you.
Probably your edit text fragment have no access to the ArrayList or ArrayAdapter. I can't really tell without seeing its code.
As I see you have your fragments embedded in activity's layout and accessing them by ID.
The fragments are useful if you want to have parts of your UI dynamically loaded/unloaded. If you are planning to have just ListView and edit text on the screen then probably you can do it without fragments. It would be much easier. Just put a regular ListView and EditText in your activity's layout.
Actually the ListFragment is a Fragment that hosts a ListView.

How to replace a null value with a string with an EditText?

I have this app with an EditText and when you click a button it sends the value to the second screen/activity. There is a hint in the EditText upon opening the app, but does that count as not a null value? I currently have an if statement but it isn't working to replace the null value with "friend".
How can i change the code to display "friend" when nothing is typed into the EditText?
public class SecondActivity extends Activity {
public static final String TAG = SecondActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.secondscreen);
Intent intent = getIntent();
String message = intent.getStringExtra("message");
if (message == null) {
message = "Friend";
}
Log.d(TAG, message);
TextView textView = (TextView) findViewById(R.id.button);
textView.append(message);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_second, 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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Welcome to Stackoverflow!
The method getText() returns the content of a TextView as a CharSequence which may be empty but not null. You can check if it's empty by calling myTextView.getText().length == 0.
If a TextVew is empty or filled only by a hint, the char sequence is just empty. Your second activity gets an empty string but never null. Check rather for an empty string than null.
use something like this
Bundle extras = getIntent().getExtras();
if (extras!= null) {
textview.setText(extras.getString("message"));
}else{
textview.setText("Friend");
}
i guess your problem is with the append (you dont have anything to join/add at the textview), first try with a setText(),later in your code, use a append if you want

'this' keyword not working

I created some ImageViews using a for loop and inserted them into a ScrollView.
Then I need to create one more ImageView when on touching the screen.
The this keyword cannot be used for creating an ImageView at the '###' marked position.
I am a beginner.
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ScrollView scroll=new ScrollView(this);
final LinearLayout layout =new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
layout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT));
final LinearLayout.LayoutParams lparams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
lparams.setMargins(0, 10, 0, 10);
lparams.gravity=Gravity.CENTER;
int i;
for(i=0;i<15;i++) {
//here 'this' is working ******************
ImageView imView = new ImageView(this);
imView.setLayoutParams(lparams);
Drawable new_image = getResources().getDrawable(R.drawable.rakthasakshi);
imView.setBackgroundDrawable(new_image);
layout.addView(imView, lparams);
}
scroll.addView(layout);
setContentView(scroll);
scroll.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP){
//but here says 'this' cannot be applied ###############
ImageView imView = new ImageView(this);
imView.setLayoutParams(lparams);
Drawable new_image = getResources().getDrawable(R.drawable.rakthasakshi);
imView.setBackgroundDrawable(new_image);
layout.addView(imView, lparams);
scroll.addView(layout);
setContentView(scroll);
return true;
}
return false;
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Use ImageView imView = new ImageView(MainActivity.this);.
In the first case, this refers to MainActivity already.
However, in the second case, this actually refers to View.OnTouchListener.
Do you realise what this means in your context?
this references an anonymous class of type View.OnTouchListener.
To reference the object of your class MainActivity you have to reference MainActivity.this.
Add a final context which have this and use it.
Example:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ScrollView scroll=new ScrollView(this);
final Context ctx = this;
...
//but here says 'this' cannot be applied ###############
ImageView imView = new ImageView(ctx);
This keyword works well in the parent class, but as you create child classes, you have to use ActivityName.this instead of this.

what to do if backpressed

i have a code to change the text of textview in a layout according to the value of the edittext (et) in the previous layout >> somethig like this
I cannot comment, so i will help you editing. Use SharedPreferences to store the string from the edittext in order to get persistance. Then get the string from the SharedPreferences and do the same thing that you are doing(pass it through the intent)
there is MorningDrsGeneral :
public class MorningDrsGeneral extends ActionBarActivity {
Button button ;
EditText et;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.morningdrs);
et = (EditText) findViewById(R.id.et);
addListenerOnButton1();
}
public void addListenerOnButton1() {
final Context context = this;
button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Intent intent = new Intent(context, bookingKamal.class);
intent.putExtra("fn" , et.getText().toString());
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);
}
}
and there is bookingKamal.java :
public class bookingKamal extends ActionBarActivity {
Button button;
TextView textView3;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.bookingkamal);
textView3 = (TextView) findViewById(R.id.textView3);
String A = textView3.getText().toString();
String N = " ";
if (A.equals(N)){
Intent intent = getIntent();
String texx = intent.getStringExtra("fn");
textView3.setText(texx);
}
}
#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);
}
}
So i have to keep the text in the bookingKamal activity .. it means when i go back from this layout and back to it the text should be the same as previous. And in this code it back to null :/ or
You have two options here:
Save the value into the internal file system so it can still will be loaded after the app has been unloaded
Save the value in the Activity which holds the button to this activity and save the text over there in a variable and when the bookingkamal activity starts, it could be read from somewhere (hint: Intent#putExtra("KEY", "VALUE"))
I am not describing how you should do it because there is enough documentation about it out there and that is not the point of this answer. This should give you an idea how to it.
You can do that by using sharedpreferences.
The above link will help you undderstand how to use it.
To add data to SharedPreferences use
SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit();
editor.putString("text", mSaved.getText().toString());
editor.putInt("selection-start", mSaved.getSelectionStart());
editor.putInt("selection-end", mSaved.getSelectionEnd());
editor.apply();
And to retrieve
SharedPreferences prefs = getPreferences(MODE_PRIVATE);
String restoredText = prefs.getString("text", null);
if (restoredText != null)
{
//mSaved.setText(restoredText, TextView.BufferType.EDITABLE);
int selectionStart = prefs.getInt("selection-start", -1);
int selectionEnd = prefs.getInt("selection-end", -1);
/*if (selectionStart != -1 && selectionEnd != -1)
{
mSaved.setSelection(selectionStart, selectionEnd);
}*/
}
Note : that SharedPreferences will save the value such that, even of you close the application and restart it. The values will still remain. So, make sure you clear the data when you done with it. You can read more about it here at the SharedPreferences docs.

Categories