I know there are several questions around this, but do not quite get how to solve it.
The problem is that I am showing some values from local SQlite database, the different options are shown ok and I can select them and the value displayed is ok. the problem is that when I try to save it, the getSelectedItem, gets the first item on the list. Any help or suggestions on how to solve it would be great.
Product product = new Product();
productsList = product.getProducts();
Spinner spinnerProduct = findViewById(R.id.spinnerProduct);
String[] arrayProduct = new String[productsList.size()];
for(int i = 0; i < productsList.size(); i++) {
arrayProduct[i] = productsList.get(i).nameProduct;
}
ArrayAdapter<String> adapterProduct = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, arrayProduct);
adapterProduct.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerProduct.setAdapter(adapterProduct);
spinnerProduct.setOnItemSelectedListener(onItemSelectedListener1);
String productSelected=spinnerProduct.getSelectedItem().toString();
AdapterView.OnItemSelectedListener onItemSelectedListener1 =
new AdapterView.OnItemSelectedListener(){
#Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
Product product = new Product();
productsList = product.getProducts();
int[] arrayProduct = new int[productsList.size()];
for(int i = 0; i < productsList.size(); i++) {
arrayProduct[i] = productsList.get(i).stockCurrent;
}
String productStock = String.valueOf(arrayProduct[position]);
product_amount_available.setText(productStock);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {}
};
A spinner uses Event listening so you cannot just do below in a linear fashion:
spinnerProduct.setOnItemSelectedListener(onItemSelectedListener1);
String productSelected=spinnerProduct.getSelectedItem().toString();
Basically what your code is doing is setting the listener, and immediately after, it's getting some arbitrary/default value from your spinnerProduct object. But you haven't even entered any input to the spinner yet. You must process all the UI and business logic in the event listener's onItemSelected() method only.
You need to implement OnItemSelectedListener and override
public void onItemSelected(AdapterView<?> parent, View view,
int pos, long id) {
// An item was selected. You can retrieve the selected item using
// parent.getItemAtPosition(pos)
}
public void onNothingSelected(AdapterView<?> parent) {
// Another interface callback
}
More info can be found here https://developer.android.com/guide/topics/ui/controls/spinner#SelectListener
Thanks for the help. I solved it. I made the global variables.
int idProduct,idStorage;
String productSelected,storageSelected;
first fill the spinners
Product product = new Product();
productsList = product.getProducts();
Storage storage = new Storage();
storageList = storage.getStorage();
Spinner spinnerProduct = findViewById(R.id.spinnerProduct);
spinnerProduct.setOnItemSelectedListener(this);
Spinner spinnerStorage = findViewById(R.id.spinnerStorage);
spinnerStorage.setOnItemSelectedListener(this);
String[] arrayProduct = new String[productsList.size()];
for(int i = 0; i < productsList.size(); i++) {
arrayProduct[i] = productsList.get(i).nameProduct;
}
ArrayAdapter<String> adapterProduct = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, arrayProduct);
adapterProduct.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerProduct.setAdapter(adapterProduct);
spinnerProduct.setOnItemSelectedListener(this);
String[] arrayStorage = new String[storageList.size()];
for(int i = 0; i < storageList.size(); i++) {
arrayStorage[i] = storageList.get(i).nameStorage;
}
ArrayAdapter<String> adapterStorage = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, arrayStorage);
adapterStorage.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerStorage.setAdapter(adapterStorage);
spinnerProduct.setOnItemSelectedListener(this);
then, as suggested implemented the onclicklisteners
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int pos, long l) {
if(adapterView.getId() == R.id.spinnerProduct)
{
idProduct=(int) adapterView.getSelectedItemId();
productSelected=adapterView.getSelectedItem().toString();
Product product = new Product();
productsList = product.getProducts();
int[] arrayProduct = new int[productsList.size()];
for(int i = 0; i < productsList.size(); i++) {
arrayProduct[i] = productsList.get(i).stockCurrent;
}
String productStock = String.valueOf(arrayProduct[pos]);
product_amount_available.setText(productStock);
}
else if(adapterView.getId() == R.id.spinnerStorage)
{
storageSelected=adapterView.getSelectedItem().toString();
idStorage=(int) adapterView.getSelectedItemId();
}
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
and at last I passed the values into the method triggered by a button
btnSaveTransferProduct.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
saveTransferProduct(idProduct,productSelected, idStorage, storageSelected);
}
}
});
Related
This is my Country spinner, in this i take the country id and pass in ApiGetState with country code i am getting state list, after getting state list i want to set it in State Spinner, I have done everything but if i select country first time its working fine but if i change the country, state spinner not updating, am i miss something in this code?
country.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
scountry = parent.getItemAtPosition(position).toString();
String cCode = scountry.substring(0, scountry.indexOf("-"));
countryCode = Integer.parseInt(cCode);
ApiGetStates(countryCode);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
I set the values on StateSpinner here from server:-
public void onResponse(Call<StatesModel> call, Response<StatesModel> response) {
if (response.isSuccessful()){
StatesModel model = response.body();
List<StatesModel.StatesModelDetail> list = model.getData();
for (int i = 0; i < list.size(); i++){
stateData = list.get(i);
String stateName = stateData.getName();
String code = stateData.getId();
String finalname = code + "-" + stateName;
arrayList.add(finalname);
ArrayAdapter<String> adapter = new ArrayAdapter<>(getContext(), R.layout.simple_spinner_dropdown, arrayList);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
state.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
i done this thing. Just clear the arraylist before "ApiGetStates(countryCode);" and call "adapter.notifyDataSetChanged();" outside "for loop" as per Sandeep Pareek. e.g:-
arrayList.clear();
ApiGetStates(countryCode);
I have a spinner which populates data after an API call. I need to add an item that says "select one" as a first item in spinner. This item should not be able to be selected. I tried several ways online, but not able to implement it in my code since the array is filled after the api call and couldn't figure out a correct way to add "select one" item to that array.. Could anyone tell me how to do this in my code?
public void TEMPLATE_PARSE(JSONArray array) {
TemplateArrayList = new ArrayList<>();
TemplateNames = new ArrayList<String>();
for (int i = 0; i < array.length(); i++) {
JSONObject json = null;
try {
json = array.getJSONObject(i);
ModelTemplate GetTemplateDataModel = new ModelTemplate();
GetTemplateDataModel.setTemplateID(json.getInt("TemplateID"));
GetTemplateDataModel.setTemplateText(json.getString("TemplateText"));
TemplateArrayList.add(GetTemplateDataModel);
TemplateNames.add(TemplateArrayList.get(i).getTemplateText().toString());
} catch (JSONException e) {
e.printStackTrace();
}
} // Close for loop here
if (array.length() != 0) {
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(this, simple_spinner_item, TemplateNames);
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); // The drop down view
spinTemplate.setAdapter(spinnerArrayAdapter);
spinTemplate.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Log.i("ssssmIsSpinnerFirstCall",mIsSpinnerFirstCall.toString());
if(!mIsSpinnerFirstCall) {
selectedTemplateID = TemplateArrayList.get(position).getTemplateID();
String selectedTemplateText = TemplateArrayList.get(position).getTemplateText();
editText.setText(selectedTemplateText);
saveInSp("selectedTemplateID", String.valueOf(selectedTemplateID));
templateSelected = true;
}
mIsSpinnerFirstCall = false;
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
}
First add Select One at position 0 to TemplateNames and then create adapter and set it to Spinner
TemplateNames.add(0, "Select One");
And then inside onItemSelected, check selected position and do whatever you want.
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if(position == 0)
// Skip or show validation message if you want
else {
// Do your actual task here
...
selectedTemplateID = TemplateArrayList.get(position - 1).getTemplateID();
String selectedTemplateText = TemplateArrayList.get(position - 1).getTemplateText();
...
}
}
i have a list :
[{
"catid": 1,
"title": "windows"
},
{
"catid": 2,
"title": "Android",
}
]
i want show list titles in spinner.
when user select a title, variable (int)selected_item equals corresponding catid.
for example when user select title "Android" from spinner , (int)selected_item = 2;
public void setupcatspinner(ArrayList<String> titles,ArrayList<Integer> catids){
final Spinner s1 = findViewById(R.id.spinner);
ArrayAdapter<String> adap=new ArrayAdapter<>
(this, android.R.layout.simple_spinner_item, titles);
adap.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
s1.setAdapter(adap);
s1.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// (int)selected_item = ???
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
https://developer.android.com/reference/android/widget/AdapterView.OnItemSelectedListener.html#onItemSelected(android.widget.AdapterView%3C?%3E,%20android.view.View,%20int,%20long)
Therefore selected_item = titles.get(position).get(0), assuming 0 is the index of catid the the two dimensional list titles.
You can maintain two different list one for ids and other for titles. Set OnItemSelectedListener to spinner and you will get the selected item position , get the corresponding id from catId list.
Check the code below,
// List containing all category ids
ArrayList<String> catIdList = new ArrayList<>();
// List containing all titles
ArrayList<String> titleList = new ArrayList<>();
// Store the data in respective lists
JSONArray jsonArray = new JSONArray(data);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
if(jsonObject.has("catid")){
catIdList.add(jsonObject.getString("catid"));
}
if(jsonObject.has("title")){
titleList.add(jsonObject.getString("title"));
}
}
You can pass titleList to SpinnerAdapter.
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long l) {
String catId = catIdList.get(position);
String title = titleList.get(position);
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
I am creating an app that contains a functionality that includes a list of questions with multiple answer options for each. To do this I am using a listview that with each item contains a TextView for displaying the question with a spinner that holds the list of answers. I am attempting to retrieve the currently selected value of a spinner within each listview item. This is typically easy except for the fact that I have a spinner for each listview item and the number of spinners I need is "unknown" until the number of questions is loaded.
My issue is how to get the value of each currently selected spinner item. Currently I am only able to get the value of the first spinner item. Below is my code for the class that uses my custom adapter:
questionsList = new ArrayList<>();
masterAnswersList = new ArrayList<>();
//For all questions with the tech answer's group id, get questions
for(int k = 0; k < allQuestions.size(); k++) {
final int z = k;
//Each question for the tech
System.out.println("Question " + z + " " + allQuestions.get(z).getQuestionTitle());
questionsList.add(new CompleteQuestions.ListViewItem() {{
QUESTION = allQuestions.get(z).getQuestionTitle();
}});
int questionId = allQuestions.get(z).getQuestionId();
//Get all possible answers for this question based on the question and the group id
allAnswers = db.getAllGroupAnswers(questionId, groupID, database);
answersList = new ArrayList<>();
//For all answers for this question, add to arraylist
for(int j = 0; j < allAnswers.size(); j++) {
final int p = j;
answersList.add(new CompleteQuestions.ListViewItem() {{
ANSWER = allAnswers.get(p).getAnswerTitle().trim();
}});
}
masterAnswersList.add(answersList);
}
adapter = new CompQuestionsAdapter(this, questionsList, masterAnswersList);
completeQuestionsListView.setAdapter(adapter);
//For the number of items in the listview
for (int i = 0; i < completeQuestionsListView.getCount(); i++) {
//Update ticket questions table
String techChoice = CompQuestionsAdapter.spinner.getSelectedItem().toString();
System.out.println("techChoice: " + techChoice);
//Get id of answer tech chose
int techAnswerId = db.getAnswerId(techChoice, database);
int questionId = allQuestions.get(i).getQuestionId();
int groupId = db.getGroupId(techChoice, questionId, database);
System.out.println("Group id: " + groupId);
Ticket questionTicket = new Ticket(questionId, techAnswerId, ticketId, companyId, groupId, true);
db.addTicketQuestionResponse(questionTicket, context, database);
}
And part of the custom adapter itself:
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
/**
* The database used to pull all ticket information
*/
final DatabaseHandler db = new DatabaseHandler(context);
final SQLiteDatabase database = db.getReadableDatabase();
ListViewItem item = questions.get(position);
//ListViewItem item2 = answers.get(position).get(position);
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.comp_questions_view, null);
TextView question = (TextView)vi.findViewById(R.id.QUESTION);
question.setText("" + item.QUESTION);
spinner = (Spinner)vi.findViewById(R.id.ANSWERS);
List<String> strAnswers = new ArrayList<>();
List<CompleteQuestions.ListViewItem> currentAnswers = answers.get(position);
for (int i = 0; i < currentAnswers.size(); i++) {
strAnswers.add(currentAnswers.get(i).ANSWER);
}
//Place all the cleared by codes in a string array used to populate the spinner
String[] strArrayAnswers = new String[strAnswers.size()];
for(int i = 0; i < strAnswers.size(); i++) {
if(strAnswers.get(i) != null) {
strArrayAnswers[i] = strAnswers.get(i);
}
}
adapter = new ArrayAdapter<>(context,
android.R.layout.simple_spinner_item, strArrayAnswers);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
List<String> selections = new ArrayList<>();
selections.add(spinner.getSelectedItem().toString());
System.out.println("Currently selected item: " + spinner.getSelectedItem());
return vi;
}
Any help on this would be greatly appreciated.
First of all you need to define an interface so your adapter class can use to tell the parent class which item has been chosen from the spinner in position and what is the selectedItem
The OnSpinnerItemSelected Interface
public interface OnSpinnerItemSelected {
void onItemSelected(int position, String selectedItem);
}
Then you need to pass one OnSpinnerItemSelected Object in your adapter constructor.
private OnSpinnerItemSelected onSpinnerItemSelected;
public CompQuestionsAdapter(......, OnSpinnerItemSelected onSpinnerItemSelected) {
this.onSpinnerItemSelected = onSpinnerItemSelected;
}
In your class that uses custem adapter add this:
adapter = new CompQuestionsAdapter(this, questionsList, masterAnswersList, new OnSpinnerItemSelected() {
#Override
public void onItemSelected(int position, String selectedItem) {
}
});
In your adapter call onItemSelected method (in getView method)
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
onSpinnerItemSelected.onItemSelected(position, adapterView.getAdapter().getItem(i));
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
Just let me know if it's not clear.
I've been stuck with this for a long while and it's really frustrating. Basically the app starts off with a ListView containing Movie Titles, their Gross, and Year.
The user then can add a new movie, gross, and year using a different activity from the menu. The values are then returned back to the first activity and is placed at the bottom of the list.
This is where my problem begins. The first problem I had is that the app Force Closes when it's about to display the new item. Now, it doesn't want to display at all. Here's the Code:
public class Lab7_084106 extends ListActivity {
private SampleCustomAdapter adapter;
private ArrayList<MyMovies> movieList;
public static boolean Flag = false;
#SuppressWarnings("null")
#Override
public void onCreate(Bundle savedInstanceState) {
//create stuff
super.onCreate(savedInstanceState);
movieList = new ArrayList<MyMovies>();
Intent data = getIntent();
//Flag = data.getStringExtra("Flag");
String[] oldMovieList = getResources().getStringArray(R.array.movieArray);
String[] oldGrossList = getResources().getStringArray(R.array.worldwideGross);
String[] oldYearList = getResources().getStringArray(R.array.yearArray);
//if there's no new movie to display
if(!Flag){
for (int i = 0; i < oldMovieList.length; i++) {
MyMovies newMovie = new MyMovies();
newMovie.setMovie(oldMovieList[i] + "NEW");
newMovie.setGross(oldGrossList[i]);
newMovie.setYear(oldYearList[i]);
movieList.add(newMovie);
}
//adapter = new SampleCustomAdapter(movieList);
//setContentView(R.layout.row);
//setListAdapter(adapter);
}
else{
Toast.makeText(getApplicationContext(), "Else Entered", Toast.LENGTH_SHORT).show();
int newLength = 50; //oldMovieList.length + 1;
//create new array to store the new value
String[] newMovieArray = new String[newLength];
String[] newGrossArray = new String[newLength];
String[] newYearArray = new String[newLength];
//populate the new list with the old one plus the new one
for (int i = 0; i < newLength; i++) {
if( i != newLength - 1){
newMovieArray[i] = oldMovieList[i];
newGrossArray[i] = oldGrossList[i];
newYearArray[i] = oldYearList[i];
}
else{
newMovieArray[i] = data.getStringExtra("Title");
newGrossArray[i] = data.getStringExtra("Gross");
newYearArray[i] = data.getStringExtra("Year");
}
}
//populate the old one using the new list
for (int i = 0; i < newLength; i++) {
oldMovieList[i] = newMovieArray[i];
oldGrossList[i] = newGrossArray[i];
oldYearList[i] = newYearArray[i];
}
//display stuff
for (int i = 0; i < newLength; i++) {
MyMovies newMovie = new MyMovies();
newMovie.setMovie(oldMovieList[i]);
newMovie.setGross(oldGrossList[i]);
newMovie.setYear(oldYearList[i]);
movieList.add(newMovie);
}
//adapter = new SampleCustomAdapter(movieList);
//setListAdapter(adapter);
}
adapter = new SampleCustomAdapter(movieList);
setListAdapter(adapter);
ListView lv = getListView();
lv.setTextFilterEnabled(true);
//set stuff such that Page2 sends back a result to page 1
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView t = (TextView) view.findViewById(R.id.title);
String name = (String) t.getText();
Toast.makeText(getApplicationContext(), name, Toast.LENGTH_SHORT).show();
}
});
}
private class SampleCustomAdapter extends BaseAdapter {
private ArrayList<MyMovies> internalList;
String[] oldMovieList = getResources().getStringArray(R.array.movieArray);
String[] oldGrossList = getResources().getStringArray(R.array.worldwideGross);
String[] oldYearList = getResources().getStringArray(R.array.yearArray);
private ArrayList<MyMovies> GetSearchResults(){
ArrayList<MyMovies> results = new ArrayList<MyMovies>();
// make sure the arrays have the same length
for (int i = 0; i < oldMovieList.length; i++) {
MyMovies sr = new MyMovies();
sr.setMovie(oldMovieList[i]);
sr.setGross(oldGrossList[i]);
sr.setYear(oldYearList[i]);
results.add(sr);
}
return results;
}
public SampleCustomAdapter(ArrayList<MyMovies> contacts){
internalList = contacts;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return internalList.size();
}
#Override
public Object getItem(int index) {
// TODO Auto-generated method stub
return internalList.get(index);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// NOTE: you can only do this if you have access to the Activity object
// which is why this is an inner class
LayoutInflater inflater = getLayoutInflater();
View view;
//System.out.println(parent.getClass().getName());
//System.out.println(position);
if (convertView==null){
view = inflater.inflate(R.layout.row, null);
}
else{
view = convertView;
}
// extract the views to be populated
TextView movie = (TextView) view.findViewById(R.id.title);
TextView gross = (TextView) view.findViewById(R.id.gross);
TextView date = (TextView) view.findViewById(R.id.date);
// extract the object that will fill these
MyMovies movies = GetSearchResults().get(position);
//MyMovies movies = internalList.get(position);
movie.setText(movies.getMovie());
gross.setText(movies.getGross());
date.setText(movies.getYear());
// return the view
return view;
}
}
//menu lawl
#Override
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menupage1, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
//Handle item selection using item.getItemId()
switch(item.getItemId()){
case R.id.addMovie:
AddMovie();
break;
}
return true;
}
//end menu stuff lol
public void AddMovie(){
Intent intent2 = new Intent(this, com.Android.Lab7.addMovie.class);
startActivity(intent2);
finish();
}
}
The Flag Boolean variable basically tells if the user added a movie. If the user added a movie, it will enter the else statement and update from there. I'm really confused where to put this if-else statement.
I ran a few experiments with the GetSearchResult function of SampleCustomAdapter and found out that it directly affects the output of the ListView. I tried placing the if-else statement there but I ended up with a LOT of items in the ListView.
Using adapter.notifyDataSetChanged(); gives a NullPointerException error and points to where I placed it. So even if do something like:
MyMovies newMovie = new MyMovies();
newMovie.setMovie(data.getStringExtra("Title"));
newMovie.setGross(data.getStringExtra("Gross"));
newMovie.setYear(data.getStringExtra("Year"));
movieList.add(newMovie);
adapter.notifyDataSetChanged();
As the else block, it does not work. I think it has something to do with the fact that I'm getting my initial values from the string.xml resource folder and not via hardcode or user input.
This problem has been frustrating me ever since 2-3 days ago and help is really appreciated. Thanks.
you just have to notify the data set Changed on your adapter
movieList.add(newMovie);
adapter.notifyDataSetChanged();
the listview will be updated automatically
UPDATE
you can always use the following it'll work but I prefer notifying the adapter.
movieList.add(newMovie);
adapter = new SampleCustomAdapter(movieList);
setListAdapter(adapter);
you should use adapter.notifyDataSetChanged(). CheckThis Link