Android Open Source - pulltorefresh_library_with_Indexable_listView Index Scroller






From Project

Back to project page pulltorefresh_library_with_Indexable_listView.

License

The source code is released under:

Apache License

If you think the Android project pulltorefresh_library_with_Indexable_listView listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright 2011 woozzu//from   www  . j  a  v  a 2s.  c om
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.handmark.pulltorefresh.library.extras;

import com.handmark.pulltorefresh.library.PullToRefreshBase;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.view.MotionEvent;
import android.widget.Adapter;
import android.widget.HeaderViewListAdapter;
import android.widget.ListView;
import android.widget.SectionIndexer;

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 = 10 * 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 HeaderViewListAdapter) {
      HeaderViewListAdapter headerViewListAdapter = (HeaderViewListAdapter) adapter;
      if (((HeaderViewListAdapter) adapter).getWrappedAdapter() instanceof SectionIndexer){
        mIndexer = (SectionIndexer) headerViewListAdapter.getWrappedAdapter();
        mSections = (String[]) mIndexer.getSections();
      }
    } else 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
      PullToRefreshBase.INDEXABLE_ISSHOW = false;
      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(1000);
      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;
      }
    }
    
  };
  
  public boolean isShow(){ 
     if (mState == STATE_HIDDEN) 
       return false; 

     return true; 

   }



}




Java Source Code List

com.handmark.pulltorefresh.configuration.xml.ExtendedXmlConfigParserFactory.java
com.handmark.pulltorefresh.configuration.xml.PullToRefreshConfigXmlParser.java
com.handmark.pulltorefresh.configuration.xml.PullToRefreshNode.java
com.handmark.pulltorefresh.configuration.xml.PullToRefreshXmlConfiguration.java
com.handmark.pulltorefresh.configuration.xml.XmlPullNodeParser.java
com.handmark.pulltorefresh.configuration.xml.XmlPullNode.java
com.handmark.pulltorefresh.configuration.xml.XmlPullParserWrapper.java
com.handmark.pulltorefresh.extras.listfragment.PullToRefreshBaseListFragment.java
com.handmark.pulltorefresh.extras.listfragment.PullToRefreshExpandableListFragment.java
com.handmark.pulltorefresh.extras.listfragment.PullToRefreshIndexableListFragment.java
com.handmark.pulltorefresh.extras.listfragment.PullToRefreshListFragment.java
com.handmark.pulltorefresh.library.AlphaAnimator.java
com.handmark.pulltorefresh.library.GoogleStyleProgressLayoutFactory.java
com.handmark.pulltorefresh.library.GoogleStyleProgressLayout.java
com.handmark.pulltorefresh.library.GoogleStyleViewLayoutFactory.java
com.handmark.pulltorefresh.library.GoogleStyleViewLayout.java
com.handmark.pulltorefresh.library.IGoogleStyleProgressLayout.java
com.handmark.pulltorefresh.library.IGoogleStyleViewLayout.java
com.handmark.pulltorefresh.library.IIndicatorLayout.java
com.handmark.pulltorefresh.library.ILoadingLayout.java
com.handmark.pulltorefresh.library.IPullToRefreshConsumer.java
com.handmark.pulltorefresh.library.IPullToRefresh.java
com.handmark.pulltorefresh.library.IndicatorLayoutFactory.java
com.handmark.pulltorefresh.library.LoadingLayoutFactory.java
com.handmark.pulltorefresh.library.LoadingLayoutProxy.java
com.handmark.pulltorefresh.library.OverscrollHelper.java
com.handmark.pulltorefresh.library.PullToRefreshAdapterViewBase.java
com.handmark.pulltorefresh.library.PullToRefreshBase.java
com.handmark.pulltorefresh.library.PullToRefreshExpandableListView.java
com.handmark.pulltorefresh.library.PullToRefreshGridView.java
com.handmark.pulltorefresh.library.PullToRefreshHorizontalScrollView.java
com.handmark.pulltorefresh.library.PullToRefreshIndexableListView.java
com.handmark.pulltorefresh.library.PullToRefreshListView.java
com.handmark.pulltorefresh.library.PullToRefreshScrollView.java
com.handmark.pulltorefresh.library.PullToRefreshWebView.java
com.handmark.pulltorefresh.library.StringMatcher.java
com.handmark.pulltorefresh.library.extras.IndexScroller.java
com.handmark.pulltorefresh.library.extras.IndexableListView.java
com.handmark.pulltorefresh.library.extras.PullToRefreshWebView2.java
com.handmark.pulltorefresh.library.extras.SoundPullEventListener.java
com.handmark.pulltorefresh.library.internal.AbstractDefaultGoogleStyleViewLayout.java
com.handmark.pulltorefresh.library.internal.Assert.java
com.handmark.pulltorefresh.library.internal.DefaultGoogleStyleProgressLayout.java
com.handmark.pulltorefresh.library.internal.DefaultGoogleStyleViewLayout.java
com.handmark.pulltorefresh.library.internal.DefaultIndicatorLayout.java
com.handmark.pulltorefresh.library.internal.EmptyViewMethodAccessor.java
com.handmark.pulltorefresh.library.internal.FlipLoadingLayout.java
com.handmark.pulltorefresh.library.internal.FlippedProgressBar.java
com.handmark.pulltorefresh.library.internal.IndicatorLayout.java
com.handmark.pulltorefresh.library.internal.LoadingLayout.java
com.handmark.pulltorefresh.library.internal.PullingProgressLayout.java
com.handmark.pulltorefresh.library.internal.RotateLoadingLayout.java
com.handmark.pulltorefresh.library.internal.Utils.java
com.handmark.pulltorefresh.library.internal.ViewCompat.java