Search code examples
androidstackview

StackView and OnItemSelectedListener (Android 3.0+)


In Stackview, it seems that OnItemSelectedListener (from superclass "AdapterView") is never called... How can I trigger some event when the view on top of the stack is changed by the user ?

I want to display some text to show the position of the current item inside the stack, so I need to find a way to update the textview when the user browses through the stack.

Thanks,


Solution

  • What i have done is writing a new class extending StackView and writing some code to get the OnItemSelected logics works. When the onTouchEvent gives me a MotionEvent.getAction() == ACTION_UP, i start a Thread that calls himself 'till the StackView.getDisplayedChild() changes. When it changes, i start the OnItemSelected logic, so i can always get the first displayed child.

    public boolean onTouchEvent(MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_UP && this.getAdapter() != null) {
            mPreviousSelection = this.getDisplayedChild();
            post(mSelectingThread);
        }
        return super.onTouchEvent(motionEvent);
    }
    

    This thread cycles himself untill he gets the new displayedChild:

    private class SelectingThread implements Runnable {
        CustomStackView mStackView;
    
        public SelectingThread(CustomStackView stackView) {
            this.mStackView = stackView;
        }
    
        @Override
        public void run() {
            if(mStackView.getAdapter() != null) {
                if (mPreviousSelection == CustomStackView.this.getDisplayedChild()) {
                    mThisOnItemSelectedListener.onItemSelected(mStackView, mStackView.getAdapter().getView(mPreviousSelection, null, mStackView),
                        mStackView.mPreviousSelection, mStackView.getAdapter().getItemId(mPreviousSelection));
                    return;
                } else {
                    mPreviousSelection = mStackView.getDisplayedChild();
                    mStackView.post(this);
                }
            }
        }
    }
    

    This Listener instead sets the Selected flag to true after deselecting them all.

    private class StackViewOnItemSelectedListener implements OnItemSelectedListener {
    
        CustomStackView mStackView;
    
        public StackViewOnItemSelectedListener(CustomStackView stackView) {
            this.mStackView = stackView;
        }
    
        @Override
        public void onItemSelected(AdapterView<?> parent, View selectedView, int position, long id) {
            deselectAll();
            if (mStackView.getAdapter() != null) {
                if (mOnItemSelectedListener != null) {
                    mStackView.mOnItemSelectedListener.onItemSelected(parent, selectedView, position, id);
                }
                mStackView.getAdapter().getView(position, null, mStackView).setSelected(true);
            }
        }
    
        private void deselectAll() {
            if (mStackView.getAdapter() != null) {
                int adapterSize = mStackView.getAdapter().getCount();
                for (int i = 0; i < adapterSize; i++) {
                    mStackView.getAdapter().getView(i, null, mStackView).setSelected(false);
                }
            }
        }
    
        @Override
        public void onNothingSelected(AdapterView<?> parent) {
            if (mStackView.getAdapter() != null) {
                if (mOnItemSelectedListener != null) {
                    mStackView.mOnItemSelectedListener.onNothingSelected(parent);
                }
                deselectAll();
            }
        }
    }
    

    I've tested it a little and it works..