Question

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,

Was it helpful?

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..

OTHER TIPS

A little late for the party but for folks coming here from google. Fortunately I found an easier solution. It still involves extending StackView though.

import android.content.Context;
import android.util.AttributeSet;
import android.widget.StackView;

public class StackViewAdv extends StackView
{
    public StackViewAdv(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }

    public StackViewAdv(Context context, AttributeSet attrs, int defStyleAttr)
    {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void setDisplayedChild(int whichChild)
    {
        this.getOnItemSelectedListener().onItemSelected(this, null, whichChild, -1);

        super.setDisplayedChild(whichChild);
    }
}

Please note that this solution only gives the index of the selected view to the listener and view (second parameter on onItemSelected) is null!

Using this.getCurrentView() instead of null unfortunately doesn't work because it returns a sub class of StackView. Maybe someone finds a solution to that.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top