Unable to add hint in android spinner
Asked Answered
D

3

0

I have a spinner that behaves like a dropdown in my android application. I am developing the app in android studio. The spinner get data from the api. At run time it gets usernames from API and shows in the spinner. When app runs it shows the username and ID of the selected user like shown in below image

enter image description here

Now i want to add hint so i searched many articles and found many solutions and i follow the easiest of them. For more understanding please see the below code

 try
        {
            JSONObject jobj = new JSONObject(jsonObject.toString());
            // Locate the NodeList name
            jsonArray = jobj.getJSONArray("users");

            for(int i=0; i<jsonArray.length(); i++)
            {
                jsonObject = jsonArray.getJSONObject(i);

                Users user = new Users();

                user.setId(jsonObject.optString("Id"));
                user.setName(jsonObject.optString("Name"));
                users.add(user);

                userList.add("Select a username");// i add this as a hint
                userList.add(jsonObject.optString("Name"));

            }
        } catch (JSONException e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }

Now on onPostExecute() method

  @Override
    protected void onPostExecute(Void args)
    {
        // Locate the spinner in activity_main.xml
        Spinner spinner = (Spinner)findViewById(R.id.spinner);

        // Spinner adapter
        spinner.setAdapter(new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_spinner_dropdown_item, userList));

        // Spinner on item click listener

        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {


            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

                textViewResult = (TextView)findViewById(R.id.textView);

                // Set the text followed by the position

                // Set the text followed by the position
                if(!users.get(position).getName().equals("Select a username")) {
                    textViewResult.setText(" " + users.get(position - 1).getName() + "  " + users.get(position - 1).getId());
                }else {

                    textViewResult.setText("Hi " + users.get(position).getName() + " your ID is " + users.get(position).getId());
                    UserId = String.valueOf(users.get(position).getId());
                    progressDialog.dismiss();
                    _latitude.setText("");
                    _longitude.setText("");
                    Latitude = null;
                    Longitude = null;

                }

            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                textViewResult.setText("");
            }
        });
    }

When i run the application the app crashes while giving me the below error

Process: com.example.accurat.myapp, PID: 30382
                                                                       java.lang.ArrayIndexOutOfBoundsException: length=12; index=-1
                                                                           at java.util.ArrayList.get(ArrayList.java:310)
                                                                           at com.example.accurat.myapp.MainActivity$DownloadJSON$1.onItemSelected(MainActivity.java:494)
                                                                           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)

This error hits at the point textViewResult.setText(" " + users.get(position - 1).getName() + " " + users.get(position - 1).getId());

Update 1

following the answer of Junaid Hafeez i have done the following

for(int i=0; i<jsonArray.length(); i++)
            {
                jsonObject = jsonArray.getJSONObject(i);

                Users user = new Users();

                user.setId(jsonObject.optString("Id"));
                user.setName(jsonObject.optString("Name"));
                users.add(user);


                userList.add(jsonObject.optString("Name"));

            }
            userList.add(0, "Select a username"); // after for loop ended i add `select a username` at `0` index 

after that in postExecute() method i have done the following

 @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

                textViewResult = (TextView)findViewById(R.id.textView);

                // Set the text followed by the position

                // Set the text followed by the position
                if(position>0)
                {
                    textViewResult.setText("Hi " + users.get(position).getName() + " your ID is " + users.get(position).getId());

                    UserId = String.valueOf(users.get(position).getId());

                    _latitude.setText("");
                    _longitude.setText("");
                    Latitude = null;
                    Longitude = null;
                }
                else {


                }

                progressDialog.dismiss();

            }

The result i get is below

enter image description here

It does show me the hint, but when i select any username it shows me the name and id of the next username as shown in below image

enter image description here

I am stuck to it and couldn't find any solution

Any help would be highly appreciated.

Dunbarton answered 24/2, 2017 at 12:24 Comment(14)
add the default value as hint at at 0 place of array to act as hintHereto
you should add first item in your list for hint like Select Item.Mcghee
@SouravGanguly can you please provide me a snippet ?Dunbarton
add default item in your userList like this userList.add("select user"); on onPreExecute method.Ricciardi
why are you doing position-1?Anosmia
@aksacha added it, still facing same exceptionDunbarton
@VivekMishra if i don't do it then it will automatically show me the first name and id while the text on the spinner is select a nameDunbarton
I think u have overrided the 0th element of the userlist with the hintSwastika
@Swastika what to do then ?Dunbarton
Faisal is there in the list right..so it is not overridden..try textViewResult.setText("Hi " + users.get(position-1).getName() + " your ID is " + users.get(position-1).getId());Swastika
@Swastika you means ' if(position>0) { textViewResult.setText("Hi " + users.get(position-1).getName() + " your ID is " + users.get(position-1).getId()); UserId = String.valueOf(users.get(position).getId()); _latitude.setText(""); _longitude.setText(""); Latitude = null; Longitude = null; } else { }' like this ?Dunbarton
yes..use position-1 instead of positionSwastika
Let us continue this discussion in chat.Dunbarton
@Swastika it's working thank you :)Dunbarton
B
3

probably what you are doing is, you are clicking on first item of you spinner, where the position = 0 and doing this position - 1 in your setText which makes the index -1 that is actually not exists and crashes. Secondly you are doing this

 userList.add("Select a username");// i add this as a hint 

in your loop, which is adding new item on each iteration. what you need to do is

once you have complete list of your data, just add hint on its 0 index like this

userList.add(0, "Select a username");

and in your onClick, check weather position > 0 then do your work otherwise ignore as user clicked on hint.

Broadminded answered 24/2, 2017 at 12:34 Comment(4)
Thanks for the answer but i am still unable to completely resolve the issue, i have updated the question can you please see it ?Dunbarton
@faisal1208 are you sure users and usersList are the same lists? you have added new item in usersList and trying to get from users in your click method. abviosly it will show next item as 0 index was missed becuase of hint text and I think you won't have hint test in usersBroadminded
both users and user list get data from same json, if you want anything that will make things clear please tell meDunbarton
simply put a break point when you click spinner item and check what you have on first index of your Users list.Broadminded
R
2
package com.keshav.spinnerhintexample;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    Button btn_submit;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final Spinner spinner = (Spinner) findViewById(R.id.spinner);
        btn_submit = (Button) findViewById(R.id.btn_submit);



        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item) {

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {

                View v = super.getView(position, convertView, parent);
                if (position == getCount()) {
                    ((TextView)v.findViewById(android.R.id.text1)).setText("");
                    ((TextView)v.findViewById(android.R.id.text1)).setHint(getItem(getCount())); //"Hint to be displayed"
                }

                return v;
            }

            @Override
            public int getCount() {
                return super.getCount()-1; // you dont display last item. It is used as hint.
            }

        };


        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        adapter.add("Daily");
        adapter.add("Two Days");
        adapter.add("Weekly");
        adapter.add("Monthly");
        adapter.add("Three Months");
        adapter.add("Select a Item"); //This is the text that will be displayed as hint.


        spinner.setAdapter(adapter);
        spinner.setSelection(adapter.getCount()); //set the hint the default selection so it appears on launch.
        // spinner.setOnItemSelectedListener(this);


        btn_submit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                String item=spinner.getSelectedItem().toString();

                Log.e("keshav","selectedItem is ->"  + item);

                if(spinner.getSelectedItem().toString().equals("Select a Item")){
                    Toast.makeText(MainActivity.this,"Please Select an Item",Toast.LENGTH_LONG).show();
                }else {
                    Toast.makeText(MainActivity.this,"selected Item is -> "+item,Toast.LENGTH_LONG).show();
                }
            }
        });
    }
}

-------------------Xml File ----------


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.keshav.spinnerhintexample.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />


    <Spinner
        android:id="@+id/spinner"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:layout_marginTop="40dp"
        />


    <Button
        android:id="@+id/btn_submit"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:layout_alignParentBottom="true"
        android:layout_margin="10dp"
        android:background="@color/colorPrimaryDark"
        android:text="Submit"
        android:textColor="#FFFFFF"

        />

</RelativeLayout>
Rudiger answered 28/2, 2017 at 10:26 Comment(0)
R
1

Hello Use below library for the hint spinner

Hint Spinner library

Raynard answered 24/2, 2017 at 12:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.