Search code examples
androidandroid-fragmentsfocusandroid-spinnerchildren

Android Fragments: How to loop through fragment controls


How do I make all Spinners in my Fragment focusable?

Setting android:focusableInTouchMode and android:focusable in my layout's XML is having no effect.

More generally, I'm having trouble looping through my Fragment's controls and finding all controls of a specific type, such as all Spinners or all EditTexts.


Solution

  • This was very tricky for me, so I figured I would post my solution here. This solves a particular problem (how to make spinners focusable) but also addresses a more general problem (how to loop through controls in a fragment.

    public class MyFragment extends Fragment {
    
        private static ArrayList<Spinner> spinners = new ArrayList<Spinner>();
    
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    
            // inflate the layout
            View layout = inflater.inflate(R.layout.my_fragment_xml, container, false);
    
            // cast our newly inflated layout to a ViewGroup so we can 
            // enable looping through its children
            set_spinners((ViewGroup)layout);
    
            // now we can make them focusable
            make_spinners_focusable();
    
            return layout;
        }
    
        //find all spinners and add them to our static array
    
        private void set_spinners(ViewGroup container) {
            int count = container.getChildCount();
            for (int i = 0; i < count; i++) {
                View v = container.getChildAt(i);
                if (v instanceof Spinner) {
                    spinners.add((Spinner) v);
                } else if (v instanceof ViewGroup) {
                    //recurse through children
                    set_spinners((ViewGroup) v);
                }
            }
        }
    
        //make all spinners in this fragment focusable
        //we are forced to do this in code
    
        private void make_spinners_focusable() {            
            for (Spinner s : spinners) {
                s.setFocusable(true);
                s.setFocusableInTouchMode(true);
                s.setOnFocusChangeListener(new View.OnFocusChangeListener() {
                    @Override
                    public void onFocusChange(View v, boolean hasFocus) {
                        if (hasFocus) {
                            v.performClick();
                        }
                    }
                });
            }
        }
    
    
    }