Android PinnedSectionListView异常崩溃报错

Android PinnedSectionListView异常崩溃报错:java.lang.ClassCastException: android.view.ViewGroup$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams


Android PinnedSectionListView是一个良好的第三方开源悬停分组ListView,其在github上的项目主页是:https://github.com/beworker/pinned-section-listview ,在涉及到一些联系人分组,好友分组等需要对ListView进行分组的情况下,使用起来效果不错。

但是作为开源项目,本身也在不停的迭代和完善中,最近(截止2015年11月26日)发现PinnedSectionListView在一些Android SDK版本中运行时候异常崩溃报错,如图:



报错的关键内容是:

[plain]  view plain copy
  1. java.lang.ClassCastException: android.view.ViewGroup$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams  

错误内容提示在PinnedSectionListView.java的202行出现错误,这是PinnedSectionListView.java源代码中的原始内容:

[java]  view plain copy
  1. // read layout parameters  
  2.         LayoutParams layoutParams = (LayoutParams) pinnedView.getLayoutParams();  
  3.         if (layoutParams == null) {  
  4.             layoutParams = (LayoutParams) generateDefaultLayoutParams();  
  5.             pinnedView.setLayoutParams(layoutParams);  
  6.         }  
如图:

Android PinnedSectionListView异常崩溃报错_第1张图片


经由研究发现,此原因是在调用Android系统的generateDefaultLayoutParams()方法时候,发生异常,致使代码运行获得的结果layoutParams不正常,进而导致PinnedSectionListView崩溃。


解决方案:
自己动手重写Android系统的generateDefaultLayoutParams()方法,返回自己定制的LayoutParams值。

具体实现:
在PinnedSectionListView.java中增加自己重写的generateDefaultLayoutParams()方法:

[java]  view plain copy
  1. //add by Zhang Phil @CSDN  
  2.    @Override  
  3.    protected ViewGroup.LayoutParams generateDefaultLayoutParams() {  
  4.       
  5.     LayoutParams mLayoutParams=new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);  
  6.       
  7.     return mLayoutParams;  
  8.    }  

最终修复bug,改进后的PinnedSectionListView.java全部源代码为:

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

你可能感兴趣的:(Android PinnedSectionListView异常崩溃报错)