1

So basically I have 2 Spinners with a set of values. When I change a Spinner value, the Recyclerview will refresh and update with a new set of data. I'm stuck here and any help is welcome, thanks in advance!

private String[] vocSpinner;
private String[] popSpinner;
private List<Standard> standardList = new ArrayList<>();
private RecyclerView recyclerView;
private StandardsAdapter sAdapter;

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    getActivity().setTitle("Standard");

recyclerView = (RecyclerView) getActivity().findViewById(R.id.recyclerView);
sAdapter = new StandardsAdapter(standardList);
RecyclerView.LayoutManager mLayoutManager = new 
LinearLayoutManager(getActivity().getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(sAdapter);

this.vocSpinner = new String[]{
            "CDO/Diver/Gds/Fitness Spec", "Combat/Service"
    };

    this.popSpinner = new String[]{
            "NSmen", "Regular/NSF", "Pre-enlistee"
    };

Spinner v = (Spinner) getActivity().findViewById(R.id.spinner_Voc);
final Spinner p = (Spinner) getActivity().findViewById(R.id.spinner_PopGp);

ArrayAdapter<String> adapterV = new ArrayAdapter<String>(getActivity(),
            android.R.layout.simple_spinner_item, vocSpinner);
v.setAdapter(adapterV);

ArrayAdapter<String> adapterP = new ArrayAdapter<String>(getActivity(),
            android.R.layout.simple_spinner_item, popSpinner);
p.setAdapter(adapterP);

v.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
            switch (position) {
                case 0:
                    if (p.getSelectedItem().equals("NSmen")) {
                        addStandardToList("Gold", ">90pts");
                        addStandardToList("Silver", ">75pts");
                        // I need help here!!
                        sAdapter.notifyDataSetChanged();


                    } else if (p.getSelectedItem().equals("Regular/NSF")) {
                        addStandardToList("Gold", ">85pts");
                        sAdapter.notifyDataSetChanged();

                    } else if (p.getSelectedItem().equals("Pre-enlistee")) {                           
                    }
                    break;

                case 1:
                    if (p.getSelectedItem().equals("NSmen")) {
                    } else if (p.getSelectedItem().equals("Regular/NSF")) {
                    } else if (p.getSelectedItem().equals("Pre-enlistee")) {                       
                    }
                    break;
            }
        }

@Override
        public void onNothingSelected(AdapterView<?> parentView) {
        }
    });

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_standard, container, false);
    return view;
}

private void addStandardToList(String stdStan, String stdPts) {
    Standard standardObj = new Standard (stdStan, stdPts);
    standardList.add(standardObj);
    sAdapter.notifyDataSetChanged();
}

}

KeLiuyue
  • 8,149
  • 4
  • 25
  • 42
Ryan
  • 13
  • 2
  • 11
  • use adapter.notifyDataSetChanged(); method – AskNilesh Jul 25 '17 at 06:27
  • @NileshRathod Is right. Use the method in listener of the spinner – Nabin Jul 25 '17 at 06:28
  • after adding new data in your adapter just call adapter.notifyDataSetChanged(); – AskNilesh Jul 25 '17 at 06:28
  • I don't really get it. Didn't I already set sAdapter.notifyDataSetChanged(); ? I have to clear the current list of data but sAdapter.clear(); doesn't seem to appear/work. – Ryan Jul 25 '17 at 06:32
  • @Ryan we'd have to see your StandardAdapter implementation. Currently you're adding your items to `standardList`, which you did pass to your adapter. But you need to make sure that you didn't create a new list within your adapter or the changes won't be reflected. You may also consider notifying insertions rather than the generic data set change – Allan W Jul 25 '17 at 06:36
  • @Ryan See my answer below. Your adapter on which itemselected is applied is populated with vocCpinner arrray and your if uses popSpinner array conditions – Kapil G Jul 25 '17 at 06:36
  • @Allan W https://pastebin.com/yva6u0H2 – Ryan Jul 25 '17 at 06:38
  • @Ryan can you actually verify that your item count is changing? Add a logger there and check the result. I don't think the issue is there, but I strongly recommend you put the add method in your adapter and directly modify the list, rather than assign a reference in the adapter and then modify a separate list in the process. Lastly, try notify item inserted (with the appropriate index) – Allan W Jul 25 '17 at 06:58
  • I apologize but I do not really understand how to implement what you suggested. – Ryan Jul 25 '17 at 07:08
  • I think your RecyclerView another Instance of your activity. How many times you change the recycleritem not affect Activitys RecyclerView. So change the recyclerViews initation. Like this `recyclerView = (RecyclerView) getActivity().getRecyclerView();` or trought constuctor – Fr099y Jul 25 '17 at 08:30

2 Answers2

0

@Ryan Your issue is in the logic and not notifyAdapterDataSet mostly. What you have done is populated adapterV and adapterP with different items and only set itemSelectedListener of adapterV. Now in your selected listener, you have an if condition and the values of your if conditions are related to values you set in adapterP. So they would never be selected in v.onitemselected Hence the issue. Change this line

v.setOnItemSelectedListener

to

p.setOnItemSelectedListener

and then change values of P to see if selection works and then modify your logic

UPDATE 1: To clear the list as per your comments, Just add standardList.clear() in your on itemselected method as the first line as shown below -

public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
        standardList.clear();
      switch (position) {
            case 0:
                //Your code here remains as it is now.
Kapil G
  • 4,081
  • 2
  • 20
  • 32
  • I have changed it from v to p but it doesn't work either. – Ryan Jul 25 '17 at 06:46
  • Ok so if you select any value from P apart from Pre-enlistee it doesn't change your adapter values? – Kapil G Jul 25 '17 at 06:47
  • Yup, changing the spinner to either NSmen or Regular/NSF doesn't change any value. – Ryan Jul 25 '17 at 06:54
  • @Ryan for me its working and updating. Can you let me know what you need exactly and i will modify the code and share. I have created your code with me – Kapil G Jul 25 '17 at 07:13
  • Can u copy the code into pastebin and I'l see what I can do from there? Thanks :) – Ryan Jul 25 '17 at 07:23
  • I used the same code as above. So I think what is happening is you are playing with 2 spinners and getting confused over there. When you run your app you will have 2 spinners with 1st item already selected in both of them and recyclerview updated with 2 values which is under your if p.getSelectedItem().equals("NSmen"). Now if you select the same values in spinner you dont see any change because in that case selectedlistener is not called. Now in your current code if you go to ui change the value of first spinner to second value and again back to first value you will see 2 more rows added – Kapil G Jul 25 '17 at 07:28
  • Yes, that is true. Having 1st item selected for both spinners. I have tried using all combination of the spinners but the recyclerview did not update. I took a look at your code and there were not much changes and I am surprised why it is able to work for you. – Ryan Jul 25 '17 at 07:40
  • Mine is Fragment if that matters. – Ryan Jul 25 '17 at 07:40
  • Yeah thats the only difference and thats what i was thinking. Would have to try with that though that shouldn't matter – Kapil G Jul 25 '17 at 07:41
  • So I did what you told me to, vocSpinner to 2nd then 1st value and adjust popSpinner to either 1st or 2nd value and it did generated the row out but it overlay with the NSmen values. That means I have to clear while I generate a new row. – Ryan Jul 25 '17 at 07:49
  • Yes correct. That it will do because the clear logic is not in place. That's the reason i asked what you need exactly so that i can modify it. but seeing this its clear that on click works and refreshes. Only thing is what needs to be refreshed has to be placed correctly in the logic :) – Kapil G Jul 25 '17 at 07:53
  • http://imgur.com/a/rJ1gc This is how it looks like right now. Are you able to modify the clear? I've standardList.clear(); but the recyclerview is empty upon start. – Ryan Jul 25 '17 at 07:55
  • Yeah thats because you have initialized the adapter with an empty list. If you want some default values you can add to the list. Or the best thing would be to have Select POP and Select Voc as spinner items so that once user selects the item your on click listener populates it perfectly. – Kapil G Jul 25 '17 at 08:57
  • I do not need any default list. But is there any way for me to clear the list created in value 1 of popSpinner when user changes from the 1st to 2nd value before generating the list needed? – Ryan Jul 25 '17 at 09:23
  • @Ryan I updated my answer. Have a look and it should solve your problem. All you have to do is add standardList.clear(); as first line of your itemselected method – Kapil G Jul 25 '17 at 09:30
  • @Ryan let me know if it worked and pls accept the answer if it does. – Kapil G Jul 25 '17 at 10:37
  • Hey sorry I was out of school. I have added the line, it only worked for the first time. Meaning, Gold (90pts) successfully changed to Gold (85pts) but it doesn't go back to displaying Gold & Silver when adjusting the popSpinner values. – Ryan Jul 25 '17 at 12:21
  • yeah because you don't have a pop Spinner itemSelectedListener implemented in this code so far. You need to have itemSelectedListener for both the spinners to get it to work on changing those values :) – Kapil G Jul 25 '17 at 12:46
  • https://pastebin.com/FmQa9LPA This is my current code with updated values. You mentioned having two itemSelectedListener, but won't they have the same codes inside? – Ryan Jul 25 '17 at 13:14
  • @Ryan That would depend a lot on your logic and how you want to implement it. If they need to have the same code, then you can add this code inside a method and call the method from both. So basically if you want the values to change on item selection of both the spinners, you need to implement that method for both. – Kapil G Jul 25 '17 at 13:17
  • Can I just copy and paste the whole set of codes but just replace v.setOnItemSelectedListener to p.setOnItemSelectedListener and if (p.getSelectedItem().equals("NSmen")) to (v.getSelectedItem().equals("Combat/Service")) and so on with the same code logic behind them? – Ryan Jul 25 '17 at 13:27
  • Yup you can do that if that works for you. The code might not look good and you might have to modify it later to optimize it if possible. It will all depend on what 2 combinations of the 2 spinners needs to execute which part of the code. That is the logic part of your app :) – Kapil G Jul 25 '17 at 13:30
  • I've tried what I mentioned above but it's filled with errors. Are you able to assist for a headstart? Thank you :) – Ryan Jul 25 '17 at 13:47
  • I can though and that's not related to this question which would cause too much of data here and future users might not understand it. You can mark this question as complete and raise another query with your errors and we all will be ready to assist you :) – Kapil G Jul 25 '17 at 13:49
  • How do I mark the question as complete? Sorry I am new to Stackoverflow. – Ryan Jul 25 '17 at 13:56
  • You just have to accept the answer which worked for you. In this case the above one. You will see a tick mark on the left side of the answer. – Kapil G Jul 25 '17 at 13:57
  • Great. You can raise a seperate ques now with as minimal code as possible which showcases the error you are getting along with the error that you get. and you will get the help from me as well as anyone else online :) – Kapil G Jul 25 '17 at 14:00
  • Thanks for your help once again. I am attempting to post a new question but I have to wait 90 mins.. I can't afford the downtime :/ – Ryan Jul 25 '17 at 14:15
  • https://pastebin.com/mW6sdnMt I'm trying to get the checkbox to display the set of data dynamically when they are checked/unchecked. – Ryan Jul 25 '17 at 14:26
  • You mean you need to change your recyclerview based on selection of checkbox? How do the values change. I dont see any code there for that – Kapil G Jul 25 '17 at 14:29
  • In the if else statements if (cb1.isChecked() || cb2.isChecked()) { addStandardToList (); } – Ryan Jul 25 '17 at 14:37
  • this part of code was not in pastebin. So if any of these is checked you will add. so what is the problem coming? – Kapil G Jul 25 '17 at 14:39
  • It's in (16 min ago post). Hmm, so basically if I check Push Up, the recyclerview will update with a new list of data just like when I change the spinner values. So if I check 1 or both, the data will update dynamically. But it doesn't do so. – Ryan Jul 25 '17 at 14:44
  • So you want o update data when check state is changed or when spinner is changed. If you want o update on even changing the checked state of checkbox from true to false or reverse you will have to implement setOnCheckedChangeListener https://stackoverflow.com/questions/8386832/android-checkbox-listener – Kapil G Jul 25 '17 at 14:49
  • Where do I place it exactly? Inside the switch or outside of setOnItemSelected? I've tried both but both gave me an error, "Cannot resolve symbol 'onCheckedChangeListener()' I tried change to AdapterView.onCheckedChangeListener() but error still persist, alt+enter but nothing helpful. – Ryan Jul 25 '17 at 15:02
  • in your onCreate. do cb1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { // Your code here } }); – Kapil G Jul 25 '17 at 15:04
  • It worked however when I uncheck, it doesn't change the data. Is this intentional or is it due to my previous/other code's logic? Anyway to solve it? – Ryan Jul 25 '17 at 15:18
  • It depends on how have you used isChecked boolean value in your check change listener and also what are spinner values. – Kapil G Jul 25 '17 at 15:26
  • I did this. cb1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { standardList.clear(); if (v.getSelectedItem().equals("CDO/Diver/Gds/Fitness Spec") && p.getSelectedItem().equals("NSmen")) { // Data code } } }); – Ryan Jul 25 '17 at 15:31
  • You need to check your logic. This logic of if statement will give the result as its coming. Since I don't know the overall requirement of your project I am not sure if I can give you the right logic for the code. Overall looks fine though – Kapil G Jul 25 '17 at 15:49
  • Alright thanks. Then how do I do if both cb1 & cb2 is checked since setOnCheckedChangeListener is only linked to one checkbox at a time. – Ryan Jul 25 '17 at 15:55
  • You need to link it to both same way as you did for spinner item – Kapil G Jul 25 '17 at 15:57
  • I've played around my codes for the best possible outcome. I guess I am done. Also, I cannot express my gratitude in words to you for aiding me the whole day! Have a great week my friend! Till then :) – Ryan Jul 25 '17 at 17:03
  • Thanks and same to you as well :) – Kapil G Jul 25 '17 at 17:28
  • Hey sorry, I have 1 more thing to ask. Let's say for vocSpinner value = "Combat/Service" and popSpinner value = "NSmen" and I check cb1. It will give a list. However, when I change popSpinner to "Regular/NSF" it will change to another list (which is correct) but how do I uncheck the checkbox as well without creating another data that overlay http://imgur.com/a/1wt4N – Ryan Jul 26 '17 at 08:22
  • v.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView> parentView, View selectedItemView, int position, long id) { standardList.clear(); cb1.setEnabled(true); cb2.setEnabled(true); switch (position) { case 0: if (p.getSelectedItem().equals("NSmen")) { cb1.setChecked(false); cb2.setChecked(false); This is my current code – Ryan Jul 26 '17 at 08:23
  • @Ryan Now I got a bit confused due to so much code of past and present. Can you please post a separate query with minimal code and your requirement. You won't need much details like how you are adding or displaying list etc. You just need parts where you want to change values from checkbox and all. – Kapil G Jul 26 '17 at 08:43
  • https://stackoverflow.com/questions/45321885/how-do-i-uncheck-checkbox-upon-new-spinner-value – Ryan Jul 26 '17 at 08:49
0

If you need to clear the recycler view and add new values. Then first you need to clear values in arraylist which is passed to adapter

standardList.clear();

Then you have to add new values by calling

 addStandardToList("Gold", ">90pts");

Then you have to ask adapter to refresh data on recycler view by calling

sAdapter.notifyDataSetChanged();
Sangeet Suresh
  • 2,527
  • 1
  • 18
  • 19
  • I've tried adding standardList.clear(); after addStandardToList("Gold", ">90pts"); and before sAdapter.notifyDataSetChanged(); but the list doesn't show up upon run. – Ryan Jul 25 '17 at 06:46