App crashes if I try going to a specific activity - java

So I am making a simple app. It's just basically making a list of win with a custom list view at the end.
It starts off on the main screen where there are two buttons, one is an "Add" button which takes you to the Add activity. If you push this it'll take you to a page where you type in the name,price, description of the wine and then hit a submit button to the list. The other button on the main screen is a "Go to List" button which just takes you directly to the list activity.
If I go through the Add button, add a wine, and then go to the list, it works fine. I can see the list. It even works if I don't add anything to the list. I can see the empty list activity.
When I push the "Go to List" button on the main screen though, it crashes and says "The application has stopped".
I don't get why I can go through the Add button to get to the list fine, but this button doesn't work at all.
Could I get some help?
Here are the three relevant activities, the AddActivity, the ListActivity, and the MainActivity.
AddActivity:
public class AddActivity extends AppCompatActivity {
EditText editWineName;
EditText editWinePrice;
EditText editWineDescription;
Button btnSubmit;
Button btnGoToList;
String stringWineName;
String stringWinePrice;
String stringWineDescription;
ArrayList<String> listWineName = new ArrayList<>();
ArrayList<String> listPrice = new ArrayList<>();
ArrayList<String> listWineDescription = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add);
setVariables();
btnSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
setVariables();
listWineName.add(stringWineName);
listPrice.add(stringWinePrice);
listWineDescription.add(stringWineDescription);
Toast.makeText(AddActivity.this, stringWineName + " was added to the list.", Toast.LENGTH_SHORT).show();
clearEditText();
}
});
btnGoToList.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intentGoToList = new Intent(AddActivity.this,ListActivity.class);
intentGoToList.putStringArrayListExtra("WINENAME", listWineName);
intentGoToList.putStringArrayListExtra("WINEPRICE", listPrice);
intentGoToList.putStringArrayListExtra("WINEDESCRIPTION", listWineDescription);
startActivity(intentGoToList);
}
});
}
private void setVariables(){
editWineName = (EditText) findViewById(R.id.editName);
editWinePrice = (EditText) findViewById(R.id.editPrice);
editWineDescription = (EditText) findViewById(R.id.editDescription);
btnSubmit = (Button) findViewById(R.id.btnSubmit);
btnGoToList = (Button) findViewById(R.id.btnGoToList);
stringWineName = editWineName.getText().toString();
stringWinePrice = "$" + editWinePrice.getText().toString();
stringWineDescription = editWineDescription.getText().toString();
}
private void clearEditText() {
editWineName.getText().clear();
editWinePrice.getText().clear();
editWineDescription.getText().clear();
}
}
ListActivity:
public class ListActivity extends AppCompatActivity {
ListView wineList;
ArrayAdapter adapter;
Button btnBacktoMain;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
setVariables();
ArrayList<String> listWineName = getIntent().getStringArrayListExtra("WINENAME");
ArrayList<String > listWinePrice = getIntent().getStringArrayListExtra("WINEPRICE");
ArrayList<String> listWineDescription = getIntent().getStringArrayListExtra("WINEDESCRIPTION");
adapter = new CustomAdapter(this, listWineName, listWinePrice, listWineDescription);
wineList.setAdapter(adapter);
btnBacktoMain.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intentBackToMain = new Intent(ListActivity.this,MainActivity.class);
startActivity(intentBackToMain);
}
});
}
private void setVariables (){
btnBacktoMain = (Button) findViewById(R.id.btnBackToMain);
wineList = (ListView) findViewById(R.id.listWine);
}
}
MainActivity:
public class MainActivity extends AppCompatActivity {
Button btnAdd;
Button btnList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setVariables();
btnAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) { //Goes to the add activity
Intent intentAdd = new Intent(MainActivity.this, AddActivity.class);
startActivity(intentAdd);
}
});
btnList.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) { //Goes to the list activity
Intent intentList = new Intent(MainActivity.this, ListActivity.class);
startActivity(intentList);
}
});
}
private void setVariables(){
btnAdd = (Button) findViewById(R.id.btnAddWine);
btnList = (Button) findViewById(R.id.btnViewList);
}
}

Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
at android.widget.ArrayAdapter.getCount(ArrayAdapter.java:344)
at android.widget.ListView.setAdapter(ListView.java:493)
at com.example.jeremy.mywine.ListActivity.onCreate(ListActivity.java:33)
Your crash indicates that the data in the adapter given to the ListView in ListActivity is null. Make it not null. Start at ListActivity.java at line 33 and go backwards to find where you are (or this case are not) initializing the data in the list adapter.
In you case, you are expecting data in your intent. OK, where is your intent set up? In your MainActivity click. Well, there you just launch the activity without passing any data in the intent extras, hence there is nothing to pull out from the intent in ListActivity, hence your crash.
So you need to initialize the data in MainActivity and set it as extras in the Intent you use to launch ListActivity.
Since the ListActivity is expecting this:
ArrayList<String> listWineName = getIntent().getStringArrayListExtra("WINENAME");
ArrayList<String > listWinePrice = getIntent().getStringArrayListExtra("WINEPRICE");
ArrayList<String> listWineDescription = getIntent().getStringArrayListExtra("WINEDESCRIPTION");
You would update your MainActivity to do something like this (where getDescriptions() is a fictitious method you would create to return a list of strings)
btnList.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Goes to the list activity
Intent intentList = new Intent(MainActivity.this, ListActivity.class);
intentList.putExtra("WINENAME", new ArrayList<String>()); // Empty list
intentList.putExtra("WINEPRICE", Arrays.asList("Foo", "Bar")); // Explicit list named items
intentList.putExtra("WINEDESCRIPTION", getDescriptions()); // Get list from private method
startActivity(intentList);
}
});
Also check this post my be useful for learning how to read and understand a crash log.
And check the documentation on how to start activities.
Hope that helps!

Related

How to save checkbox states using simple_list_item_multiple_choice?

I'm doing a grocery list app and i want all the list to be sort by department (Meat, fruit, bakery etc.). I try to do the first list which is the fruit list everything is working i can add item the checkbox is there i can use it no problem. the problem is that when i check items and i press the previous button on the phone and then i click back on the button to access the fruit list the items are not checked anymore.
I use the android.R.layout.simple_list_item_multiple_choice for the checkbox.
I try to use onSaveinstance but i cant get it to work ...i would like to save it without using SQl now my array are save in a file for my list.
I eard about shared preference but i'm not sure its what i'm looking for and i would need some help to understand how to use it.
This is the class that call the activity where the fruit list is displayed with the checkbox:
public class SelectDoActivity extends AppCompatActivity {
/*Set the instance variable*/
private ImageButton btn_FruitList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.activity_select_do);
btn_FruitList = (ImageButton) findViewById (R.id.btn_FruitList);
/*Create the method that call the activity*/
btn_FruitList.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openFruitList_Activity();
}
});
}
public void openFruitList_Activity() {
Intent intent = new Intent (this, FruitList_Activity.class);
startActivity(intent);
}
}
This is the class that display the fruit list with the check mark.
public class FruitList_Activity extends AppCompatActivity {
private ListView fruitsList;
private ArrayAdapter<String> adapterFruit;
private Button btn_Delete;
private Button btn_SelectAll;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.activity_fruit_list_);
fruitsList = findViewById(R.id.list_Fruits);
fruitsList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
btn_Delete = findViewById (R.id.btn_delete);
CreateActivity.itemsFruit = FileHelper.readData(this);
adapterFruit = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_multiple_choice, CreateActivity.itemsFruit);
fruitsList.setAdapter(adapterFruit);
/*button to Remove items*/
btn_Delete.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
SparseBooleanArray checkedItemPositions = fruitsList.getCheckedItemPositions();
int itemCount = fruitsList.getCount();
for(int i=itemCount-1; i >= 0; i--){
if(checkedItemPositions.get(i)){
fruitsList.setItemChecked(i,true);
adapterFruit.remove(CreateActivity.itemsFruit.get(i));
FileHelper.writeData(CreateActivity.itemsFruit, FruitList_Activity.this );
}
}
adapterFruit.notifyDataSetChanged();
}
});
}
}
I've been stuck with this since 2 weeks i would we really like some precious help i'm ne to java and android so thanks for taking the time to explain how to fix this.

Sending data to Listview of another activity

After pressing the button I would like to go to the second activity, enter the data in the second activity and then return to the main activity, but having data in ListView. This is my code:
MainActivity:
public class MainActivity extends AppCompatActivity {
Button button;
ListView listView;
String name;
private static final int REQUEST_CODE = 1;
ArrayAdapter<String> adapter;
ArrayList<String> nameList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = findViewById(R.id.button2);
listView = findViewById(R.id.CarList);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(MainActivity.this, SecondActivity.class);
startActivityForResult(i, REQUEST_CODE);
}
});
nameList = new ArrayList<String>();
nameList.addAll(Arrays.asList(name));
adapter = new ArrayAdapter<String>(this, R.layout.element, nameList);
listView.setAdapter(adapter);
}
protected void onActivityResult(int requestCode, int resultCode, Intent i){
if (resultCode == RESULT_OK && requestCode == REQUEST_CODE) {
name = i.getStringExtra("name");
}
}
}
And this is my SecondActivity:
public class SecondActivity extends AppCompatActivity {
EditText editText;
Button button2;
String name;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
editText = findViewById(R.id.editText);
button2 = findViewById(R.id.button);
}
public void finish() {
Intent i = new Intent();
name = editText.getText().toString();
i.putExtra("name", name);
setResult(RESULT_OK, i);
super.finish();
}
}
What could I change to make the application work? Because now I only get the message that: app has stopped, but I don't receive information about any error.
After pressing the button I would like to go to the second activity, enter the data in the second activity and then return to the main activity, but having data in ListView.
What could I change to make the application work? Because now I only get the message that: app has stopped, but I don't receive information about any error.
This is simply because you've incorrectly thinking that Activity.finish() is always called whenever you close the activity. But it never be called by the Android. Take a look for this Lifecyle picture from Activity-lifecycle concepts:
you can see that only onStop() then onDestroy() is called when activity is closed.
You need to call the finish() method manually to send your intent. Or, the better way, create a method that only build and set the intent for the result. Something like this:
private void prepareResult(String name) {
Intent i = new Intent();
i.putExtra("name", name);
setResult(RESULT_OK, i);
}
then call it whenever you want to close your activity:
String name = editText.getText().toString();
prepareResult(name);
finish();
Or you can override the onBackPressed() to also handing the back pressed, like the following:
#Override
public void onBackPressed() {
Intent i = new Intent();
name = editText.getText().toString();
i.putExtra("name", name);
setResult(RESULT_OK, i);
// The default implementation simply finishes the current activity
// see the documentation.
super.onBackPressed();
}

Starting previous activity with Intent, without creating a new one

I want to have my MainActivity which shows a list of different TextViews.
The second Activity contains an EditText field. When I hit 'Submit' in the second Activity, I want to add the String from EditText to the list of TextViews in MainActivity.
The problem I have is that there is a new MainActivity started each time, so that only the latest Text is shown. I want to go back to my MainActivity and kind of "collect" the texts in there. Here is some code:
The MainActivity:
public class FullTimeline extends AppCompatActivity {
private LinearLayout linLayout;
private FloatingActionButton addEntry;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_full_timeline);
linLayout = (LinearLayout) findViewById(R.id.entriesLinear);
addEntry = (FloatingActionButton) findViewById(R.id.floatingActionButton); //starts the second Activity with the EditText
//Here I want to get the text from my second Activity
Intent intent = getIntent();
String entry = intent.getStringExtra(EntryTextActivity.EXTRA_ENTRY);
linLayout.addView(createNewTextView(entry), 0);
}
public void openEntryActivity(View view){
Intent intent = new Intent(this, EntryTextActivity.class);
startActivity(intent);
}
private TextView createNewTextView(String text) {
final LinearLayout.LayoutParams lparams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
final TextView textView = new TextView(this);
textView.setLayoutParams(lparams);
textView.setText(text);
return textView;
}
}
This is the second Activity with the EditText:
public class EntryTextActivity extends AppCompatActivity {
public static final String EXTRA_ENTRY = "com.xyz.ENTRY";
private Button submitButton;
private EditText editTextEntry;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_entry_text);
submitButton = (Button) findViewById(R.id.submitButton);
submitButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(EntryTextActivity.this, FullTimeline.class);
editTextEntry = (EditText) findViewById(R.id.editTextEntry);
String entryText = editTextEntry.getText().toString();
intent.putExtra(EXTRA_ENTRY, entryText);
startActivity(intent);//this starts a new instance of the MainActivity ?
}
});
}
}
I hope that helps understanding my problem. I could not find any working solutions on here.
You need to use startActivityForResult()
Here's a Nishant's simple explanation on how to work with it:
- https://stackoverflow.com/a/10407371/5648172
Basically, you want to start your EntryTextActivity with startActivityForResult() instead of startActivity().
I haven't tested it but i think that in the case you don't want to use a database, you can set your MainActivity as "singleInstance" in your manifest :
<activity android:name="{your }" android:launchMode= "singleInstance" />
Then you can add the new text in an your MainActivity's onResume
#Override
public void onResume() {
super.onResume();
Intent intent = getIntent();
String entry = intent.getStringExtra(EntryTextActivity.EXTRA_ENTRY);
linLayout.addView(createNewTextView(entry), 0);
}

Trying to get string variables from a seperate class causing app to crash

I have simple page to start up the app that has a spinner,editText, and a button. When the user clicks the button I want the app take the selection of the spinner and text and set them to text views in the new class. I tried using getters but when I try this the app crashes.
First Class:
public class MainActivity extends AppCompatActivity {
String pullerName;
String storeName;
Spinner spinner;
EditText etPuller;
public String getStoreName(){
return storeName;
}
public String getPullerName(){
return pullerName;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
spinner = (Spinner) findViewById(R.id.spinner);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.store_list, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
Button create = (Button) findViewById(R.id.btnCreate);
etPuller = (EditText) findViewById(R.id.editText);
create.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
pullerName = etPuller.getText().toString();
storeName = spinner.getSelectedItem().toString();
Intent i = new Intent(MainActivity.this,MainActivity2.class);
startActivity(i);
}
});
}
}
Second Class:
public class MainActivity2 extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_main);
MainActivity main = new MainActivity();
TextView user = (TextView) findViewById(R.id.tvUser);
TextView store = (TextView) findViewById(R.id.tvStore);
user.setText(main.getPullerName());
store.setText(main.getStoreName());
When this code runs it crashes as soon as i click the button to move to the next activity.
To pass data to a new Activity you need to use Intent.
This is what you need to do:
MainActivity.class:
create.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
pullerName = etPuller.getText().toString();
storeName = spinner.getSelectedItem().toString();
Intent i = new Intent(MainActivity.this,MainActivity2.class);
i.putExtra("puller-name", pullerName);
i.putExtra("store-name", storeName);
startActivity(i);
}
});
In the MainActivity2.class:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_main);
TextView user = (TextView) findViewById(R.id.tvUser);
TextView store = (TextView) findViewById(R.id.tvStore);
Intent intent = getIntent();
if(intent != null){ //I always check this to avoid Exceptions
String pullerName = intent.getStringExtra("puller-name");
String storeName = intent.getStringExtra("store-name");
if(pullerName != null) user.setText(pullerName);
if(storeName != null) store.setText(storeName);
}
}
You was creating a new instance of MainActivity in MainActivity2. So, when you called the getters of this mainActivity will return null, because these values were never setters. If you want to use your method, you need to pass the same instance of the activity to MainActivity2, but this is not recommended. The official method to pass data to another activity is via intent. To learn more about Intent learn the official Android documentation: https://developer.android.com/training/basics/firstapp/starting-activity.html
You have used wrong way to get values from MainActivity to MainActivity2. Simply you can pass values using the technique below.
Intent intent = new Intent(MainActivity.this,MainActivity2.class);
intent.putExtra("pullerName", pullerName);
To use this value pullerName in MainActivity2 class, just use the technique below.
String value = getIntent().getExtras().getString("pullerName");`

Adding items in ListView

I have problems with my list . I had an Activity I get some Data from.
The data must accessed in variables in my class :
Mylist.java class
public String Job,Ship,Location,Shift,Date;
public String workingHour;
Mylist(String job,String loc,String shp,String shft,String dat,String wh){
Job=job;
Location=loc;
Ship=shp;
Shift=shft;
Date=dat;
workingHour=wh;
}
and by pressing Save Button The list must add an item.My problem is when I add another items the list have only one item How to fix this ?
Adding Class :
AddOredit.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_oredit);
final ArrayList<Mylist>list =new ArrayList<>();
final ArrayList<String> Job=new ArrayList<>();
String selecteditem1, selecteditem2,getlocation,getship,getdate,gethours;
Spinner type=(Spinner)findViewById(R.id.s1);
Spinner shift=(Spinner)findViewById(R.id.s2);
EditText location=(EditText)findViewById(R.id.loc);
EditText ship=(EditText)findViewById(R.id.ship);
EditText date=(EditText)findViewById(R.id.date);
EditText workinghours=(EditText)findViewById(R.id.hours);
Button Save = (Button) findViewById(R.id.editbtn);
Button cancel = (Button) findViewById(R.id.cancelbtn);
selecteditem1 = type.getSelectedItem().toString(); //for first spinner
selecteditem2 = shift.getSelectedItem().toString();//for second spinner
getlocation=location.getText().toString();
getship=ship.getText().toString();
getdate=date.getText().toString();
gethours=workinghours.getText().toString();
list.add(new Mylist(selecteditem1,getlocation,getship,selecteditem2,getdate,gethours));
Log.e(TAG, String.valueOf(list.size()));
for(int i=0;i<list.size();i++){
Job.add("Job "+(i+1));
}
//When pressing save Button
Save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//list.add(new Mylist(selecteditem1, getlocation, getship, selecteditem2, getdate, gethours));
Intent intent = new Intent(AddOredit.this, MainActivity.class);
intent.putStringArrayListExtra("MyList", Job);
startActivity(intent);
}
});
}
MainActivity.java this class
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView lv= (ListView) findViewById(R.id.listView);
Button ADD=(Button)findViewById(R.id.addbtn);
Button DELETE=(Button)findViewById(R.id.deletebtn);
Button PROFILE=(Button)findViewById(R.id.profilebtn);
Intent intent=getIntent();
ArrayList<String> Job ;
Job=intent.getStringArrayListExtra("MyList");
if(Job!=null){
ListAdapter adapter= new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, Job);
lv.setAdapter(adapter);
//when user click on add button
}
ADD.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//go to AddOreditpage
Intent i = new Intent(MainActivity.this, AddOredit.class);
startActivity(i);
}
});
**Note :- ** Add Button is for Adding items in the list and Save Button is for saving data entered at AddOredit class.
**Note :- ** By clicking Add Button , getting to the AddOredit Activity .
By Clicking Save Button, getting back to the main activity with the item added
You are assigning a new List for list object on your second activity created. Try to assign the list with an existing object and add your new object.
EDIT:
Try to Declare this globally as,
private static ArrayList list =new ArrayList<>();
and with in onCreate() remove it. Let me know if it still do not work.

Categories