Null PointerException in spinner in android - java

I am working in Android. I want to design a spinner of song categories.
This is my code:
public Spinner spinner_category_forSong;
String[] arr_Category={"Select","sad","dj","rock"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
this,android.R.layout.simple_spinner_item,arr_Category);
spinner_category_forSong = (Spinner)findViewById(R.id.Spinner_category_forUpload);
spinner_category_forSong.setPrompt("Music Category :");
spinner_category_forSong.setAdapter(adapter);
But whenever I run my project, a null pointer exception is created in spinner_category_forSong.setPrompt("Music Category :"); and spinner_category_forSong.setAdapter(adapter);.
Please tell me what mistake I have made in this code.

From your exception it seems that findViewById(R.id.Spinner_category_forUpload) returns null. My guess is that you didn't call setContentView() prior to your method calls.
From the code sample your class structure is not clear. Are some lines inside onCreate()?

try after setting adapter spinner_category_forSong.setAdapter(adapter); before spinner_category_forSong.setPrompt("Music Category :");

Related

Android Runtime error on passing info between activities

I have 2 activities in my assignment: MainActivity and Country_Activity.
I'm trying to pass 2 inputs the user puts in MainActivity:
int counter
String Country
But the app always crashes here: (this is Country_Activity)
private void Update(){
Intent mIntent = getIntent();
int intValue = mIntent.getIntExtra("intCounter", 0);
String country = mIntent.getStringExtra("country");
counterTextView.setText(intValue);
countryTextView.setText(country);
if (country.equals("canada")){
flagView.setImageResource(R.drawable.canada);
}
else if (country.equals("us")){
flagView.setImageResource(R.drawable.us);
}
}
Specifically on the lines "setText" for each variable.
Everything else works. I can't figure out why they wouldn't.
Thanks!
Usually the extras that are passed from one activity to another are read inside on onCreate() where all the needed initialization of variables and views is made.
In your case I see that you get the extras inside another method (maybe it's called inside onCreate()?).
So you forgot to initialize the textviews:
TextView counterTextView = findViewById(R.id.countersomething);
TextView countryTextView = findViewById(R.id.countrysomething);
also another error that you will encounter later is this:
counterTextView.setText(intValue);
change it to:
counterTextView.setText(String.ValueOf(intValue));
Don't pass an integer value inside setText() because it will be treated as the id of a resource.

Android - Open Activity and wait for Result before continue in calling class

I am quite new to Android and facing a problem.
I have a class A from where i would like to call another activity. I have found some post saying that there is no way to pause the calling Activity and wait for the result.
public class A extends AppCompatActivity {
[...]
private List<String> list = new ArrayList<String>();
private void doSomething() {
list.add("a");
list.add("b");
for(String tmp:list) {
Intent intent = new Intent(this, OtherActivity.class);
intent.putStringExtra("TAG", tmp);
startActivityForResult(intent, 1);
}
}
This is not a complete example but basically the problem I am facing.
I have a loop and try to open another activity. The loop does not stop when i start the "OtherActivity".
The first thing i see is the OtherActivity for the last element of the list (here String "b"). When i finish this Activity i see the OtherActivity with String "a" in wrong order.
I considered a callback for this, but i am not sure how to implement it because the callback handler wouldn't be within the loop.
Again I am not sure if a callback would be a good idea because many people say i should not Pause the "calling" activity for the sub activity.
You are doing it totally wrong, if you want to send data to other activity and do some work then get the result , i would prefer that send the whole data as a list , do the work and then get the data from that activity , you shouldn't be doing it in a loop. Either pass it is as intent or save it in database then retrieve from database.
If you want to pass the whole list of string to the other activity I suggest you do this
You can pass an ArrayList the same way, if the E type is
Serializable.
You would call the putExtra (String name, Serializable value) of
Intent to store, and getSerializableExtra (String name) for retrieval.
Example:
ArrayList<String> myList = new ArrayList<String>();
intent.putExtra("mylist", myList);
In the other Activity:
ArrayList<String> myList = (ArrayList<String>) getIntent().getSerializableExtra("mylist");
Please note that serialization can cause performance issues: it takes time, and a lot of objects will be allocated (and thus, have to be garbage collected)
Source: Passing a List from one Activity to another
Or as Abdul suggested, save the data to a database and retrieve it from there in the other activity

Making a TextView visible at runtime in java (Android)

I have two activities; the first activity starts the second one with some data passed through the intent.
Intent i = new Intent(this,BActivity.class);
i.putExtra("identify", "c2f");
startActivityForResult(i, 1);
In the second activity, I want to make some TextViews/EditTexts visible (which are initially set to invisible) based on the information passed from the first activity.
Here's the code for that:
tv1 = (TextView)findViewById(R.id.textView2);
tv2 = (TextView)findViewById(R.id.textView3);
et1 = (EditText)findViewById(R.id.editText1);
et2 = (EditText)findViewById(R.id.editText2);
button = (Button)findViewById(R.id.send_result);
Bundle extras = getIntent().getExtras();
String identifier = extras.getString("identify");
if(identifier == "c2f")
{
tv1.setVisibility(0);
tv1.setText("Celcius");
et1.setVisibility(0);
}
else if(identifier == "f2c")
{
tv1.setVisibility(0);
tv1.setText("Fahrenheit");
et1.setVisibility(0);
}
else if(identifier == "currency")
{
tv1.setVisibility(0);
tv1.setText("Amount");
tv2.setVisibility(0);
tv2.setText("Conv. Rate");
et1.setVisibility(0);
et2.setVisibility(0);
}
Now when the second activity starts, none of these TextViews or EditTexts seem to get visible!
identifier (string) holds the correct value passed from first activity and it even goes into the if conditions, but it doesn't make any view visible.
Am I making any mistake in trying to make these views visible?
Use .equals instead of == to string comparison. You can also use the variable after the quoted string to avoid nullpointer. And you can use TextView.VISIBLE, it's a constant to get it visible.
if("c2f".equals(identifier))
{
tv1.setVisibility(TextView.VISIBLE);
tv1.setText("Celcius");
et1.setVisibility(TextView.VISIBLE);
}
Simply use the View's constants for this.
your_view.setVisibility(View.VISIBLE);
This will make your View visible.
your_view.setVisibility(View.INVISIBLE);
This will make it invisible but still with the layout visible (basically, the space where it goes remains untouched)
your_view.setVisibility(View.GONE);
This will make your View disappear, like it never existed!
As pointed by giacomoni, please use equals for String comparison. Here is a link to explain why.
http://javarevisited.blogspot.in/2012/03/how-to-compare-two-string-in-java.html
Also, try using the standard View.VISIBLE etc constants for showing and hiding views. They are much more easy to use and understand. Happy coding. :)

Android - Refresh data in an AlertDialog?

So, if I create an AlertDialog like so:
AlertDialog.Builder b = new AlertDialog.Builder();
b.setItems(MyStringArray, MyListener);
b.create().show();
And then I want to update the items in the list, i.e. MyStringArray has changed to have more or fewer items. I can't seem to find a way to do this. So far, I've tried getting the ListView from the AlertDialog, but I can't seem to get .setAdapter to work. Is this the right approach, or is there a better way to do this?
I haven't tried this out myself, but from all the other apps I've built I'm pretty sure this will solve your problem.
Instead of using setItems, try using the setAdapter() method and pass in an ArrayAdapter that has been initialized with the data from your Array of String. Then, when you know that the data has changed, you can use getListView() to get your View object and from there call getAdapter() so that now you're working directly with the dataset. You can clear it, and re-initialize it if you like, or just add / remove the items as you like. From the adapter object, if you call notifyDataSetChanged() it should trigger a re-draw using the new data set that you just supplied to the adapter.
Hope that helps you out. Let me know if it doesn't.
DSC
If you are like me and you would like to use default adapter for example for multichoice items, then there is also a way.
Just as with any other adapter just update the string array object, get adapter from the dialog instance, cast it to appropriate adapter and invalidate it.
AlertDialog.Builder b = new AlertDialog.Builder();
b.setItems(MyStringArray, MyListener);
AlertDialog instance = b.create();
instance.show();
// Later when you need to update
MyStringArray[0] = "puf";
ListView list = instance.getListView();
// Now according to whether you used cursor or array for supplying items to the builder
// you have to cast adapter to either CursorAdapter or ArrayAdapter
ArrayAdapter adapter = (ArrayAdapter)list.getAdapter();
adapter.notifyDataSetChanged();
You can find out more here.
This is how I did it in Kotlin:
AlertDialog.Builder(context).apply {
val actions = arrayListOf("aa", "bb")
val onItemClickListener = DialogInterface.OnClickListener { dialog, which ->
// code
}
val adapter = ArrayAdapter(requireContext(),
android.R.layout.simple_list_item_1, actions)
setAdapter(adapter, onItemClickListener)
executeGetRequest() {
actions.add("cc")
adapter.notifyDataSetChanged()
}
}.show()

Binding data from a Cursor to a Spinner Android

I am trying to populate a Spinner in an Android dialog. When the user clicks a button, a dialog pops up and I load the layout from an XML file. Now I am trying to populate that Spinner from a SQL query. I have searched all over and cannot figure out what the problem is. I can loop through the Cursor and add each value to an ArrayAdapter and then use that as the list for the spinner but that doesn't come with the _id's from the database. I have done this before using a SimpleCursorAdapter and I have even copied and pasted my old code exactly and still it isn't working. Any help would be much appreciated.
My Dialog code:
private void displayNewInteractionDialog() {
final Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.mm_new_dialog);
dialog.setTitle(R.string.mm_new_dialog_title);
dialog.setCancelable(true);
final Spinner spinner = (Spinner) dialog.findViewById(R.id.mm_spinner);
DatabaseInterface db = new DatabaseInterface(this);
db.open();
Cursor c = db.getNames();
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_spinner_item,
c,
new String[] {DatabaseInterface.KEY_ID, DatabaseInterface.KEY_NAME},
new int[] {android.R.id.text1});
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
c.close();
db.close();
dialog.show();
}
Here is the code that returns a Cursor in my DatabaseInterface class:
public Cursor getNames() {
return db.query(DATABASE_TABLE_4, new String[] {DatabaseInterface.KEY_ID, DatabaseInterface.KEY_NAME}, null, null, null, null, null);
}
I know this will work I am just missing something apparently. I know that I could load the Spinner with the list of names from the ArrayAdapter that I stated above and also populate an array with the ID's from the query and when the user selects an item I could just grab the corresponding one from the array of ID's... But I know the SimpleCursorAdapter will work I just can't seem to figure it out and I'm not giving up until I do haha. Thanks in advance for any help.
Well looks like I am dumb haha... For some reason or another, probably from just trying numerous things and then forgetting to remove parts that I had added. I just removed c.close(); and now everything is fine. I remember adding that as I was trying to figure things out and I must've fixed the problem somewhere else and then didn't realize it because this line was still in there. Since I am not actually doing anything with the Cursor other than passing it to a function, it doesn't need to be closed. Anyhow all is good, I knew it was going to be something stupid. Like usual.

Categories