无法从列表视图中隐藏IndexScroll

时间:2014-02-26 09:53:33

标签: java android listview scroll

我有一个自定义列表视图,它有一个自定义的inexscroller,当你滚动列表时它会自动绘制。现在,当我的listview没有太多项目时,这看起来并不好看。所以我想要做的是当项目小于可滚动的特定数字时隐藏IndexScroller。我做了一切,但我无法隐藏列表视图。请帮忙:

以下是使用的类:

IndexableListViewActivity

public class IndexableListViewActivity extends Activity implements OnClickListener
{
    private ArrayList<String> mItems;
    private IndexableListView mListView;
    TextView MyTasks, TeamTasks, username, fullusername;
    RelativeLayout listlay;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mItems = new ArrayList<String>();
        mItems.add("Diary of a Wimpy Kid 6: Cabin Fever");
        mItems.add("Steve Jobs");
        mItems.add("Inheritance (The Inheritance Cycle)");
        mItems.add("11/22/63: A Novel");
        mItems.add("The Hunger Games");
        mItems.add("The LEGO Ideas Book");
        mItems.add("Explosive Eighteen: A Stephanie Plum Novel");
        mItems.add("Catching Fire (The Second Book of the Hunger Games)");
        mItems.add("Elder Scrolls V: Skyrim: Prima Official Game Guide");
        mItems.add("Death Comes to Pemberley");
        mItems.add("Diary of a Wimpy Kid 6: Cabin Fever");
        mItems.add("Steve Jobs");
        mItems.add("Inheritance (The Inheritance Cycle)");
        mItems.add("11/22/63: A Novel");
        mItems.add("The Hunger Games");
        mItems.add("The LEGO Ideas Book");
        mItems.add("Explosive Eighteen: A Stephanie Plum Novel");
        mItems.add("Catching Fire (The Second Book of the Hunger Games)");
        mItems.add("Elder Scrolls V: Skyrim: Prima Official Game Guide");
        mItems.add("Death Comes to Pemberley");
        mItems.add("Make this list longer");
        mItems.add("A");
        mItems.add("B");
//        mItems.add("C");
//        mItems.add("D");
//        mItems.add("E");
//        mItems.add("F");
//        mItems.add("H");
//        mItems.add("I");
//        mItems.add("J");
//        mItems.add("K");
//        mItems.add("L");
//        mItems.add("M");
//        mItems.add("N");
//        mItems.add("O");
//        mItems.add("P");
//        mItems.add("Q");
//        mItems.add("R");
//        mItems.add("S");
//        mItems.add("T");
//        mItems.add("U");
//        mItems.add("V");
//        mItems.add("W");
//        mItems.add("X");
//        mItems.add("Y");
//        mItems.add("Z");        

        Collections.sort(mItems);

        ContentAdapter adapter = new ContentAdapter(this,
                android.R.layout.simple_list_item_1, mItems);

        mListView = (IndexableListView) findViewById(R.id.listview);
        mListView.setAdapter(adapter);
        mListView.setFastScrollEnabled(true);


        MyTasks = (TextView)findViewById(R.id.myTasks);
        MyTasks.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                MyTasks.setBackgroundResource(R.drawable.rectangle_selected);
                TeamTasks.setBackgroundResource(R.drawable.rectangle);

                 if(mListView.getLastVisiblePosition() + 1 == mListView.getCount()) {
                     Toast.makeText(getBaseContext(), "No need to scroll", Toast.LENGTH_SHORT).show();

                   }
                 else
                 {
                     Toast.makeText(getBaseContext(), "Need to scroll", Toast.LENGTH_SHORT).show();

                 }

            }
        });





        TeamTasks = (TextView)findViewById(R.id.teamTasks);
        TeamTasks.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                TeamTasks.setBackgroundResource(R.drawable.rectangle_selected);
                MyTasks.setBackgroundResource(R.drawable.rectangle);
            }
        });
    }

    private class ContentAdapter extends ArrayAdapter<String> implements SectionIndexer {

        private String mSections = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ";

        public ContentAdapter(Context context, int textViewResourceId,
                List<String> objects) {
            super(context, textViewResourceId, objects);
        }

        @Override
        public int getPositionForSection(int section) {
            // If there is no item for current section, previous section will be selected
            for (int i = section; i >= 0; i--) {
                for (int j = 0; j < getCount(); j++) {
                    if (i == 0) {
                        // For numeric section
                        for (int k = 0; k <= 9; k++) {
                            if (StringMatcher.match(String.valueOf(getItem(j).charAt(0)), String.valueOf(k)))
                                return j;
                        }
                    } else {
                        if (StringMatcher.match(String.valueOf(getItem(j).charAt(0)), String.valueOf(mSections.charAt(i))))
                            return j;
                    }
                }
            }
            return 0;
        }

        @Override
        public int getSectionForPosition(int position) {
            return 0;
        }

        @Override
        public Object[] getSections() {
            String[] sections = new String[mSections.length()];
            for (int i = 0; i < mSections.length(); i++)
                sections[i] = String.valueOf(mSections.charAt(i));
            return sections;
        }
    }

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub

    }
}

StrngMatcher.java

public class StringMatcher {
    public static boolean match(String value, String keyword) {
        if (value == null || keyword == null)
            return false;
        if (keyword.length() > value.length())
            return false;

        int i = 0, j = 0;
        do {
            int vi = value.charAt(i);
            int kj = keyword.charAt(j);
            if (isKorean(vi) && isInitialSound(kj)) {
            } else {
                if (vi == kj) {
                    i++;
                    j++;
                } else if (j > 0)
                    break;
                else
                    i++;
            }
        } while (i < value.length() && j < keyword.length());

        return (j == keyword.length())? true : false;
    }

    private static boolean isKorean(int i) {
        return false;
    }

    private static boolean isInitialSound(int i) {
        return false;
    }
}

IndexableListView.java

public class IndexableListView extends ListView {

    private boolean mIsFastScrollEnabled = false;
    private IndexScroller mScroller = null;
    private GestureDetector mGestureDetector = null;

    public IndexableListView(Context context) {
        super(context);
    }

    public IndexableListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public IndexableListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean isFastScrollEnabled() {
        return mIsFastScrollEnabled;
    }

    @Override
    public void setFastScrollEnabled(boolean enabled) {
        mIsFastScrollEnabled = enabled;
        if (mIsFastScrollEnabled) {
            if (mScroller == null)
                mScroller = new IndexScroller(getContext(), this);
    } 
            else {
            if (mScroller != null) {
                mScroller.hide();
                mScroller = null;
            }
        }
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);

        // Overlay index bar
        if (mScroller != null)
            mScroller.draw(canvas);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        // Intercept ListView's touch event
        if (mScroller != null && mScroller.onTouchEvent(ev))
            return true;

        if (mGestureDetector == null) {
            mGestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {

                @Override
                public boolean onFling(MotionEvent e1, MotionEvent e2,
                        float velocityX, float velocityY) {
                    // If fling happens, index bar shows
                    if(mScroller!=null)
                    mScroller.show();
                    return super.onFling(e1, e2, velocityX, velocityY);
                }

            });
        }
        mGestureDetector.onTouchEvent(ev);

        return super.onTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return true;
    }

    @Override
    public void setAdapter(ListAdapter adapter) {
        super.setAdapter(adapter);
        if (mScroller != null)
            mScroller.setAdapter(adapter);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (mScroller != null)
            mScroller.onSizeChanged(w, h, oldw, oldh);
    }

}

IndexScroller.java

public class IndexScroller {

    private float mIndexbarWidth;
    private float mIndexbarMargin;
    private float mPreviewPadding;
    private float mDensity;
    private float mScaledDensity;
    private float mAlphaRate;
    private int mState = STATE_HIDDEN;
    private int mListViewWidth;
    private int mListViewHeight;
    private int mCurrentSection = -1;
    private boolean mIsIndexing = false;
    private ListView mListView = null;
    private SectionIndexer mIndexer = null;
    private String[] mSections = null;
    private RectF mIndexbarRect;

    private static final int STATE_HIDDEN = 0;
    private static final int STATE_SHOWING = 1;
    private static final int STATE_SHOWN = 2;
    private static final int STATE_HIDING = 3;

    public IndexScroller(Context context, ListView lv) {
        mDensity = context.getResources().getDisplayMetrics().density;
        mScaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
        mListView = lv;
        setAdapter(mListView.getAdapter());

        mIndexbarWidth = 20 * mDensity;
        mIndexbarMargin = 2 * mDensity;
        mPreviewPadding = 5 * mDensity;
    }

    public void draw(Canvas canvas) {
        if (mState == STATE_HIDDEN)
            return;

        // mAlphaRate determines the rate of opacity
        Paint indexbarPaint = new Paint();
        indexbarPaint.setColor(Color.BLACK);
        indexbarPaint.setAlpha((int) (64 * mAlphaRate));
        indexbarPaint.setAntiAlias(true);
        canvas.drawRoundRect(mIndexbarRect, 5 * mDensity, 5 * mDensity, indexbarPaint);

        if (mSections != null && mSections.length > 0) {
            // Preview is shown when mCurrentSection is set
            if (mCurrentSection >= 0) {
                Paint previewPaint = new Paint();
                previewPaint.setColor(Color.BLACK);
                previewPaint.setAlpha(96);
                previewPaint.setAntiAlias(true);
                previewPaint.setShadowLayer(3, 0, 0, Color.argb(64, 0, 0, 0));

                Paint previewTextPaint = new Paint();
                previewTextPaint.setColor(Color.WHITE);
                previewTextPaint.setAntiAlias(true);
                previewTextPaint.setTextSize(50 * mScaledDensity);

                float previewTextWidth = previewTextPaint.measureText(mSections[mCurrentSection]);
                float previewSize = 2 * mPreviewPadding + previewTextPaint.descent() - previewTextPaint.ascent();
                RectF previewRect = new RectF((mListViewWidth - previewSize) / 2
                        , (mListViewHeight - previewSize) / 2
                        , (mListViewWidth - previewSize) / 2 + previewSize
                        , (mListViewHeight - previewSize) / 2 + previewSize);

                canvas.drawRoundRect(previewRect, 5 * mDensity, 5 * mDensity, previewPaint);
                canvas.drawText(mSections[mCurrentSection], previewRect.left + (previewSize - previewTextWidth) / 2 - 1
                        , previewRect.top + mPreviewPadding - previewTextPaint.ascent() + 1, previewTextPaint);
            }

            Paint indexPaint = new Paint();
            indexPaint.setColor(Color.WHITE);
            indexPaint.setAlpha((int) (255 * mAlphaRate));
            indexPaint.setAntiAlias(true);
            indexPaint.setTextSize(12 * mScaledDensity);

            float sectionHeight = (mIndexbarRect.height() - 2 * mIndexbarMargin) / mSections.length;
            float paddingTop = (sectionHeight - (indexPaint.descent() - indexPaint.ascent())) / 2;
            for (int i = 0; i < mSections.length; i++) {
                float paddingLeft = (mIndexbarWidth - indexPaint.measureText(mSections[i])) / 2;
                canvas.drawText(mSections[i], mIndexbarRect.left + paddingLeft
                        , mIndexbarRect.top + mIndexbarMargin + sectionHeight * i + paddingTop - indexPaint.ascent(), indexPaint);
            }
        }
    }

    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            // If down event occurs inside index bar region, start indexing
            if (mState != STATE_HIDDEN && contains(ev.getX(), ev.getY())) {
                setState(STATE_SHOWN);

                // It demonstrates that the motion event started from index bar
                mIsIndexing = true;
                // Determine which section the point is in, and move the list to that section
                mCurrentSection = getSectionByPoint(ev.getY());
                mListView.setSelection(mIndexer.getPositionForSection(mCurrentSection));
                return true;
            }
            break;
        case MotionEvent.ACTION_MOVE:
            if (mIsIndexing) {
                // If this event moves inside index bar
                if (contains(ev.getX(), ev.getY())) {
                    // Determine which section the point is in, and move the list to that section
                    mCurrentSection = getSectionByPoint(ev.getY());
                    mListView.setSelection(mIndexer.getPositionForSection(mCurrentSection));
                }
                return true;
            }
            break;
        case MotionEvent.ACTION_UP:
            if (mIsIndexing) {
                mIsIndexing = false;
                mCurrentSection = -1;
            }
            if (mState == STATE_SHOWN)
                setState(STATE_HIDING);
            break;
        }
        return false;
    }

    public void onSizeChanged(int w, int h, int oldw, int oldh) {
        mListViewWidth = w;
        mListViewHeight = h;
        mIndexbarRect = new RectF(w - mIndexbarMargin - mIndexbarWidth
                , mIndexbarMargin
                , w - mIndexbarMargin
                , h - mIndexbarMargin);
    }

    public void show() {
        if (mState == STATE_HIDDEN)
            setState(STATE_SHOWING);
        else if (mState == STATE_HIDING)
            setState(STATE_HIDING);
    }

    public void hide() {
        if (mState == STATE_SHOWN)
            setState(STATE_HIDING);
    }

    public void setAdapter(Adapter adapter) {
        if (adapter instanceof SectionIndexer) {
            mIndexer = (SectionIndexer) adapter;
            mSections = (String[]) mIndexer.getSections();
        }
    }

    private void setState(int state) {
        if (state < STATE_HIDDEN || state > STATE_HIDING)
            return;

        mState = state;
        switch (mState) {
        case STATE_HIDDEN:
            // Cancel any fade effect
            mHandler.removeMessages(0);
            break;
        case STATE_SHOWING:
            // Start to fade in
            mAlphaRate = 0;
            fade(0);
            break;
        case STATE_SHOWN:
            // Cancel any fade effect
            mHandler.removeMessages(0);
            break;
        case STATE_HIDING:
            // Start to fade out after three seconds
            mAlphaRate = 1;
            fade(3000);
            break;
        }
    }

    private boolean contains(float x, float y) {
        // Determine if the point is in index bar region, which includes the right margin of the bar
        return (x >= mIndexbarRect.left && y >= mIndexbarRect.top && y <= mIndexbarRect.top + mIndexbarRect.height());
    }

    private int getSectionByPoint(float y) {
        if (mSections == null || mSections.length == 0)
            return 0;
        if (y < mIndexbarRect.top + mIndexbarMargin)
            return 0;
        if (y >= mIndexbarRect.top + mIndexbarRect.height() - mIndexbarMargin)
            return mSections.length - 1;
        return (int) ((y - mIndexbarRect.top - mIndexbarMargin) / ((mIndexbarRect.height() - 2 * mIndexbarMargin) / mSections.length));
    }

    private void fade(long delay) {
        mHandler.removeMessages(0);
        mHandler.sendEmptyMessageAtTime(0, SystemClock.uptimeMillis() + delay);
    }

    private Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            switch (mState) {
            case STATE_SHOWING:
                // Fade in effect
                mAlphaRate += (1 - mAlphaRate) * 0.2;
                if (mAlphaRate > 0.9) {
                    mAlphaRate = 1;
                    setState(STATE_SHOWN);
                }

                mListView.invalidate();
                fade(10);
                break;
            case STATE_SHOWN:
                // If no action, hide automatically
                setState(STATE_HIDING);
                break;
            case STATE_HIDING:
                // Fade out effect
                mAlphaRate -= mAlphaRate * 0.2;
                if (mAlphaRate < 0.1) {
                    mAlphaRate = 0;
                    setState(STATE_HIDDEN);
                }

                mListView.invalidate();
                fade(10);
                break;
            }
        }

    };
}

在此, IndexableListView IndexScroller 位于同一个包中,其他2个类位于2个不同的包中。

请帮助如何隐藏IndexScroller,以便它不会出现在触摸上

1 个答案:

答案 0 :(得分:0)

由于没有人愿意回答,这就是要做的事情。

对于所有设置状态的行,如IndexScroller.java所示,将它们包含在:

isTrue = mListView.getLastVisiblePosition() + 1 == mListView.getCount();
    if(!isTrue)
    {
      //State Shown
    }