欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Android-section-list分組列表

系統 1940 0

分組列表項目源碼地址:

http://code.google.com/p/android-section-list/

android中listiew仿組向上滾動特效 原文地址:

http://www.cnblogs.com/xiaoQLu/archive/2011/12/20/2293732.html


非常感謝 kylin17 喲一嗨 同學發現的bug,確實存在此問題,已修正

MySectionIndexer.java中 public int getPositionForSection( int section)方法第一個判斷有誤,應該為大于等于,已修改,源碼重新上傳

手機qq上有這樣一個特效:當前分組的好友,向上滾動時,在頂部會出現一個透明的框,當下一個分組到達時,會把上一個分組慢慢頂上去,覺得這個特效蠻有意思,就研究了一下,android自帶的通訊錄分組就有這個特效,這里是自己仿寫的一個,部分源碼從通訊錄中扣出來的

實現原理:

前提條件,假設所有的數據已經分好組

1.listview中每一個item都默認有一個分組標簽,但是只顯示此分組下面的第一個,其他的默認不顯示

2.滾動的時候,判斷每一個分組的狀態,是向上滾動,還是完全顯示,或者隱藏,主要是取當前item所在的分組跟(下一個分組-1=當前分組)相比,如果相等,說明是向上流動,否則是隱藏

3.獲取當前分組的狀態后,就可以放置分組的位置了,這里使用view.layout(int left,int top,int rigth,int bottom) ,其他left是0,right是分組標簽的長度,top和bottom是需要計算的,用ViewGroup.getChileAt(0)獲取listview中第一個孩子的view,然后用bottom=view.getBottom獲取底部距離父窗口的位置,最后得到兩者之差y=bottom-標題框的高度,用這個差就可以得出頂部和底部的位置,就是top和bottom的值。

關鍵類解析

PinnedHeaderListView.java 這個是實現listview分組的關鍵,當然布局文件中的listview也要使用這個類,里面有個接口,adapter要實現此接口,是滾動時回調用,其中getPinnedHeaderState()是用來分組標簽狀態的,

它的3種狀態都在此接口中定義,configurePinnedHeader()是用來設置分組標簽的標題,也是相當于組中的組名,此類中的configHeaderView()就是放置分組使用的,結合上面的分析跟這個方法研究這個類

        
          /*
        
        
          
 * Copyright (C) 2010 The Android Open Source Project
 *
 * 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.demo.sectionlistview;


        
          import
        
         android.content.Context;

        
          import
        
         android.graphics.Canvas;

        
          import
        
         android.util.AttributeSet;

        
          import
        
         android.view.View;

        
          import
        
         android.widget.ListAdapter;

        
          import
        
         android.widget.ListView;


        
          /**
        
        
          
 * A ListView that maintains a header pinned at the top of the list. The
 * pinned header can be pushed up and dissolved as needed.
 
        
        
          */
        
        
          public
        
        
          class
        
         PinnedHeaderListView 
        
          extends
        
         ListView {

    
        
          /**
        
        
          
     * Adapter interface.  The list adapter must implement this interface.
     
        
        
          */
        
        
          public
        
        
          interface
        
         PinnedHeaderAdapter {

        
        
          /**
        
        
          
         * Pinned header state: don't show the header.
         
        
        
          */
        
        
          public
        
        
          static
        
        
          final
        
        
          int
        
         PINNED_HEADER_GONE = 0;

        
        
          /**
        
        
          
         * Pinned header state: show the header at the top of the list.
         
        
        
          */
        
        
          public
        
        
          static
        
        
          final
        
        
          int
        
         PINNED_HEADER_VISIBLE = 1;

        
        
          /**
        
        
          
         * Pinned header state: show the header. If the header extends beyond
         * the bottom of the first shown element, push it up and clip.
         
        
        
          */
        
        
          public
        
        
          static
        
        
          final
        
        
          int
        
         PINNED_HEADER_PUSHED_UP = 2;

        
        
          /**
        
        
          
         * Computes the desired state of the pinned header for the given
         * position of the first visible list item. Allowed return values are
         * {
        
        
          @link
        
        
           #PINNED_HEADER_GONE}, {
        
        
          @link
        
        
           #PINNED_HEADER_VISIBLE} or
         * {
        
        
          @link
        
        
           #PINNED_HEADER_PUSHED_UP}.
         
        
        
          */
        
        
          int
        
         getPinnedHeaderState(
        
          int
        
         position);

        
        
          /**
        
        
          
         * Configures the pinned header view to match the first visible list item.
         *
         * 
        
        
          @param
        
        
           header pinned header view.
         * 
        
        
          @param
        
        
           position position of the first visible list item.
         * 
        
        
          @param
        
        
           alpha fading of the header view, between 0 and 255.
         
        
        
          */
        
        
          void
        
         configurePinnedHeader(View header, 
        
          int
        
         position, 
        
          int
        
         alpha);
    }

    
        
          private
        
        
          static
        
        
          final
        
        
          int
        
         MAX_ALPHA = 255;

    
        
          private
        
         PinnedHeaderAdapter mAdapter;
    
        
          private
        
         View mHeaderView;
    
        
          private
        
        
          boolean
        
         mHeaderViewVisible;

    
        
          private
        
        
          int
        
         mHeaderViewWidth;

    
        
          private
        
        
          int
        
         mHeaderViewHeight;

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

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

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

    
        
          public
        
        
          void
        
         setPinnedHeaderView(View view) {
        mHeaderView = view;

        
        
          //
        
        
           Disable vertical fading when the pinned header is present
        
        
        
          //
        
        
           TODO change ListView to allow separate measures for top and bottom fading edge;
        
        
        
          //
        
        
           in this particular case we would like to disable the top, but not the bottom edge.
        
        
        
        
          if
        
         (mHeaderView != 
        
          null
        
        ) {
            setFadingEdgeLength(0);
        }
        requestLayout();
    }

    @Override
    
        
          public
        
        
          void
        
         setAdapter(ListAdapter adapter) {
        
        
          super
        
        .setAdapter(adapter);
        mAdapter = (PinnedHeaderAdapter)adapter;
    }

    @Override
    
        
          protected
        
        
          void
        
         onMeasure(
        
          int
        
         widthMeasureSpec, 
        
          int
        
         heightMeasureSpec) {
        
        
          super
        
        .onMeasure(widthMeasureSpec, heightMeasureSpec);
        
        
          if
        
         (mHeaderView != 
        
          null
        
        ) {
            measureChild(mHeaderView, widthMeasureSpec, heightMeasureSpec);
            mHeaderViewWidth = mHeaderView.getMeasuredWidth();
            mHeaderViewHeight = mHeaderView.getMeasuredHeight();
        }
    }

    @Override
    
        
          protected
        
        
          void
        
         onLayout(
        
          boolean
        
         changed, 
        
          int
        
         left, 
        
          int
        
         top, 
        
          int
        
         right, 
        
          int
        
         bottom) {
        
        
          super
        
        .onLayout(changed, left, top, right, bottom);
        
        
          if
        
         (mHeaderView != 
        
          null
        
        ) {
            mHeaderView.layout(0, 0, mHeaderViewWidth, mHeaderViewHeight);
            configureHeaderView(getFirstVisiblePosition());
        }
    }

    
        
          public
        
        
          void
        
         configureHeaderView(
        
          int
        
         position) {
        
        
          if
        
         (mHeaderView == 
        
          null
        
        ) {
            
        
          return
        
        ;
        }

        
        
          int
        
         state = mAdapter.getPinnedHeaderState(position);
        
        
          switch
        
         (state) {
            
        
          case
        
         PinnedHeaderAdapter.PINNED_HEADER_GONE: {
                mHeaderViewVisible = 
        
          false
        
        ;
                
        
          break
        
        ;
            }

            
        
          case
        
         PinnedHeaderAdapter.PINNED_HEADER_VISIBLE: {
                mAdapter.configurePinnedHeader(mHeaderView, position, MAX_ALPHA);
                
        
          if
        
         (mHeaderView.getTop() != 0) {
                    mHeaderView.layout(0, 0, mHeaderViewWidth, mHeaderViewHeight);
                }
                mHeaderViewVisible = 
        
          true
        
        ;
                
        
          break
        
        ;
            }

            
        
          case
        
         PinnedHeaderAdapter.PINNED_HEADER_PUSHED_UP: {
                View firstView = getChildAt(0);
                
        
          int
        
         bottom = firstView.getBottom();

        
          //
        
        
                          int itemHeight = firstView.getHeight();
        
        
        
        
          int
        
         headerHeight = mHeaderView.getHeight();
                
        
          int
        
         y;
                
        
          int
        
         alpha;
                
        
          if
        
         (bottom < headerHeight) {
                    y = (bottom - headerHeight);
                    alpha = MAX_ALPHA * (headerHeight + y) / headerHeight;
                } 
        
          else
        
         {
                    y = 0;
                    alpha = MAX_ALPHA;
                }
                mAdapter.configurePinnedHeader(mHeaderView, position, alpha);
                
        
          if
        
         (mHeaderView.getTop() != y) {
                    mHeaderView.layout(0, y, mHeaderViewWidth, mHeaderViewHeight + y);
                }
                mHeaderViewVisible = 
        
          true
        
        ;
                
        
          break
        
        ;
            }
        }
    }

    @Override
    
        
          protected
        
        
          void
        
         dispatchDraw(Canvas canvas) {
        
        
          super
        
        .dispatchDraw(canvas);
        
        
          if
        
         (mHeaderViewVisible) {
            drawChild(canvas, mHeaderView, getDrawingTime());
        }
    }
}
      


MySectionIndexer.java類,主要是用來提供分組的數據的,主要包括,String[]mSections-->所有的組名,int[] mPositions-->每一個組名在listivew中的位置,當然,他們的長度應該是相同的。

        
          package
        
        
           com.demo.sectionlistview;


        
        
          import
        
        
           java.util.Arrays;


        
        
          import
        
        
           android.widget.SectionIndexer;


        
        
          public
        
        
          class
        
         MySectionIndexer 
        
          implements
        
        
           SectionIndexer{
    
        
        
          private
        
        
          final
        
         String[] mSections;
        
          //

        
        
          private
        
        
          final
        
        
          int
        
        
          [] mPositions;
    
        
        
          private
        
        
          final
        
        
          int
        
        
           mCount;
    
    
        
        
          /**
        
        
          
     * 
        
        
          @param
        
        
           sections
     * 
        
        
          @param
        
        
           counts
     
        
        
          */
        
        
          public
        
         MySectionIndexer(String[] sections, 
        
          int
        
        
          [] counts) {
        
        
        
          if
        
         (sections == 
        
          null
        
         || counts == 
        
          null
        
        
          ) {
            
        
        
          throw
        
        
          new
        
        
           NullPointerException();
        }
        
        
        
          if
        
         (sections.length !=
        
           counts.length) {
            
        
        
          throw
        
        
          new
        
        
           IllegalArgumentException(
                    
        
        "The sections and counts arrays must have the same length"
        
          );
        }
        
        
        
          this
        
        .mSections =
        
           sections;
        mPositions 
        
        = 
        
          new
        
        
          int
        
        
          [counts.length];
        
        
        
          int
        
         position = 0
        
          ;
        
        
        
          for
        
         (
        
          int
        
         i = 0; i < counts.length; i++
        
          ) {
            
        
        
          if
        
        (mSections[i] == 
        
          null
        
        
          ) {
                mSections[i] 
        
        = ""
        
          ;
            } 
        
        
          else
        
        
           {
                mSections[i] 
        
        =
        
           mSections[i].trim(); 
            }
            
            mPositions[i] 
        
        =
        
           position;
            position 
        
        +=
        
           counts[i];
        }
        mCount 
        
        =
        
           position;
    }
    
    @Override
    
        
        
          public
        
        
           Object[] getSections() {
        
        
        
          //
        
        
           TODO Auto-generated method stub
        
        
          return
        
        
           mSections;
    }

    @Override
    
        
        
          public
        
        
          int
        
         getPositionForSection(
        
          int
        
        
           section) {
        
        
        
          //
        
        
          change by lcq 2012-10-12 section > mSections.length以為>= 
        
        
          if
        
         (section < 0 || section >=
        
           mSections.length) {
            
        
        
          return
        
         -1
        
          ;
        }
System.out.println(
        
        "lcq:section:"+
        
          section);
        
        
        
          return
        
        
           mPositions[section];
    }

    @Override
    
        
        
          public
        
        
          int
        
         getSectionForPosition(
        
          int
        
        
           position) {
        
        
        
          if
        
         (position < 0 || position >=
        
           mCount) {
            
        
        
          return
        
         -1
        
          ;
        }
        
        
        
          //
        
        
          注意這個方法的返回值,它就是index<0時,返回-index-2的原因
        
        
        
          //
        
        
          解釋Arrays.binarySearch,如果搜索結果在數組中,剛返回它在數組中的索引,如果不在,剛返回第一個比它大的索引的負數-1
        
        
        
          //
        
        
          如果沒弄明白,請自己想查看api
        
        
          int
        
         index =
        
           Arrays.binarySearch(mPositions, position);
        
        
        
          return
        
         index >= 0 ? index : -index - 2; 
        
          //
        
        
          當index小于0時,返回-index-2,
        
        
                  
    }

}
        
      

  當然,adapter也灰常重要,這里簡單分析下,因為具體使用時,會根據情況使用不同的adapter,比如說,有數據庫的,可以使用SimpleCursorAdapter,也可以使用SimpleAdapter等等,這里使用的原始的listAdapter,比較麻煩,這里要實現上面提到的PinnedHeaderAdapter,還要實現SectionIndexer,主要是用來根據實際位置查找分組的索引,以及根據索引返回組名在實際listview中的位置(這里有點不太好講,不太懂的,仔細看源碼和api)

其他的就是一些adapter的基本應用以及一些android 的基本知識,這里不在講述,不懂的請提問。

源碼下載地址:http://files.cnblogs.com/xiaoQLu/DemoSectionListView_Plus.rar



Android-section-list分組列表


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 中文字幕av亚洲精品一部二部 | 亚洲综合亚洲国产尤物 | 午夜99| 中文字幕在线精品 | 深夜寂寞影院 | 国产精品福利视频免费观看 | 亚洲国产精品一区二区三区久久 | 91精品久久久久久综合五月天 | 国产精品久久久久无码AV1 | 男女作爱免费网站 | 日本毛片免费看 | 毛片免费观看 | 奇米色777欧美一区二区 | 成人精品一区二区 | 色综合天天综合网国产成人网 | 亚洲欧洲另类 | 91免费在线看 | www.4hu影院| 国产网址在线 | 91在线 | porny | 欧美 | 91激情网| 成人一区二区在线观看视频 | 日韩 第一页 | 亚洲综合色视频在线观看 | 久久草资源费视频在线观看 | 免费很黄很色裸乳在线观看 | 日韩欧美在线一区二区三区 | 久久99精品久久久久久噜噜 | 九七婷婷狠狠成人免费视频 | 亚洲精品一区久久久久久 | 日本男人天堂 | 一级在线观看视频 | 精品欧美乱码久久久久久 | 一区二区三区四区精品 | 日韩在线短视频 | 中文字幕无线码一区二区三区 | 91影片| 亚洲精品v天堂中文字幕 | 欧美高清性色生活片免费观看 | 99久久久久久久 | 久996视频精品免费观看 |