Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> 聯系人分組標簽懸停滑入滑出的實現方法。,標簽懸停

聯系人分組標簽懸停滑入滑出的實現方法。,標簽懸停

編輯:關於android開發

聯系人分組標簽懸停滑入滑出的實現方法。,標簽懸停


《類似通訊錄分組的Android PinnedSectionListView,分組標簽懸停滑入滑出》

常用的聯系人、通訊錄,會按照聯系人的姓氏從A,B,C,,,X,Y,Z,這樣歸類排列下去,方便用戶快速查找和定位。PinnedSectionListView是一個第三方的開源框架,在github上的鏈接地址是:https://github.com/beworker/pinned-section-listview 。分組的標簽會懸停在ListView的頂部,直到該分組被滑出/滑入整個ListView的可視界面而呈現出彈入彈出效果。

 

將PinnedSectionListView類放入自己的項目中:

PinnedSectionListView類代碼:

  1 package com.lixu.biaoqianxuanting;
  2 /*
  3  * Copyright (C) 2013 Sergej Shafarenka, halfbit.de
  4  *
  5  * Licensed under the Apache License, Version 2.0 (the "License");
  6  * you may not use this file kt in compliance with the License.
  7  * You may obtain a copy of the License at
  8  *
  9  * http://www.apache.org/licenses/LICENSE-2.0
 10  *
 11  * Unless required by applicable law or agreed to in writing, software
 12  * distributed under the License is distributed on an "AS IS" BASIS,
 13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  * See the License for the specific language governing permissions and
 15  * limitations under the License.
 16  */
 17 
 18 import android.content.Context;
 19 import android.database.DataSetObserver;
 20 import android.graphics.Canvas;
 21 import android.graphics.Color;
 22 import android.graphics.PointF;
 23 import android.graphics.Rect;
 24 import android.graphics.drawable.GradientDrawable;
 25 import android.graphics.drawable.GradientDrawable.Orientation;
 26 import android.os.Parcelable;
 27 import android.util.AttributeSet;
 28 import android.view.MotionEvent;
 29 import android.view.SoundEffectConstants;
 30 import android.view.View;
 31 import android.view.ViewConfiguration;
 32 import android.view.accessibility.AccessibilityEvent;
 33 import android.widget.AbsListView;
 34 import android.widget.HeaderViewListAdapter;
 35 import android.widget.ListAdapter;
 36 import android.widget.ListView;
 37 import android.widget.SectionIndexer;
 38 
 39 
 40 /**
 41  * ListView, which is capable to pin section views at its top while the rest is still scrolled.
 42  */
 43 public class PinnedSectionListView extends ListView {
 44 
 45     //-- inner classes
 46 
 47     /** List adapter to be implemented for being used with PinnedSectionListView adapter. */
 48     public static interface PinnedSectionListAdapter extends ListAdapter {
 49         /** This method shall return 'true' if views of given type has to be pinned. */
 50         boolean isItemViewTypePinned(int viewType);
 51     }
 52 
 53     /** Wrapper class for pinned section view and its position in the list. */
 54     static class PinnedSection {
 55         public View view;
 56         public int position;
 57         public long id;
 58     }
 59 
 60     //-- class fields
 61 
 62     // fields used for handling touch events
 63     private final Rect mTouchRect = new Rect();
 64     private final PointF mTouchPoint = new PointF();
 65     private int mTouchSlop;
 66     private View mTouchTarget;
 67     private MotionEvent mDownEvent;
 68 
 69     // fields used for drawing shadow under a pinned section
 70     private GradientDrawable mShadowDrawable;
 71     private int mSectionsDistanceY;
 72     private int mShadowHeight;
 73 
 74     /** Delegating listener, can be null. */
 75     OnScrollListener mDelegateOnScrollListener;
 76 
 77     /** Shadow for being recycled, can be null. */
 78     PinnedSection mRecycleSection;
 79 
 80     /** shadow instance with a pinned view, can be null. */
 81     PinnedSection mPinnedSection;
 82 
 83     /** Pinned view Y-translation. We use it to stick pinned view to the next section. */
 84     int mTranslateY;
 85 
 86     /** Scroll listener which does the magic */
 87     private final OnScrollListener mOnScrollListener = new OnScrollListener() {
 88 
 89         @Override public void onScrollStateChanged(AbsListView view, int scrollState) {
 90             if (mDelegateOnScrollListener != null) { // delegate
 91                 mDelegateOnScrollListener.onScrollStateChanged(view, scrollState);
 92             }
 93         }
 94 
 95         @Override
 96         public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
 97 
 98             if (mDelegateOnScrollListener != null) { // delegate
 99                 mDelegateOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
100             }
101 
102             // get expected adapter or fail fast
103             ListAdapter adapter = getAdapter();
104             if (adapter == null || visibleItemCount == 0) return; // nothing to do
105 
106             final boolean isFirstVisibleItemSection =
107                     isItemViewTypePinned(adapter, adapter.getItemViewType(firstVisibleItem));
108 
109             if (isFirstVisibleItemSection) {
110                 View sectionView = getChildAt(0);
111                 if (sectionView.getTop() == getPaddingTop()) { // view sticks to the top, no need for pinned shadow
112                     destroyPinnedShadow();
113                 } else { // section doesn't stick to the top, make sure we have a pinned shadow
114                     ensureShadowForPosition(firstVisibleItem, firstVisibleItem, visibleItemCount);
115                 }
116 
117             } else { // section is not at the first visible position
118                 int sectionPosition = findCurrentSectionPosition(firstVisibleItem);
119                 if (sectionPosition > -1) { // we have section position
120                     ensureShadowForPosition(sectionPosition, firstVisibleItem, visibleItemCount);
121                 } else { // there is no section for the first visible item, destroy shadow
122                     destroyPinnedShadow();
123                 }
124             }
125         };
126 
127     };
128 
129     /** Default change observer. */
130     private final DataSetObserver mDataSetObserver = new DataSetObserver() {
131         @Override public void onChanged() {
132             recreatePinnedShadow();
133         };
134         @Override public void onInvalidated() {
135             recreatePinnedShadow();
136         }
137     };
138 
139     //-- constructors
140 
141     public PinnedSectionListView(Context context, AttributeSet attrs) {
142         super(context, attrs);
143         initView();
144     }
145 
146     public PinnedSectionListView(Context context, AttributeSet attrs, int defStyle) {
147         super(context, attrs, defStyle);
148         initView();
149     }
150 
151     private void initView() {
152         setOnScrollListener(mOnScrollListener);
153         mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
154         initShadow(true);
155     }
156 
157     //-- public API methods
158 
159     public void setShadowVisible(boolean visible) {
160         initShadow(visible);
161         if (mPinnedSection != null) {
162             View v = mPinnedSection.view;
163             invalidate(v.getLeft(), v.getTop(), v.getRight(), v.getBottom() + mShadowHeight);
164         }
165     }
166 
167     //-- pinned section drawing methods
168 
169     public void initShadow(boolean visible) {
170         if (visible) {
171             if (mShadowDrawable == null) {
172                 mShadowDrawable = new GradientDrawable(Orientation.TOP_BOTTOM,
173                         new int[] { Color.parseColor("#ffa0a0a0"), Color.parseColor("#50a0a0a0"), Color.parseColor("#00a0a0a0")});
174                 mShadowHeight = (int) (8 * getResources().getDisplayMetrics().density);
175             }
176         } else {
177             if (mShadowDrawable != null) {
178                 mShadowDrawable = null;
179                 mShadowHeight = 0;
180             }
181         }
182     }
183 
184     /** Create shadow wrapper with a pinned view for a view at given position */
185     void createPinnedShadow(int position) {
186 
187         // try to recycle shadow
188         PinnedSection pinnedShadow = mRecycleSection;
189         mRecycleSection = null;
190 
191         // create new shadow, if needed
192         if (pinnedShadow == null) pinnedShadow = new PinnedSection();
193         // request new view using recycled view, if such
194         View pinnedView = getAdapter().getView(position, pinnedShadow.view, PinnedSectionListView.this);
195 
196         // read layout parameters
197         LayoutParams layoutParams = (LayoutParams) pinnedView.getLayoutParams();
198         if (layoutParams == null) {
199             layoutParams = (LayoutParams) generateDefaultLayoutParams();
200             pinnedView.setLayoutParams(layoutParams);
201         }
202 
203         int heightMode = MeasureSpec.getMode(layoutParams.height);
204         int heightSize = MeasureSpec.getSize(layoutParams.height);
205 
206         if (heightMode == MeasureSpec.UNSPECIFIED) heightMode = MeasureSpec.EXACTLY;
207 
208         int maxHeight = getHeight() - getListPaddingTop() - getListPaddingBottom();
209         if (heightSize > maxHeight) heightSize = maxHeight;
210 
211         // measure & layout
212         int ws = MeasureSpec.makeMeasureSpec(getWidth() - getListPaddingLeft() - getListPaddingRight(), MeasureSpec.EXACTLY);
213         int hs = MeasureSpec.makeMeasureSpec(heightSize, heightMode);
214         pinnedView.measure(ws, hs);
215         pinnedView.layout(0, 0, pinnedView.getMeasuredWidth(), pinnedView.getMeasuredHeight());
216         mTranslateY = 0;
217 
218         // initialize pinned shadow
219         pinnedShadow.view = pinnedView;
220         pinnedShadow.position = position;
221         pinnedShadow.id = getAdapter().getItemId(position);
222 
223         // store pinned shadow
224         mPinnedSection = pinnedShadow;
225     }
226 
227     /** Destroy shadow wrapper for currently pinned view */
228     void destroyPinnedShadow() {
229         if (mPinnedSection != null) {
230             // keep shadow for being recycled later
231             mRecycleSection = mPinnedSection;
232             mPinnedSection = null;
233         }
234     }
235 
236     /** Makes sure we have an actual pinned shadow for given position. */
237     void ensureShadowForPosition(int sectionPosition, int firstVisibleItem, int visibleItemCount) {
238         if (visibleItemCount < 2) { // no need for creating shadow at all, we have a single visible item
239             destroyPinnedShadow();
240             return;
241         }
242 
243         if (mPinnedSection != null
244                 && mPinnedSection.position != sectionPosition) { // invalidate shadow, if required
245             destroyPinnedShadow();
246         }
247 
248         if (mPinnedSection == null) { // create shadow, if empty
249             createPinnedShadow(sectionPosition);
250         }
251 
252         // align shadow according to next section position, if needed
253         int nextPosition = sectionPosition + 1;
254         if (nextPosition < getCount()) {
255             int nextSectionPosition = findFirstVisibleSectionPosition(nextPosition,
256                     visibleItemCount - (nextPosition - firstVisibleItem));
257             if (nextSectionPosition > -1) {
258                 View nextSectionView = getChildAt(nextSectionPosition - firstVisibleItem);
259                 final int bottom = mPinnedSection.view.getBottom() + getPaddingTop();
260                 mSectionsDistanceY = nextSectionView.getTop() - bottom;
261                 if (mSectionsDistanceY < 0) {
262                     // next section overlaps pinned shadow, move it up
263                     mTranslateY = mSectionsDistanceY;
264                 } else {
265                     // next section does not overlap with pinned, stick to top
266                     mTranslateY = 0;
267                 }
268             } else {
269                 // no other sections are visible, stick to top
270                 mTranslateY = 0;
271                 mSectionsDistanceY = Integer.MAX_VALUE;
272             }
273         }
274 
275     }
276 
277     int findFirstVisibleSectionPosition(int firstVisibleItem, int visibleItemCount) {
278         ListAdapter adapter = getAdapter();
279 
280         int adapterDataCount = adapter.getCount();
281         if (getLastVisiblePosition() >= adapterDataCount) return -1; // dataset has changed, no candidate
282 
283         if (firstVisibleItem+visibleItemCount >= adapterDataCount){//added to prevent index Outofbound (in case)
284             visibleItemCount = adapterDataCount-firstVisibleItem;
285         }
286 
287         for (int childIndex = 0; childIndex < visibleItemCount; childIndex++) {
288             int position = firstVisibleItem + childIndex;
289             int viewType = adapter.getItemViewType(position);
290             if (isItemViewTypePinned(adapter, viewType)) return position;
291         }
292         return -1;
293     }
294 
295     int findCurrentSectionPosition(int fromPosition) {
296         ListAdapter adapter = getAdapter();
297 
298         if (fromPosition >= adapter.getCount()) return -1; // dataset has changed, no candidate
299         
300         if (adapter instanceof SectionIndexer) {
301             // try fast way by asking section indexer
302             SectionIndexer indexer = (SectionIndexer) adapter;
303             int sectionPosition = indexer.getSectionForPosition(fromPosition);
304             int itemPosition = indexer.getPositionForSection(sectionPosition);
305             int typeView = adapter.getItemViewType(itemPosition);
306             if (isItemViewTypePinned(adapter, typeView)) {
307                 return itemPosition;
308             } // else, no luck
309         }
310 
311         // try slow way by looking through to the next section item above
312         for (int position=fromPosition; position>=0; position--) {
313             int viewType = adapter.getItemViewType(position);
314             if (isItemViewTypePinned(adapter, viewType)) return position;
315         }
316         return -1; // no candidate found
317     }
318 
319     void recreatePinnedShadow() {
320         destroyPinnedShadow();
321         ListAdapter adapter = getAdapter();
322         if (adapter != null && adapter.getCount() > 0) {
323             int firstVisiblePosition = getFirstVisiblePosition();
324             int sectionPosition = findCurrentSectionPosition(firstVisiblePosition);
325             if (sectionPosition == -1) return; // no views to pin, exit
326             ensureShadowForPosition(sectionPosition,
327                     firstVisiblePosition, getLastVisiblePosition() - firstVisiblePosition);
328         }
329     }
330 
331     @Override
332     public void setOnScrollListener(OnScrollListener listener) {
333         if (listener == mOnScrollListener) {
334             super.setOnScrollListener(listener);
335         } else {
336             mDelegateOnScrollListener = listener;
337         }
338     }
339 
340     @Override
341     public void onRestoreInstanceState(Parcelable state) {
342         super.onRestoreInstanceState(state);
343         post(new Runnable() {
344             @Override public void run() { // restore pinned view after configuration change
345                 recreatePinnedShadow();
346             }
347         });
348     }
349 
350     @Override
351     public void setAdapter(ListAdapter adapter) {
352 
353         // assert adapter in debug mode
354         if (BuildConfig.DEBUG && adapter != null) {
355             if (!(adapter instanceof PinnedSectionListAdapter))
356                 throw new IllegalArgumentException("Does your adapter implement PinnedSectionListAdapter?");
357             if (adapter.getViewTypeCount() < 2)
358                 throw new IllegalArgumentException("Does your adapter handle at least two types" +
359                         " of views in getViewTypeCount() method: items and sections?");
360         }
361 
362         // unregister observer at old adapter and register on new one
363         ListAdapter oldAdapter = getAdapter();
364         if (oldAdapter != null) oldAdapter.unregisterDataSetObserver(mDataSetObserver);
365         if (adapter != null) adapter.registerDataSetObserver(mDataSetObserver);
366 
367         // destroy pinned shadow, if new adapter is not same as old one
368         if (oldAdapter != adapter) destroyPinnedShadow();
369 
370         super.setAdapter(adapter);
371     }
372 
373     @Override
374     protected void onLayout(boolean changed, int l, int t, int r, int b) {
375         super.onLayout(changed, l, t, r, b);
376         if (mPinnedSection != null) {
377             int parentWidth = r - l - getPaddingLeft() - getPaddingRight();
378             int shadowWidth = mPinnedSection.view.getWidth();
379             if (parentWidth != shadowWidth) {
380                 recreatePinnedShadow();
381             }
382         }
383     }
384 
385     @Override
386     protected void dispatchDraw(Canvas canvas) {
387         super.dispatchDraw(canvas);
388 
389         if (mPinnedSection != null) {
390 
391             // prepare variables
392             int pLeft = getListPaddingLeft();
393             int pTop = getListPaddingTop();
394             View view = mPinnedSection.view;
395 
396             // draw child
397             canvas.save();
398 
399             int clipHeight = view.getHeight() +
400                     (mShadowDrawable == null ? 0 : Math.min(mShadowHeight, mSectionsDistanceY));
401             canvas.clipRect(pLeft, pTop, pLeft + view.getWidth(), pTop + clipHeight);
402 
403             canvas.translate(pLeft, pTop + mTranslateY);
404             drawChild(canvas, mPinnedSection.view, getDrawingTime());
405 
406             if (mShadowDrawable != null && mSectionsDistanceY > 0) {
407                 mShadowDrawable.setBounds(mPinnedSection.view.getLeft(),
408                         mPinnedSection.view.getBottom(),
409                         mPinnedSection.view.getRight(),
410                         mPinnedSection.view.getBottom() + mShadowHeight);
411                 mShadowDrawable.draw(canvas);
412             }
413 
414             canvas.restore();
415         }
416     }
417 
418     //-- touch handling methods
419 
420     @Override
421     public boolean dispatchTouchEvent(MotionEvent ev) {
422 
423         final float x = ev.getX();
424         final float y = ev.getY();
425         final int action = ev.getAction();
426 
427         if (action == MotionEvent.ACTION_DOWN
428                 && mTouchTarget == null
429                 && mPinnedSection != null
430                 && isPinnedViewTouched(mPinnedSection.view, x, y)) { // create touch target
431 
432             // user touched pinned view
433             mTouchTarget = mPinnedSection.view;
434             mTouchPoint.x = x;
435             mTouchPoint.y = y;
436 
437             // copy down event for eventually be used later
438             mDownEvent = MotionEvent.obtain(ev);
439         }
440 
441         if (mTouchTarget != null) {
442             if (isPinnedViewTouched(mTouchTarget, x, y)) { // forward event to pinned view
443                 mTouchTarget.dispatchTouchEvent(ev);
444             }
445 
446             if (action == MotionEvent.ACTION_UP) { // perform onClick on pinned view
447                 super.dispatchTouchEvent(ev);
448                 performPinnedItemClick();
449                 clearTouchTarget();
450 
451             } else if (action == MotionEvent.ACTION_CANCEL) { // cancel
452                 clearTouchTarget();
453 
454             } else if (action == MotionEvent.ACTION_MOVE) {
455                 if (Math.abs(y - mTouchPoint.y) > mTouchSlop) {
456 
457                     // cancel sequence on touch target
458                     MotionEvent event = MotionEvent.obtain(ev);
459                     event.setAction(MotionEvent.ACTION_CANCEL);
460                     mTouchTarget.dispatchTouchEvent(event);
461                     event.recycle();
462 
463                     // provide correct sequence to super class for further handling
464                     super.dispatchTouchEvent(mDownEvent);
465                     super.dispatchTouchEvent(ev);
466                     clearTouchTarget();
467 
468                 }
469             }
470 
471             return true;
472         }
473 
474         // call super if this was not our pinned view
475         return super.dispatchTouchEvent(ev);
476     }
477 
478     private boolean isPinnedViewTouched(View view, float x, float y) {
479         view.getHitRect(mTouchRect);
480 
481         // by taping top or bottom padding, the list performs on click on a border item.
482         // we don't add top padding here to keep behavior consistent.
483         mTouchRect.top += mTranslateY;
484 
485         mTouchRect.bottom += mTranslateY + getPaddingTop();
486         mTouchRect.left += getPaddingLeft();
487         mTouchRect.right -= getPaddingRight();
488         return mTouchRect.contains((int)x, (int)y);
489     }
490 
491     private void clearTouchTarget() {
492         mTouchTarget = null;
493         if (mDownEvent != null) {
494             mDownEvent.recycle();
495             mDownEvent = null;
496         }
497     }
498 
499     private boolean performPinnedItemClick() {
500         if (mPinnedSection == null) return false;
501 
502         OnItemClickListener listener = getOnItemClickListener();
503         if (listener != null && getAdapter().isEnabled(mPinnedSection.position)) {
504             View view =  mPinnedSection.view;
505             playSoundEffect(SoundEffectConstants.CLICK);
506             if (view != null) {
507                 view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
508             }
509             listener.onItemClick(this, view, mPinnedSection.position, mPinnedSection.id);
510             return true;
511         }
512         return false;
513     }
514 
515     public static boolean isItemViewTypePinned(ListAdapter adapter, int viewType) {
516         if (adapter instanceof HeaderViewListAdapter) {
517             adapter = ((HeaderViewListAdapter)adapter).getWrappedAdapter();
518         }
519         return ((PinnedSectionListAdapter) adapter).isItemViewTypePinned(viewType);
520     }
521 
522 }

 

自己app的代碼:

  1 package com.lixu.biaoqianxuanting;
  2 
  3 import java.util.ArrayList;
  4 import com.lixu.biaoqianxuanting.PinnedSectionListView.PinnedSectionListAdapter;
  5 import android.app.Activity;
  6 import android.content.Context;
  7 import android.graphics.Color;
  8 import android.os.Bundle;
  9 import android.view.LayoutInflater;
 10 import android.view.View;
 11 import android.view.ViewGroup;
 12 import android.widget.ArrayAdapter;
 13 import android.widget.TextView;
 14 
 15 public class MainActivity extends Activity {
 16     private ArrayList<Data> data;
 17 
 18     @Override
 19     protected void onCreate(Bundle savedInstanceState) {
 20         super.onCreate(savedInstanceState);
 21         setContentView(R.layout.activity_main);
 22 
 23         String[] s = { "家人", "朋友", "同事", "同學", "基友", "情人", "老婆" };
 24 
 25         data = new ArrayList<Data>();
 26         for (String n : s) {
 27             Data group = new Data();
 28             group.type = Data.GROUP;
 29             group.text = n;
 30             data.add(group);
 31             for (int i = 0; i < 10; i++) {
 32                 Data child = new Data();
 33                 child.type = Data.CHILD;
 34                 child.text = "聯系人" + i;
 35                 data.add(child);
 36             }
 37         }
 38 
 39         PinnedSectionListView pslv = (PinnedSectionListView) findViewById(R.id.pslv);
 40         MyAdapter mMyAdapter = new MyAdapter(this, -1);
 41         pslv.setAdapter(mMyAdapter);
 42     }
 43 
 44     // 定義一個存放數據類型的類
 45     private class Data {
 46         public static final int GROUP = 0;
 47         public static final int CHILD = 1;
 48         public int type;
 49         public String text;
 50         // 2個type child和group
 51         public static final int TYPE_COUNT = 2;
 52 
 53     }
 54 
 55     // 定義適配器要實現PinnedSectionListAdapter接口 來調用isItemViewTypePinned(int
 56     // viewType)方法
 57     private class MyAdapter extends ArrayAdapter implements PinnedSectionListAdapter {
 58         private LayoutInflater flater;
 59 
 60         public MyAdapter(Context context, int resource) {
 61             super(context, resource);
 62 
 63             flater = LayoutInflater.from(context);
 64         }
 65 
 66         @Override
 67         public int getCount() {
 68             return data.size();
 69         }
 70 
 71         @Override
 72         public View getView(int position, View convertView, ViewGroup parent) {
 73             int type = getItemViewType(position);
 74             switch (type) {
 75             case Data.GROUP:
 76                 if (convertView == null)
 77                     convertView = flater.inflate(android.R.layout.simple_list_item_1, null);
 78 
 79                 TextView tv1 = (TextView) convertView.findViewById(android.R.id.text1);
 80 
 81                 tv1.setText(data.get(position).text);
 82                 tv1.setBackgroundColor(Color.BLUE);
 83                 tv1.setTextSize(35);
 84 
 85                 break;
 86 
 87             case Data.CHILD:
 88                 if (convertView == null)
 89                     convertView = flater.inflate(android.R.layout.simple_list_item_1, null);
 90 
 91                 TextView tv2 = (TextView) convertView.findViewById(android.R.id.text1);
 92 
 93                 tv2.setText(data.get(position).text);
 94 
 95                 tv2.setTextSize(15);
 96 
 97                 break;
 98 
 99             default:
100                 break;
101             }
102 
103             return convertView;
104         }
105 
106         // 返回列表類型 兩種 child和group
107         @Override
108         public int getViewTypeCount() {
109 
110             return Data.TYPE_COUNT;
111         }
112 
113         // 獲取列表類型
114         @Override
115         public int getItemViewType(int position) {
116             return data.get(position).type;
117         }
118 
119         @Override
120         public Object getItem(int position) {
121             return data.get(position);
122         }
123 
124         // 假設此方法返回皆為false。那麼PinnedSectionListView將退化成為一個基礎的ListView.
125         // 只不過退化後的ListView只是一個擁有兩個View Type的ListView。
126         // 從某種角度上講,此方法對於PinnedSectionListView至關重要,因為返回值true或false,將直接導致PinnedSectionListView是一個PinnedSectionListView,還是一個普通的ListView。
127         @Override
128         public boolean isItemViewTypePinned(int viewType) {
129             boolean type = false;
130             switch (viewType) {
131             case Data.GROUP:
132 
133                 type = true;
134 
135                 break;
136 
137             case Data.CHILD:
138 
139                 type = false;
140 
141                 break;
142             default:
143                 type = false;
144                 break;
145             }
146             return type;
147         }
148 
149     }
150 
151 }

xml文件:

 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent" >
 5 
 6     <com.lixu.biaoqianxuanting.PinnedSectionListView
 7         android:id="@+id/pslv"
 8         android:layout_width="match_parent"
 9         android:layout_height="match_parent" />
10 
11 </RelativeLayout>


運行效果圖:

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved