NullPointerException when calling a private final variable in a method - java

I create private ArrayList<String> values;. values is assigned a value in the onCreate method (final ArrayList<String> values = new ArrayList<String>();). Another method onOptionsItemSelected tries to use values, but then a NullPointerException happens.
The whole class is here, sorry if my explanation was hard to understand. The exception occurs on line 55.
package org.sandholm.max.MCFriendsList;
import java.util.ArrayList;
import android.app.ListActivity;
import android.content.Intent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.os.Bundle;
import android.widget.Button;
import android.widget.ListView;
import android.widget.ArrayAdapter;
public class MCFriendsListActivity extends ListActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listactivity);
final ArrayList<String> values = new ArrayList<String>();
setListAdapter(new ArrayAdapter<String>(this, R.layout.listactivity, values));
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, values);
setListAdapter(adapter);
addUser = (Button) findViewById(R.id.button1);
addUser.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
values.add("vurp0");
adapter.notifyDataSetChanged();
}
});
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
String item = (String) getListAdapter().getItem(position);
Intent i = new Intent(v.getContext(), MCFriendsInfoActivity.class);
i.putExtra("uname", item);
v.getContext().startActivity(i);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.item1:
values.add("vurp0");
adapter.notifyDataSetChanged();
return true;
case R.id.item2:
//showHelp();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private Button addUser;
private ArrayList<String> values;
private ArrayAdapter<String> adapter;
}
Please tell me if you need more information(although I doubt it) and thanks in advance.

On line 23 values is declared as a local variable (different than your instance variable). Instead, change line 66 to private final ArrayList<String> values; and line 23 to values = new ArrayList<String>();
Java allows local variables and instance variables to have the same name. In this case, it uses the local variable for operations so you get no error in onCreate but later the variable is out of scope (and the instance variable still has not been assigned a value).

values which you are using at line no. 55 is an instance variable which you have defined its data type at line no. 66(and you are under impression of using line number 23 reference variable) which by default sets to null. So throwing NullPointerException.

You have two ArrayList values .One of them local which is in oncreate metod.Other one is class level and it never assigned a value.Set class level values.
private Button addUser;
private ArrayList values;
private ArrayAdapter adapter;

Better to say, make your ArrayList a class member. Of course, it's already a class member, instantiate it where it is declared. Replace your line number 66 with the following statement and use it as and when required through out the application.
private final ArrayList<String> values = new ArrayList<String>();
You're declaring the ArrayList twice in your application once as a class member and again as a local variable. In this situation, the local variable enjoys the higher priority than the class member.

Related

AndroidStudio, ArrayList+SearchBar, how to get correct Activity

I am a beginner and I have a project to do for school. So the problem is, that whenever I try to open a new Activity on the Emulator by clicking on the listed entries I get to the activity, so far so good but the problem is because of the search bar, the positions of the entries changes. So as far as you can see in my code, Cyberpunk will always be the first entry and Dark Souls the second. But if I specificaly look for Dark Souls in the searchBar (it will only show up Dark Souls) I am getting Cyberpunk activity as a result since it is on position 1.
(I didn't finish all activities for the other entries yet, trying to fix this issure first)
I've already tried stuff like if, switch etc. but I just get the same result. I would really appreciate any help! :)
Regards
Here is my Code:
package at.fh.joanneum.smartplay;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.SearchView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
public class Searchlist extends AppCompatActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_searchlist);
final ArrayList<String> listGames = new ArrayList<>();
listGames.add("Cyberpunk");
listGames.add("Anno 1800");
listGames.add("Dark Souls 3");
listGames.add("Battlefield V");
listGames.add("Minecraft");
listGames.add("DayZ");
listGames.add("Counter Strike");
final ArrayList<Class> intents = new ArrayList<Class>();
intents.add(Cyberpunk.class);
intents.add(DarkSouls.class);
ListView myListView = (ListView) findViewById(R.id.listview_activity_Searchlist);
final ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
android.R.layout.simple_list_item_1, listGames);
myListView.setAdapter(adapter);
SearchView mySearchView = (SearchView) findViewById(R.id.searchBar);
mySearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String s) {
return false;
}
#Override
public boolean onQueryTextChange(String list) {
adapter.getFilter().filter(list);
return false;
}
});
myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent listIntent = new Intent(getApplicationContext(),
intents.get(position));
startActivity(listIntent);
}
});
}
}
The top item is always the item at first index. Since you filter your adapter you change the order of items and therefore their positions, but you don't account for that when loading the Intent from your Intent List in the itemClick callback. You should either create a complex object that contains the display text and the Intent so when onClick is called, you can retrieve the clicked item and get the Intent from it. Or you can create a mapping of item-id and intent and then use the id-parameter of the click callback to retrieve the correct Intent. I would recommend the first solution.
Create a object like
class GameData{
private String text;
private Intent intent;
public GameData(String text, Intent intent){
this.text = text;
this.intent = intent;
}
public Intent getIntent(){
return intent;
}
public String toString(){
return text;
}
}
and fill your ArrayAdapter with those objects instead of Strings. Once the item is clicked, retrieve the item for the clicked position from the adapter and call its getIntent() method. This will deliver the desired Intent.

Can not retrieve String Values in another Class

I am trying to extract the value of some particular string values in another class converter.java class from MainActivity.java , but it's cannot be shown. No Logs are shown. Even, if I want to get Data from another class spinnerSelects.java It's also no longer shown in some places. Can You please help me?
MainActivity.java code is here:
package com.gazzali.spinitmeow;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener, View.OnClickListener{
Spinner spinnerMainChoice;
Spinner spinnerInputChoice;
Spinner spinnerOutputChoice;
EditText getInputValueID;
Double inputValue;
TextView outputValueTextViewFromConverter;
Button buttonConvert;
String selectedMainChoice;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* ------------ Main code Starts Here ----------------*/
/* Main conversion Type choice with Spinner (Drop Down menu)*/
spinnerMainChoice = findViewById(R.id.spinnerIDMainChoice);
// [IMPORTANT] Set Spinner Click Listener
spinnerMainChoice.setOnItemSelectedListener(this);
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter<CharSequence> adapterMainChoice = ArrayAdapter.createFromResource(this,
R.array.MainChoices_array, android.R.layout.simple_spinner_item);
// Specify the layout to use when the list of choices appears
adapterMainChoice.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
spinnerMainChoice.setAdapter(adapterMainChoice);
/* Input Conversion type choice with Spinner */
spinnerInputChoice = findViewById(R.id.spinnerIDInputChoice);
/* Output Conversion type choice with Spinner */
spinnerOutputChoice = findViewById(R.id.spinnerIDOutputChoice);
/* for input and output fields */
getInputValueID = findViewById(R.id.editTextIDInputValue);
/* ---- Setting Button Properties -----*/
buttonConvert = findViewById(R.id.buttonIDConvert);
buttonConvert.setOnClickListener(this);
/* --- Setting Output TextView field ----*/
outputValueTextViewFromConverter = findViewById(R.id.textViewIDoutputValueToConverter);
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
// An item was selected. retrieve the selected item
selectedMainChoice = parent.getSelectedItem().toString();
Log.i("Selected", selectedMainChoice);
/* Toast.makeText(MainActivity.this, String.valueOf(inputValue), Toast.LENGTH_SHORT).show();*/
/* Implement object of spinnerSelects class*/
spinnerSelects spinnerSelectsInMain = new spinnerSelects(this, spinnerInputChoice, spinnerOutputChoice);
/* the main EVIL '(context) this' in the 2nd parameter, 5 hours wasted, but I learnt many more */
spinnerSelectsInMain.setInputOutputSpinners(selectedMainChoice);
/* calling test for converter class */
/*testOnConverter();*/
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
// Another interface callback
}
public void testOnConverter(){
converter converterInMain = new converter(selectedMainChoice);
}
#Override
public void onClick(View view)
{
String inputValueString = getInputValueID.getText().toString();
inputValue = Double.parseDouble(inputValueString);
/*Toast.makeText(this, String.valueOf(inputValue), Toast.LENGTH_SHORT).show();*/
converter converterInMain = new converter(selectedMainChoice);
double convertedValue = converterInMain.convert(inputValue);
outputValueTextViewFromConverter.setText(String.valueOf(convertedValue));
}
}
converter.java codes here:
package com.gazzali.spinitmeow;
import android.content.Context;
import android.util.Log;
import android.widget.Spinner;
import android.widget.Switch;
import android.widget.Toast;
public class converter {
public String MainChoice, inputChoice, outputChoice;
public converter() {
}
public converter(String selectedMainChoiceFromMain) {
this.MainChoice = selectedMainChoiceFromMain;
/* No Log for Main Choice is Being Shown Here */
Log.i("Main Choice is", MainChoice);
}
public converter(String inputChoiceFromSpinnerSelects, String outputChoiceFromSpinnerSelects){
this.inputChoice = inputChoiceFromSpinnerSelects;
this.outputChoice = outputChoiceFromSpinnerSelects;
/* This Logs Shows But ONLY here */
/* IF I try to show the logs anywhere else in the class, */
/* Either null exception or No Log output */
Log.i("Sub Input Choices are:", inputChoice);
Log.i("Sub Output Choices are:", outputChoice);
}
public double convert(double inputValueForEditTextFieldFromMain)
{
double inputValueInConverter = inputValueForEditTextFieldFromMain;
double outputValueToConverterToMain= 0.00;
/* Here I can't see the Log */
/* Apps Crashes When I press Convert Button*/
Log.i("Sub Input Choices are:", inputChoice);
converterLength converterLengthInConverter = new converterLength();
outputValueToConverterToMain = inputValueInConverter * 22;
/*switch (MainChoice)
{
case "Length":
outputValueToConverterToMain = converterLengthInConverter.convertLength(inputChoice, outputChoice, inputValueInConverter);
break;
}*/
return outputValueToConverterToMain;
}
}
Apps Keeep crashing when I press the convert button.
Locat error shows :
2019-07-21 16:48:33.406 10979-10979/com.gazzali.spinitmeow E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.gazzali.spinitmeow, PID: 10979
java.lang.NullPointerException: println needs a message
at android.util.Log.println_native(Native Method)
at android.util.Log.i(Log.java:166)
at com.gazzali.spinitmeow.converter.convert(converter.java:46)
at com.gazzali.spinitmeow.MainActivity.onClick(MainActivity.java:104)
UPDATE
here's my spinnerSelects class which passes inputChoice and outputChoice parameter to converter class, but still I am geing that weird error.
Although I set the constructor values of converter class by the parameter passed by spinnerSelects , it never sets it values as I can't see inputChoice value inside converter class
package com.gazzali.spinitmeow;
import android.content.Context;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
public class spinnerSelects implements AdapterView.OnItemSelectedListener{
public String inputChoice, outputChoice;
public Spinner spinnerInputChoice, spinnerOutputChoice;
public ArrayAdapter<CharSequence> adapterInputChoice, adapterOutputChoice;
private Context contextInSpinnerSelects;
public Context getContextInSpinnerSelects() {
return contextInSpinnerSelects;
}
public spinnerSelects() {
/* Empty Constructor */
}
public spinnerSelects(Context contextFromMain, Spinner spinnerInputChoiceFromMain, Spinner spinnerOutputChoiceFromMain) {
this.spinnerInputChoice = spinnerInputChoiceFromMain;
this.spinnerOutputChoice = spinnerOutputChoiceFromMain;
this.contextInSpinnerSelects = contextFromMain;
}
/**
*
* #param selectedMainChoice String retrieves Main Conversion spinner's type
*/
public void setInputOutputSpinners(String selectedMainChoice) {
switch (selectedMainChoice)
{
case "Length": {
adapterInputChoice = ArrayAdapter.createFromResource(contextInSpinnerSelects,
R.array.LengthChoices_array, android.R.layout.simple_spinner_item);
adapterOutputChoice = ArrayAdapter.createFromResource(contextInSpinnerSelects,
R.array.LengthChoices_array, android.R.layout.simple_spinner_item);
setInputOutputListenerAndDropDownAndAdapter();
}
break;
case "Temperature": {
adapterInputChoice = ArrayAdapter.createFromResource(contextInSpinnerSelects,
R.array.TemperatureChoices_array, android.R.layout.simple_spinner_item);
adapterOutputChoice = ArrayAdapter.createFromResource(contextInSpinnerSelects,
R.array.TemperatureChoices_array, android.R.layout.simple_spinner_item);
setInputOutputListenerAndDropDownAndAdapter();
}
break;
case "Weight": {
adapterInputChoice = ArrayAdapter.createFromResource(contextInSpinnerSelects,
R.array.WeightChoices_array, android.R.layout.simple_spinner_item);
adapterOutputChoice = ArrayAdapter.createFromResource(contextInSpinnerSelects,
R.array.WeightChoices_array, android.R.layout.simple_spinner_item);
setInputOutputListenerAndDropDownAndAdapter();
}
break;
}
}
private void setInputOutputListenerAndDropDownAndAdapter() {
spinnerInputChoice.setOnItemSelectedListener(this);
spinnerOutputChoice.setOnItemSelectedListener(this);
adapterInputChoice.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerInputChoice.setAdapter(adapterInputChoice);
adapterOutputChoice.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerOutputChoice.setAdapter(adapterOutputChoice);
}
public Spinner getSpinnerInputChoice() {
return spinnerInputChoice;
}
public Spinner getSpinnerOutputChoice() {
return spinnerOutputChoice;
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
inputChoice = spinnerInputChoice.getSelectedItem().toString();
outputChoice = spinnerOutputChoice.getSelectedItem().toString();
converter converterInSpinnerSelects = new converter(inputChoice, outputChoice);
/*converterInSpinnerSelects.setInputOutputChoice(inputChoice, outputChoice);*/
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
}
Your problem might be that inputChoice is never set.
You are creating a new instance of your converter-class with this code:
converter converterInMain = new converter(selectedMainChoice);
this will ONLY run this code in your converter-instance:
public converter(String selectedMainChoiceFromMain) {
this.MainChoice = selectedMainChoiceFromMain;
/* No Log for Main Choice is Being Shown Here */
Log.i("Main Choice is", MainChoice);
}
the second constructor therefore never executes public converter(String inputChoiceFromSpinnerSelects, String outputChoiceFromSpinnerSelects){ what means that you never set inputChoicenor outputChoice in your converter-instance which means that they stay null
Log.i("Sub Input Choices are:", inputChoice); therefore gets a null as inputChoice
But I don't think this is the problem here. It should still work but just output a null into your console. As I remember Log.i() works like this: Log.i(TAG, MESSAGE) so your code should look something like this:
Log.i("CONVERTER", "Sub Input Choices are: " + inputChoice);
UPDATE
Well now you are creating a new instance of convertor in (AdapterView<?> parent, View view, int position, long id) {
converter converterInSpinnerSelects = new converter(inputChoice, outputChoice);
this will NOT update the values of the convertor-instance you create in your onClick(View view)-function.
One way of solving this problem might be to simply put the Strings static:
public static String MainChoice, inputChoice, outputChoice;
But then there is no need for creating a new instance of converter every time... so simply do this then:
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
converter.inputChoice = spinnerInputChoice.getSelectedItem().toString();
converter.outputChoice = spinnerOutputChoice.getSelectedItem().toString();
}

Android Spinner error: getOnItemSelectedListener in AdapterView cannot be applied

I am using a simple spinner to display buy-in values in an integer-array. The error in the Gradle Build says: method getOnItemSelectedListener in class AdapterView<T> cannot be applied to given types. There are no required arguments and the reason for the error is given as: actual and formal arguments lists differ in length where T is a type-variable: T extends Adapter declared in class AdapterView. I am not sure how to resolve the error which appears on (this):
spinner.getOnItemSelectedListener(this);
I would assume that this is correct practice as I am telling the spinner that this activity is responsible for listening to the events on the spinner.
Here is my code:
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
public class HomeActivity extends Activity implements AdapterView.OnItemSelectedListener{
Spinner spinner;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Get the view from home_activity.xml
setContentView(R.layout.home_activity);
// initialize spinner
spinner = (Spinner) findViewById(R.id.buyInSpinner);
ArrayAdapter adapter = ArrayAdapter.createFromResource(this, R.array.buy_in, android.R.layout.simple_spinner_item);
spinner.setAdapter(adapter);
spinner.getOnItemSelectedListener(this);
} // end onCreate method
#Override
public void onItemSelected(AdapterView<?> adapterView, View v, int i, long l)
{
TextView myText = (TextView) v;
Toast.makeText(this, "You Selected "+myText.getText(), Toast.LENGTH_SHORT).show();
} // end onItemSelected method
#Override
public void onNothingSelected(AdapterView<?> adapterView)
{
Toast.makeText(this, "You Must Buy-In To Play", Toast.LENGTH_SHORT).show();
} // end onNothingSelected method
} // end HomeActivity class
Why do you want to get without a variable?
I think in this case you should use spinner.setOnItemSelectedListener(this); instead

Whats wrong with my array and array list java for android

I dont know whats wrong but every time i want to put the string element in 1. class from my class koca android gives me error.
Plese help me cause i dont know what to do...
Thanks for your ansewers
package com.klemenjezakon.koceSLO;
import java.util.ArrayList;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class KocaInter extends ListActivity {
int n = 2;
koca koce[] = new koca[n];
ArrayList<String> kocee = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
inicjalizacijaKoc();
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, kocee));
}
private void inicjalizacijaKoc() {
// TODO Auto-generated method stub
koce[0].ime = "Nekaj";
kocee.add(koce[0].ime);
koce[1].ime="Nekaj";
kocee.add(koce[1].ime);
}
protected void onListItemClick(ListView lv, View v, int position, long id) {
super.onListItemClick(lv, v, position, id);
startActivity(new Intent("android.intent.action.KocaInter"));
}
}
and clas koca:
package com.klemenjezakon.koceSLO;
public class koca {
String ime,visina,odprtost,predel,drustvo,oskrbnik,telefon,gms,telefonPD,email,splet,naslov,kategorija,lezisca,jedilnica,cenik,opis,razgled,zanimivejseTure,prehodDoKoc,vzponiNaVrhove;
}
The koce[] array is initialized to a empty koca array filled with nulls. You first need to create a koca object before you can access or modify its fields.
// Create an instance and store it in the array
koce[0] = new koca();
// Retrieve the instance and set a field
koce[0].ime = "Nekaj";
// Retrieve the field
kocee.add(koce[0].ime);
Although I have to agree with #KKD: first acquire some debugging information and (attempt to) debug it yourself first. Your code should have thrown a NullPointerException where you access koce[0].ime since koce[0] was still null.
you didn't put any value in koce[] array
so koce[0] returns null therefore koce[0].ime rises exception

Getting the position of a list item in Android

So I have this class here:
package phil.droid.game;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;
public class GameList extends GamesTrialActivity
{
private ListView lv1;
protected String Game_names[]={"God of War","FOS RO DAH", "dhwaud"};
private String Game_pics[]={"God of War","God of War II"};
private int pos;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.gamelist);
lv1=(ListView)findViewById(R.id.thegamelist);
lv1.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1 , Game_names));
lv1.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
pos = position;
Intent i = new Intent(GameList.this, game_viewer.class);
startActivity(i);
}
});
}
}
And then this VclassV extends the one ^above^
package phil.droid.game;
import android.os.Bundle;
import android.widget.TextView;
public class game_viewer extends GameList
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.game_template);
TextView game_title = (TextView)findViewById(R.id.GameTitle);
game_title.setText("" + pos);
}
}
The problem is at the moment that the last bit recognizes "pos" as "0" no matter what option I click on. Can someone suggest a way to make it so pos is recognized as the number element that's clicked on in the previous class?
Make pos protected, not private.
What you're trying to do can't work: The newly launched activity will not share the same storage as the parent, even if they inherit. The only way it would be possible is if the value was static, but that's not a good idea either.
What you should do instead is to send the data as part of the intent before starting the activity, e.g.:
intent.putExtra("pos", position);
and then you can pull it out in the new activity with
getIntent().getIntExtra("pos", -1); // -1 is used as default value
Also, game_viewer should most likely be a separate activity, rather than inherit from GameList.

Categories