0
votes

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?
2

2 Answers

2
votes

Use TouchListener on grid view:

  boolean isLetterShowing = false;
  gridView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            int action = event.getAction();
            switch (action){
                case MotionEvent.ACTION_DOWN:
                    if(!isLetterShowing){
                        isLetterShowing = true;
                    }
                    break;
                case MotionEvent.ACTION_SCROLL:
                    if(isLetterShowing){
                        mLetter.setVisibility(View.VISIBLE);
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    if(isLetterShowing){
                        isLetterShowing = false;
                        mLetter.setVisibility(View.INVISIBLE);
                    }
                    break;
            }
            return false;
        }
    });
1
votes

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