Unable to add hint in android spinner

2020-02-16 04:54发布

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.

3条回答
Rolldiameter
2楼-- · 2020-02-16 05:19

Hello Use below library for the hint spinner

Hint Spinner library

查看更多
仙女界的扛把子
3楼-- · 2020-02-16 05:28
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>
查看更多
家丑人穷心不美
4楼-- · 2020-02-16 05:34

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.

查看更多
登录 后发表回答