Search code examples
androidanimationgridviewonscrolllistener

auto show & hide gridview indexer with animation


I have a gridview with alphabet indexer on the right side and set its visibility to view.gone in default. When I start to scroll my grid view, I want that indexer to show up with animation and when I stopped scrolling the indexer will hide automatically as well

 gridView.setOnScrollListener(new AbsListView.OnScrollListener() {
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                // TODO Auto-generated method stub

                    mLetter.setVisibility(View.VISIBLE);

            }

            public void onScrollStateChanged(AbsListView view, int scrollState) {
                    if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
                        final Handler handler = new Handler();
                        handler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                Animation animation = new TranslateAnimation(0, 200, 0, 0);
                                animation.setDuration(500);
                                mLetter.startAnimation(animation);
                                mLetter.setVisibility(View.GONE);
                            }
                        }, 5000);

                    }

            }
        });

my problems are:

  1. I haven't successfully made the indexer to show up with animation. in code above it's only changed the visibility to view.visible.
  2. When I scroll the grid view multiple times it detects all touches and the hide animation will run many timees as many as touches detected. I mean if I scroll/touch it 3 times, animations will run 3times. How to avoid this?

Solution

  • after hours I finally found my own answer and it's actually pretty simple

    gridview.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    int action = event.getAction();
                    switch (action) {
                        //when first touch
                        case MotionEvent.ACTION_DOWN:
                            if(mLetter.getVisibility() == View.GONE){ //make sure indexer doesn't exist
                                Animation animation = new TranslateAnimation(100, 0, 0, 0);
                                animation.setDuration(500);
                                mLetter.startAnimation(animation);
                                mLetter.setVisibility(View.VISIBLE);
                            }
                            break;
    
                        case MotionEvent.ACTION_MOVE:
                            mLetter.setVisibility(View.VISIBLE);
                            break;
                        case MotionEvent.ACTION_UP:
                            break;
                    }
                    return false;
                }
            });
    
    
    
            gridview.setOnScrollListener(new AbsListView.OnScrollListener() {
                public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                    // TODO Auto-generated method stub
    
                }
    
                public void onScrollStateChanged(AbsListView view, int scrollState) {
                    state = scrollState;
                    if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
                        final Handler handler = new Handler();
                        handler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                if (state == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
                                    //make sure indexer is exist AND is not currently touched
                                    if (mLetter.getVisibility() == View.VISIBLE && !mLetter.getBool()) {
                                        Animation animation = new TranslateAnimation(0, 200, 0, 0);
                                        animation.setDuration(500);
                                        mLetter.startAnimation(animation);
                                        mLetter.setVisibility(View.GONE);
    
                                    }
                                }
    
                            }
                        }, 5000);
    
    
                    }
    
                }
            });
    

    this successfully prevents animation to duplicate. hope this help someone