Spinner not working properly while selecting data from it in android - android

There are lot of questions asked related to it, i searched them and tried to use the provided solution but unable to resolve my issue, that's why i am posting a new one.
I am working on android studio. In my app i am using a spinner as a dropdown. All the data is generated from a local JSON file which is in my assets folder. Below is my JSON file
ref.json
{"reference":
[
{"ref_no":"11111111111111","Name":"Faisal"},
{"ref_no":"22222222222222","Name":"Salman"},
{"ref_no":"33333333333333","Name":"Asim"},
{"ref_no":"44444444444444","Name":"Asad"},
{"ref_no":"55555555555555","Name":"Mateen"},
{"ref_no":"66666666666666","Name":"Omar"},
{"ref_no":"77777777777777","Name":"Usama"}
]}
MainActivity.java
Spinner dd_ref, dd_m_type,dd_site_status, dd_pole_type;
String refr_no, meter_type, latitude, longitude, site_status, comm_status, pole_type;
ArrayList<String> refList, m_type_List, site_status_List, pole_type_List;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
loadData();
} catch (JSONException e) {
e.printStackTrace();
}
}
public void loadData() throws JSONException {
//////////////// Below method is for reference number call
JSONArray RefjsonArray;
JSONObject Ref_obj;
refList = new ArrayList<String>();
try
{
Ref_obj = new JSONObject(loadRefJSONFromAssest());
RefjsonArray = Ref_obj.getJSONArray("reference");
for(int i = 0; i<RefjsonArray.length();i++)
{
Ref_obj = RefjsonArray.getJSONObject(i);
Log.d("Details-->", Ref_obj.getString("ref_no"));
String ref = Ref_obj.getString("ref_no");
refList.add(ref);
}
refList.add(0,"Select a reference number");
} catch (JSONException e)
{
e.printStackTrace();
}
dd_ref = (Spinner)findViewById(R.id.dd_ref);
dd_ref.setAdapter(new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_spinner_dropdown_item, refList));
dd_ref.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
refr_no = String.valueOf(refList.get(position));
//text_pos.setText("Hi " + refr_no);
// Log.d(" out ",refr_no);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});//// end reference spinner
///////// start of method meter type dropdown
JSONArray m_type_Array;
JSONObject m_type_obj;
m_type_List = new ArrayList<String>();
try{
m_type_obj = new JSONObject(loadMeterTypeJSONFromAssest());
m_type_Array = m_type_obj.getJSONArray("meter");
for(int i = 0; i<m_type_Array.length(); i++)
{
m_type_obj = m_type_Array.getJSONObject(i);
Log.d("Details-->", m_type_obj.getString("m_type"));
String m_type = m_type_obj.getString("m_type");
m_type_List.add(m_type);
}
m_type_List.add(0,"Select Meter Type");
}catch (JSONException e)
{
e.printStackTrace();
}
dd_m_type = (Spinner)findViewById(R.id.dd_m_type);
dd_m_type.setAdapter(new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_spinner_dropdown_item, m_type_List));
dd_ref.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
meter_type = String.valueOf(m_type_List.get(position));
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});// end dropdown meter type
}
////// method for loading meter type data
public String loadMeterTypeJSONFromAssest() {
String json = " ";
try{
InputStream is = getAssets().open("meter.json");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
json = new String(buffer, "UTF-8");
} catch (IOException e) {
e.printStackTrace();
return null;
}
return json;
}
//// load reference # data
public String loadRefJSONFromAssest() {
String json = " ";
try{
InputStream is = getAssets().open("ref.json");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
json = new String(buffer, "UTF-8");
} catch (IOException e) {
e.printStackTrace();
return null;
}
return json;
}
When i run my app it does load data into the spinner. I have 7 reference numbers in my list as shown in the JSON file. The app runs fine up to selecting reference number 33333333333333 and when i select 44444444444444 or more than it the app crashes while giving me below error in logcat
java.lang.ArrayIndexOutOfBoundsException: length=12; index=-1
at java.util.ArrayList.get(ArrayList.java:310)
at com.example.accurat.application.MainActivity$2.onItemSelected(MainActivity.java:131)
at android.widget.AdapterView.fireOnSelected(AdapterView.java:931)
at android.widget.AdapterView.dispatchOnItemSelected(AdapterView.java:920)
at android.widget.AdapterView.-wrap1(AdapterView.java)
at android.widget.AdapterView$SelectionNotifier.run(AdapterView.java:890)
at android.os.Handler.handleCallback(Handler.java:746)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5491)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
It's hitting at point meter_type = String.valueOf(m_type_List.get(position)); and i don't know why it's going at this point as it doesn't have any link with the meter type.
I did a search and found a solution, but it couldn't solve my issue.
Any help would be highly appreciated.

You are adding wrong spinner item click listener,Change dd_ref to dd_m_type spinner.
dd_m_type = (Spinner)findViewById(R.id.dd_m_type);
dd_m_type.setAdapter(new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_spinner_dropdown_item, m_type_List));
dd_m_type.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
meter_type = String.valueOf(m_type_List.get(position));
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});// end dropdown meter type

change
dd_ref.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
to
dd_m_type.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
In meter type dropdown method

I think there is issue in getting selected item from Spinner, Please try following approaches for getting selected items.
String Text = dd_m_type.getSelectedItem().toString();
OR
dd_m_type.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String item = parent.getItemAtPosition(position);
}
public void onNothingSelected(AdapterView<?> parent) {
}
});

Related

Class cast exception on spinner item selection

I have a spinner populated with custom adapter.
My code used to bind data to spinner is
private void setOperatorSpinnerAdapter(Spinner spinner, String data) {
listOperator = new ArrayList<>();
try {
jsonObject = new JSONObject(data);
jsonArray = jsonObject.getJSONArray("data");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
model2 = new LiabModel();
model2.setName(jsonObject.optString("name"));
listOperator.add(model2);
}
} catch (JSONException e) {
e.printStackTrace();
}
adapter_liab = new CustomListAdapter_liab(LiabilitiesActivity.this, listOperator);
spinner.setAdapter(adapter_liab);
}
My issue is with item selection. I am getting error as
java.lang.ClassCastException: java.lang.Integer cannot be cast to Model.LiabModel
My spinner item click code is
spnr.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
try {
LiabModel model2 = (LiabModel) parent.getItemAtPosition(position);
liab_type = model2.getName();
}
catch (Exception e){
Log.e("exc",""+e);
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
Im getting Class Cast exception in
"LiabModel model2 = (LiabModel) parent.getItemAtPosition(position);" this line. Why is that happening?
you can get selected value either by this
LiabModel model2 = (LiabModel) spnr.getItemAtPosition(position);
or by if listOperator is accessable
LiabModel model2 = listOperator.get(position);

Android Spinner setOnItemSelectedListener not working

I have made a spinner dynamically during a login process. I'd like to be able to return the value of the spinner when I click on an option but it doesn't seem to work.
I make the spinner here:
public Spinner page_spinner;
protected void onCreate(Bundle savedInstanceState){
...
page_spinner = (Spinner) findViewById(R.id.page_spinner);
...
//MAKE ARRAY HERE
GraphRequest requestPage = GraphRequest.newGraphPathRequest(
currentAccessToken,
"/me/accounts",
new GraphRequest.Callback() {
#Override
public void onCompleted(GraphResponse response) {
JSONArray jsonArray = null;
try {
jsonArray = response.getJSONObject().getJSONArray("data");
for(int i=0; i < jsonArray.length(); i++){
JSONObject page = jsonArray.getJSONObject(i);
String pageName = page.getString("name");
if(!pageName.equals("")) {
//Push names into the array
pages_array.add(pageName);
} else {
pages_array.clear();
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
Bundle pageParameters = new Bundle();
pageParameters.putString("fields", "name,access_token,picture{url}");
requestPage.setParameters(pageParameters);
requestPage.executeAsync();
...
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(StartPage.this, android.R.layout.simple_spinner_item, pages_array);
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); // The drop down view
page_spinner.setAdapter(spinnerArrayAdapter);
spinnerArrayAdapter.notifyDataSetChanged();
then I try to use the spinner here:
page_spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Log.d("***********", "THIS ");
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
Log.d("***********", "THIS ");
}
});
I don't ever get the Log.d or even if I made Toast there, it doesn't fire. Not sure why this is stopping and I'm not getting any errors.
Any ideas?
Declare the spinner as a global variable and without final
and try this:
page_spinner = (Spinner) findViewById(R.id.page_spinner);
...
//MAKE ARRAY HERE
GraphRequest requestPage = GraphRequest.newGraphPathRequest(
currentAccessToken,
"/me/accounts",
new GraphRequest.Callback() {
#Override
public void onCompleted(GraphResponse response) {
JSONArray jsonArray = null;
try {
jsonArray = response.getJSONObject().getJSONArray("data");
for(int i=0; i < jsonArray.length(); i++){
JSONObject page = jsonArray.getJSONObject(i);
String pageName = page.getString("name");
if(!pageName.equals("")) {
//Push names into the array
pages_array.add(pageName);
} else {
pages_array.clear();
}
}
} catch (JSONException e) {
e.printStackTrace();
}
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(StartPage.this, android.R.layout.simple_spinner_item, pages_array);
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); // The drop down view
page_spinner.setAdapter(spinnerArrayAdapter);
spinnerArrayAdapter.notifyDataSetChanged();
}
});
Your error seems somewhat correct. You are not notifying adapter about the changes in dataset.
Firstly, Your request is executed Async. So, your code execution will continue to next lines. So I guess, a blank array (size 0) is passed to ArrayAdapter<> and then the adapter is set to Spinner and then you are calling notifyDataSetChanged().
I think you should call spinnerArrayAdapter.notifyDataSetChanged();as below:
#Override
public void onCompleted(GraphResponse response) {
JSONArray jsonArray = null;
try {
jsonArray = response.getJSONObject().getJSONArray("data");
for(int i=0; i < jsonArray.length(); i++){
JSONObject page = jsonArray.getJSONObject(i);
String pageName = page.getString("name");
if(!pageName.equals("")) {
//Push names into the array
pages_array.add(pageName);
} else {
pages_array.clear();
}
}
spinnerArrayAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
I've tested your codes and everything seems Right here. First I tried Adding 10 Items at spinner. Everything worked fine. And I tested adding List of String which contains only one Item.
List<String> spinnerArray = new ArrayList<String>();
spinnerArray.add("Item 1");
My OnItemSelectedListener
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(MainActivity.this, "Selected", Toast.LENGTH_SHORT).show();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
But what happened is the code everything worked fine before was not working after because there is only one item in spinnerArray. Toast was shown when Activity loads and not called when item is selected. You may have the same issue there. So my suggestion is give priority to your Array which may contain only one item.

Getting id from from JSON objects inside onItemClickListener

First of all I use volley library for my post request. In this case I retrieve as response from the server the following json format.
{"status":"success","message":"Teams without a league have been
found.",
"teams":[{"ID":"31","team_name":"A Team"},
{"ID":"101","team_name":"The BEST team"},
{"ID":"109","team_name":"ael fc"},
{"ID":"110","team_name":"UK"},
{"ID":"111","team_name":"cyprus"},
{"ID":"112","team_name":"biochemisty"}
]
}
I do all the necessaray JSON deserialization and dispay the objects of the team array in a list.
Now what I want to do is to store in a String array the ID values of the selected teams. Any ideas on that?
Here is the part of the code
final JsonObjectRequest jsonObjReq1 = new
JsonObjectRequest(AppConfig.URL_GET_ALL_LEAGUE_TEAMS, jsonObject,
new com.android.volley.Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("TAG", response.toString());
try {
if(response.getString("status").equals("success")){
JSONArray teamsArray = response.getJSONArray("teams");
for(int i = 0; i< teamsArray.length(); i++){
teams = teamsArray.getJSONObject(i);
noLeagueMembersClass = new
NoLeagueMemberClass();
noLeagueMembersClass.
setTeamMember(teams.getString("team_name"));
noLeagueMembersClass.
setTeamMember(teams.getString("ID"));
noLeagueMemberList.add(noLeagueMembersClass);
listView.setAdapter(noLeagueAdapter);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView.setItemsCanFocus(false);
listView.setOnItemClickListener(new
AdapterView.OnItemClickListener() {
#Override
public void onItemClick
(AdapterView<?> parent, View view, int position, long id){
Toast.makeText(getApplicationContext(),"You
clicked"+position,Toast.LENGTH_SHORT).show();
}
});
}
}
} catch (JSONException e) {
e.printStackTrace();
}
I try the following
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
try {
final String teamId =
teams.getString("ID");
Log.d("teamId",teamId);
} catch (JSONException e) {
e.printStackTrace();
}
}
but I always get teamId=120. For example when I select first row,I want teamId to be equals with 31. When I click the second row I want the teamId to be equal with 101 and so on. I don't want to pass any values to a next activity yet. I hope the following picture will get you to understand what I want to do.
In other words I want each click I do to correspond to the JSON table.
{"DDL":[{"Id":1,"name":"Aruba"},{"Id":2,"name":"Afghanistan"},{"Id":3,"name":"Angola"},{"Id":4,"name":"Anguilla"},{"Id":5,"name":"Albania"},{"Id":6,"name":"Andorra"}]}
The above code shows the Json Array and DDL is the json array tag name.
//Country Spinner
private void getCountry(){
StringRequest stringRequest = new StringRequest(Request.Method.GET,"URL",
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
//Parsing the fetched Json String to JSON Object
JSONObject j = new JSONObject(response);
//Storing the Array of JSON String to our JSON Array
countryarray = j.getJSONArray("DDL");
//Calling method getStudents to get the students from the JSON Array
getCountries(countryarray);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
//Creating a request queue
RequestQueue requestQueue = Volley.newRequestQueue(this);
//Adding request to the queue
requestQueue.add(stringRequest);
}
private void getCountries(final JSONArray jsonArrayC){
//Traversing through all the items in the json array
countrylist=new ArrayList<String>();
for(int i=0;i<jsonArrayC.length();i++){
try {
//Getting json object
JSONObject json = jsonArrayC.getJSONObject(i);
countryid= Integer.valueOf(json.getString("Id"));
//Adding the name of the emtype to array list
countrylist.add(json.getString("name"));
} catch (JSONException e) {
e.printStackTrace();
}
}
countryspinner.setAdapter(new ArrayAdapter<String>(AddEmployee.this, android.R.layout.simple_spinner_dropdown_item, countrylist));
countryspinner.setSelection(99);
countryspinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
countryid = (int) id + 1;
getState((int) id + 1);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
You can use list Activity and display all the data into it and after that
protected void onListItemClick(ListView l, View v, int position, long id){
super.onListItemClick(l, v, position, id);
Intent i = new Intent(MainActivity.this,NextActivity.class);
startActivity(i);
}
Can get more details from http://developer.android.com/reference/android/app/ListActivity.html

Having trouble adding string array to spinner entries

What I'd like to accomplish is the String array names[] be what you see in the spinner, but I cannot seem to figure out how to do this. I have tried looking off of other similar questions, but everything I try results in a crash in my app, saying that it is unable to instantiate the activity. Below, I have included the onPostExecute, where I am generating the string array, and also my addListenerOnSpinnerSelection() method. Any guidance would be great.
protected void onPostExecute(JSONObject json) {
try {
// Get JSON Object
JSONObject runes = json.getJSONObject(encodedId);
// Get JSON Array node
JSONArray rune = runes.getJSONArray("pages");
// Loop through pages, page names stored in string array
String[] name = new String[rune.length()];
String curr;
ArrayList<String> runePageNames = new ArrayList<String>();
for(int i = 0; i < rune.length(); i++) {
JSONObject c = rune.getJSONObject(i);
name[i] = c.getString(TAG_NAME);
curr = c.getString(TAG_CURRENT);
if(curr.equals("true"))
name[i] = name[i] + " [Active]";
runePageNames.add(name[i]);
Log.i(".........", name[i]);
}
adapter = new ArrayAdapter(this,
android.R.layout.simple_spinner_dropdown_item,
runePageNames);
addListenerOnSpinnerSelection();
// Set TextView
textName.setText(name[0]);
} catch (JSONException e) {
e.printStackTrace();
}
public void addListenerOnSpinnerSelection() {
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
((TextView) adapterView.getChildAt(0)).setTextColor(Color.parseColor("#C49246"));
Toast.makeText(adapterView.getContext(),
"Page Selected: " + adapterView.getItemAtPosition(i).toString(),
Toast.LENGTH_SHORT).show();
page = adapterView.getItemAtPosition(i).toString();
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}

From JSONObject to ListView()

basically I have some data stories in an API in JSON format.
I have managed to get the data from the JSON, loop through the, put them into a TextView, add onClick() on the textView.
but I want to be able to use the optical button on the phone to scroll, so I been told I need a ListView()
So I put the text I want into an array and added the array to the listView
As the example shows below
But how do I add onClick for each Item and pass the ID (intStoryID)?????????
My Code Example
BufferedReader jsonBr = null;
ArrayList arrStoryList = null;
public void onCreate(Bundle savedInstancesState){
super.onCreate(savedInstancesState);
setContentView(R.layout.stories_main);
if(setTopStoryData()){
setStoriesArray();
buildPage();
}else{
// TODO add Error Handling
}
}
public boolean setTopStoryData(){
String strURL = "http://www.example.com/api/index.php?my=params";
JSONConn jsonConn = new JSONConn();
JSONConn.setURL(strURL);
if(jsonConn.setData()){
jsonBr = jsonConn.Br();
return true;
}else{
// my Error Handling
return false;
}
}
public void setStoriesArray(){
String line;
String strAddDate;
String strCurrentStatus;
String strStatusRead;
int intStoryID;
int intNumStories;
arrStoryList = new ArrayList();
JSONObject arrStories;
JSONObject arrAllStories;
JSONObject arrSingleStory;
try{
while((line = jsonBr.readLine()) != null){
arrStories = new JSONObject(line);
intNumStories = Integer.parseInt(arrStories.optString("NumStories"));
arrAllStories = arrStories.getJSONObject("StoryData");
if(intNumStories > 0){
for(int i = 0; i < intNumStories; i++){
arrSingleStory = arrAllStories.getJSONObject("Story"+i);
intStoryID = Integer.parseInt(arrSingleStory.getString("ID"));
strAddDate = arrSingleStory.getString("ADDEDDATE");
strCurrentStatus = arrSingleStory.getString("CURRENTSTATUS");
if(strCurrentStatus.equals("y")){
strStatusRead = "Online";
}else if(strCurrentStatus.equals("n")){
strStatusRead = "Offline";
}else{
strStatusRead = "Pending";
}
String strStoryText = strAddDate+" - " +strCurrentStatus;
arrStoryList.add(strStoryText));
} // end FOR loop
}
} //End while loop
} catch (IOException e) {
// TODO Auto-generated catch block
strDEBUG += "Error (2)";
} catch (JSONException e) {
// TODO Auto-generated catch block
strDEBUG += "Error (3) "+e.getLocalizedMessage()+"\n";
}
}
public void buildPage(){
if(this.arrStoryList != null){
ListView lv1 = (ListView)findViewById(R.id.listView1);
lv1.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,this.arrStoryList));
}
}
use onItemClickListener() to the list view to get click event on each item
listview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View view,
int position, long id) {
// do whatever you want here
}
});

Categories

Resources