2012-10-09 3 views
10

का कारण है I ViewPager के साथ PullToRefresh GridView का उपयोग करने का प्रयास कर रहा है जो क्लासकास्ट अपवाद को क्रैश कर रहा है। यह अपवाद है।गतिविधि समूह के अंदर गतिविधि में व्यूअरजर में ग्रिडव्यू को रीफ्रेश करने के लिए पुल का उपयोग क्लासकास्टएक्सप्शन

FATAL EXCEPTION: main java.lang.ClassCastException: android.support.v4.view.ViewPager$LayoutParams 
at android.widget.LinearLayout.measureVertical(LinearLayout.java:360) 
at android.widget.LinearLayout.onMeasure(LinearLayout.java:309) 
at android.view.View.measure(View.java:8313) 
at android.widget.RelativeLayout.measureChild(RelativeLayout.java:566) 
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:381) 
at android.view.View.measure(View.java:8313) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138) 
at android.widget.FrameLayout.onMeasure(FrameLayout.java:250) 
at android.view.View.measure(View.java:8313) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138) 
at android.widget.FrameLayout.onMeasure(FrameLayout.java:250) 
at android.view.View.measure(View.java:8313) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138) 
at android.widget.FrameLayout.onMeasure(FrameLayout.java:250) 
at android.view.View.measure(View.java:8313) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138) 
at android.widget.FrameLayout.onMeasure(FrameLayout.java:250) 
at android.view.View.measure(View.java:8313) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138) 
at android.widget.FrameLayout.onMeasure(FrameLayout.java:250) 
at android.view.View.measure(View.java:8313) 
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:581) 
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:365) 
at android.view.View.measure(View.java:8313) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138) 
at android.widget.FrameLayout.onMeasure(FrameLayout.java:250) 
at android.view.View.measure(View.java:8313) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138) 
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1017) 
at android.widget.LinearLayout.measureVertical(LinearLayout.java:386) 
at android.widget.LinearLayout.onMeasure(LinearLayout.java:309) 
at android.view.View.measure(View.java:8313) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138) 
at android.widget.FrameLayout.onMeasure(FrameLayout.java:250) 
at android.view.View.measure(View.java:8313) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138) 
at android.widget.FrameLayout.onMeasure(FrameLayout.java:250) 
at android.view.View.measure(View.java:8313) 
at android.view.ViewRoot.performTraversals(ViewRoot.java:845) 
at android.view.ViewRoot.handleMessage(ViewRoot.java:1865) 
at android.os.Handler.dispatchMessage(Handler.java:99) 
at android.os.Looper.loop(Looper.java:130) 
at android.app.ActivityThread.main(ActivityThread.java:3687) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:507) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625) 
at dalvik.system.NativeStart.main(Native Method) 

यह कोड स्निपेट है जहां इसे लागू किया गया है।

PULL_TO_REFRESH = (PullToRefreshGridView)findViewById(R.id.groupList); 
mGroupList = PULL_TO_REFRESH.getAdapterView(); 
Vector<View> pages = new Vector<View>(); 

     pages.add(mGroupList); 

     ViewPager vp = (ViewPager)findViewById(R.id.myfivepanelpager); 
     CustomPagerAdapter adapter = new CustomPagerAdapter(this, pages); 
     vp.setAdapter(adapter); 
     // Set a listener to be invoked when the list should be refreshed. 

     PULL_TO_REFRESH.setOnRefreshListener(new OnRefreshListener() { 

      @Override 
      public void onRefresh() { 
       // TODO Auto-generated method stub 


      } 
     }); 

यह जो कारण हो सकते हैं PullToRefresh पुस्तकालय से कोड का टुकड़ा है।

package com.syncusup.pulltorefresh.library.my; 

import android.content.Context; 
import android.os.Handler; 
import android.util.AttributeSet; 
import android.view.LayoutInflater; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.View.OnTouchListener; 
import android.view.ViewGroup; 
import android.view.animation.AccelerateDecelerateInterpolator; 
import android.view.animation.Animation; 
import android.view.animation.Interpolator; 
import android.view.animation.LinearInterpolator; 
import android.view.animation.RotateAnimation; 
import android.widget.AdapterView; 
import android.widget.ImageView; 
import android.widget.LinearLayout; 
import android.widget.ListAdapter; 
import android.widget.ProgressBar; 
import android.widget.TextView; 

import com.syncusup.R; 

public abstract class PullToRefreshBase<T extends AdapterView<ListAdapter>> extends LinearLayout implements 
     OnTouchListener { 

    private final class SmoothScrollRunnable implements Runnable { 

     static final int ANIMATION_DURATION_MS = 190; 
     static final int ANIMATION_FPS = 1000/60; 

     private final Interpolator interpolator; 
     private final int scrollToY; 
     private final int scrollFromY; 
     private final Handler handler; 

     private boolean continueRunning = true; 
     private long startTime = -1; 
     private int currentY = -1; 

     public SmoothScrollRunnable(Handler handler, int fromY, int toY) { 
      this.handler = handler; 
      this.scrollFromY = fromY; 
      this.scrollToY = toY; 
      this.interpolator = new AccelerateDecelerateInterpolator(); 
     } 

     @Override 
     public void run() { 

      /** 
      * Only set startTime if this is the first time we're starting, else 
      * actually calculate the Y delta 
      */ 
      if (startTime == -1) { 
       startTime = System.currentTimeMillis(); 
      } else { 

       /** 
       * We do do all calculations in long to reduce software float 
       * calculations. We use 1000 as it gives us good accuracy and 
       * small rounding errors 
       */ 
       long normalizedTime = (1000 * (System.currentTimeMillis() - startTime))/ANIMATION_DURATION_MS; 
       normalizedTime = Math.max(Math.min(normalizedTime, 1000), 0); 

       final int deltaY = Math.round((scrollFromY - scrollToY) 
         * interpolator.getInterpolation(normalizedTime/1000f)); 
       this.currentY = scrollFromY - deltaY; 
       setHeaderScroll(currentY); 
      } 

      // If we're not at the target Y, keep going... 
      if (continueRunning && scrollToY != currentY) { 
       handler.postDelayed(this, ANIMATION_FPS); 
      } 
     } 

     public void stop() { 
      this.continueRunning = false; 
      this.handler.removeCallbacks(this); 
     } 
    }; 

    // =========================================================== 
    // Constants 
    // =========================================================== 

    static final int PULL_TO_REFRESH = 0; 
    static final int RELEASE_TO_REFRESH = PULL_TO_REFRESH + 1; 
    static final int REFRESHING = RELEASE_TO_REFRESH + 1; 
    static final int EVENT_COUNT = 3; 

    // =========================================================== 
    // Fields 
    // =========================================================== 

    private int state = PULL_TO_REFRESH; 
    private T adapterView; 
    private boolean isPullToRefreshEnabled = true; 

    private ProgressBar headerProgress; 
    private TextView headerText; 
    private ImageView headerImage; 
    private Animation flipAnimation, reverseAnimation; 
    private int headerHeight; 

    private final Handler handler = new Handler(); 

    private OnTouchListener onTouchListener; 
    private OnRefreshListener onRefreshListener; 

    private SmoothScrollRunnable currentSmoothScrollRunnable; 

    private float startY = -1; 
    private final float[] lastYs = new float[EVENT_COUNT]; 

    private String releaseLabel; 
    private String pullLabel; 
    private String refreshingLabel; 

    // =========================================================== 
    // Constructors 
    // =========================================================== 

    public PullToRefreshBase(Context context) { 
     this(context, null); 
    } 

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

    // =========================================================== 
    // Getter & Setter 
    // =========================================================== 

    /** 
    * Get the Wrapped AdapterView. Anything returned here has already been 
    * added to the content view. 
    * 
    * @return The AdapterView which is currently wrapped 
    */ 
    public final T getAdapterView() { 
     return adapterView; 
    } 

    /** 
    * Whether Pull-to-Refresh is enabled 
    * 
    * @return enabled 
    */ 
    public boolean isPullToRefreshEnabled() { 
     return isPullToRefreshEnabled; 
    } 

    /** 
    * Mark the current Refresh as complete. Will Reset the UI and hide the 
    * Refreshing View 
    */ 
    public void onRefreshComplete() { 
     resetHeader(); 
    } 

    public void setOnRefreshListener(OnRefreshListener listener) { 
     onRefreshListener = listener; 
    } 

    /** 
    * A mutator to enable/disable Pull-to-Refresh for the current AdapterView 
    * 
    * @param enable 
    *   Whether Pull-To-Refresh should be used 
    */ 
    public void setPullToRefreshEnabled(boolean enabled) { 
     this.isPullToRefreshEnabled = enabled; 
    } 

    public void setReleaseLabel(String releaseLabel) { 
     this.releaseLabel = releaseLabel; 
    } 

    public void setPullLabel(String pullLabel) { 
     this.pullLabel = pullLabel; 
    } 

    public void setRefreshingLabel(String refreshingLabel) { 
     this.refreshingLabel = refreshingLabel; 
    } 

    public void setHeaderProgress(ProgressBar headerProgress) { 
     this.headerProgress = headerProgress; 
    } 

    // =========================================================== 
    // Methods for/from SuperClass/Interfaces 
    // =========================================================== 

    @Override 
    public void setOnTouchListener(OnTouchListener listener) { 
     onTouchListener = listener; 
    } 

    @Override 
    public boolean onTouch(View view, MotionEvent ev) { 
     if (isPullToRefreshEnabled) { 
      // Returning true here stops the ListView being scrollable while we 
      // refresh 
      if (state == REFRESHING) { 
       return true; 
      } else { 
       return onAdapterViewTouch(view, ev); 
      } 
     } 
     return false; 
    } 

    /** 
    * This is implemented by derived classes to return the created AdapterView. 
    * If you need to use a custom AdapterView (such as a custom ListView), 
    * override this method and return an instance of your custom class. 
    * 
    * Be sure to set the ID of the view in this method, especially if you're 
    * using a ListActivity or ListFragment. 
    * 
    * @param context 
    * @param attrs 
    *   AttributeSet from wrapped class. Means that anything you 
    *   include in the XML layout declaration will be routed to the 
    *   AdapterView 
    * @return New instance of the AdapterView 
    */ 
    protected abstract T createAdapterView(Context context, AttributeSet attrs); 

    // =========================================================== 
    // Methods 
    // =========================================================== 

    protected final void resetHeader() { 
     state = PULL_TO_REFRESH; 
     initializeYsHistory(); 
     startY = -1; 
     headerImage.setVisibility(View.VISIBLE); 
     headerProgress.setVisibility(View.GONE); 

     smoothScrollTo(0); 
    } 

    private void init(Context context, AttributeSet attrs) { 
     setOrientation(LinearLayout.VERTICAL); 

     // Header 
     ViewGroup header = (ViewGroup) LayoutInflater.from(context).inflate(R.layout.pull_to_refresh_header, this, 
       false); 
     headerText = (TextView) header.findViewById(R.id.pull_to_refresh_text); 
     pullLabel = context.getString(R.string.pull_to_refresh_pull_label); 
     refreshingLabel = context.getString(R.string.pull_to_refresh_refreshing_label); 
     releaseLabel = context.getString(R.string.pull_to_refresh_release_label); 
     headerImage = (ImageView) header.findViewById(R.id.pull_to_refresh_image); 
     headerProgress = (ProgressBar) header.findViewById(R.id.pull_to_refresh_progress); 
     addView(header, ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); 
     measureView(header); 
     headerHeight = header.getMeasuredHeight(); 

     // AdapterView 
     // By passing the attrs, we can add ListView/GridView params via XML 
     adapterView = this.createAdapterView(context, attrs); 
     adapterView.setOnTouchListener(this); 
     addView(adapterView, ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT); 

     // Animations 
     flipAnimation = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); 
     flipAnimation.setInterpolator(new LinearInterpolator()); 
     flipAnimation.setDuration(250); 
     flipAnimation.setFillAfter(true); 

     reverseAnimation = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 
       0.5f); 
     reverseAnimation.setInterpolator(new LinearInterpolator()); 
     reverseAnimation.setDuration(250); 
     reverseAnimation.setFillAfter(true); 

     // Hide Header View 
     setPadding(getPaddingLeft(), -headerHeight, getPaddingRight(), getPaddingBottom()); 
    } 

    private void measureView(View child) { 
     ViewGroup.LayoutParams p = child.getLayoutParams(); 
     if (p == null) { 
      p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); 
     } 

     int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width); 
     int lpHeight = p.height; 
     int childHeightSpec; 
     if (lpHeight > 0) { 
      childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY); 
     } else { 
      childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); 
     } 
     child.measure(childWidthSpec, childHeightSpec); 
    } 

    private boolean onAdapterViewTouch(View view, MotionEvent event) { 

     switch (event.getAction()) { 
      case MotionEvent.ACTION_MOVE: 
       updateEventStates(event); 

       if (isPullingDownToRefresh() && startY == -1) { 
        if (startY == -1) { 
         startY = event.getY(); 
        } 
        return false; 
       } 

       if (startY != -1 && !adapterView.isPressed()) { 
        pullDown(event, startY); 
        return true; 
       } 
       break; 
      case MotionEvent.ACTION_UP: 
       initializeYsHistory(); 
       startY = -1; 

       if (state == RELEASE_TO_REFRESH) { 
        setRefreshing(); 
        if (onRefreshListener != null) { 
         onRefreshListener.onRefresh(); 
        } 
       } else { 
        smoothScrollTo(0); 
       } 
       break; 
     } 

     if (null != onTouchListener) { 
      return onTouchListener.onTouch(view, event); 
     } 
     return false; 
    } 

    private void pullDown(MotionEvent event, float firstY) { 
     float averageY = average(lastYs); 

     int height = (int) (Math.max(averageY - firstY, 0)); 
     setHeaderScroll(height); 

     if (state == PULL_TO_REFRESH && headerHeight < height) { 
      state = RELEASE_TO_REFRESH; 
      headerText.setText(releaseLabel); 
      headerImage.clearAnimation(); 
      headerImage.startAnimation(flipAnimation); 
     } 
     if (state == RELEASE_TO_REFRESH && headerHeight >= height) { 
      state = PULL_TO_REFRESH; 
      headerText.setText(pullLabel); 
      headerImage.clearAnimation(); 
      headerImage.startAnimation(reverseAnimation); 
     } 
    } 

    private void setHeaderScroll(int y) { 
     scrollTo(0, -y); 
    } 

    private int getHeaderScroll() { 
     return -getScrollY(); 
    } 

    private void setRefreshing() { 
     state = REFRESHING; 
     headerText.setText(refreshingLabel); 
     headerImage.clearAnimation(); 
     headerImage.setVisibility(View.INVISIBLE); 
     headerProgress.setVisibility(View.VISIBLE); 
     smoothScrollTo(headerHeight); 
    } 

    private float average(float[] ysArray) { 
     float avg = 0; 
     for (int i = 0; i < EVENT_COUNT; i++) { 
      avg += ysArray[i]; 
     } 
     return avg/EVENT_COUNT; 
    } 

    private void initializeYsHistory() { 
     for (int i = 0; i < EVENT_COUNT; i++) { 
      lastYs[i] = 0; 
     } 
    } 

    private void updateEventStates(MotionEvent event) { 
     for (int i = 0; i < EVENT_COUNT - 1; i++) { 
      lastYs[i] = lastYs[i + 1]; 
     } 

     float y = event.getY(); 
     int top = adapterView.getTop(); 
     lastYs[EVENT_COUNT - 1] = y + top; 
    } 

    private boolean isPullingDownToRefresh() { 
     return isPullToRefreshEnabled && state != REFRESHING && isUserDraggingDownwards() && isFirstVisible(); 
    } 

    private boolean isFirstVisible() { 
     if (this.adapterView.getCount() == 0) { 
      return true; 
     } else if (adapterView.getFirstVisiblePosition() == 0) { 
      return adapterView.getChildAt(0).getTop() >= adapterView.getTop(); 
     } else { 
      return false; 
     } 
    } 

    private boolean isUserDraggingDownwards() { 
     return this.isUserDraggingDownwards(0, EVENT_COUNT - 1); 
    } 

    private boolean isUserDraggingDownwards(int from, int to) { 
     return lastYs[from] != 0 && lastYs[to] != 0 && Math.abs(lastYs[from] - lastYs[to]) > 10 
       && lastYs[from] < lastYs[to]; 
    } 

    private void smoothScrollTo(int y) { 
     if (null != currentSmoothScrollRunnable) { 
      currentSmoothScrollRunnable.stop(); 
     } 

     this.currentSmoothScrollRunnable = new SmoothScrollRunnable(handler, getHeaderScroll(), y); 
     handler.post(currentSmoothScrollRunnable); 
    } 

    // =========================================================== 
    // Inner and Anonymous Classes 
    // =========================================================== 

    public static interface OnRefreshListener { 

     public void onRefresh(); 

    } 

} 
+0

मुझे एक ही चीज़ का अनुभव हो रहा है, मैं यह जोड़ूंगा कि यह एपीआई स्तर पर होता है जिसे वास्तव में समर्थन पैकेज (एपीआई 11+) की आवश्यकता होती है। या बाद के संस्करण यह ठीक है। – Sean

+0

आप जांच सकते हैं कि पुस्तकालय समर्थन पुस्तकालय की एक ही फ़ाइल का उपयोग कर रहा है या नहीं। –

उत्तर

1

एक बेहतर जवाब के लिए, मैं CustomPagerAdapter के अपने कार्यान्वयन को देखने के लिए होगा।

लेकिन चूंकि CustomPagerAdapter के निर्माता एक पैरामीटर के रूप Views की एक सरणी/संग्रह/वेक्टर लेता है, यह मान लेना कि CustomPagerAdapter के instantiateItem विधि (या getItem विधि यदि आपके CustomPagerAdapter एक FragmentPagerAdapter है) का उपयोग शोध करे सही होगा ViewsViewPager के पेज बनाने के लिए?

यदि ऐसा है, तो यह आपकी समस्या हो सकती है।

Vector<View> pages परिवर्तनीय Views है जो एक लेआउट का हिस्सा है। इस मामले में, केवल (0) View में mGroupList है। mGroupListalready एक लेआउट का हिस्सा है। आप इस मामले में View (mGroupList नहीं बना सकते हैं) दो अलग-अलग माता-पिता का बच्चा बनें। अपने CustomPagerAdapter (या तो कोड के माध्यम से या उचित लेआउट-एक्सएमएल बढ़ा-चढ़ाकर द्वारा)

'खोज' mGroupList के बजाय

, एक ब्रांड की instantiateItem विधि में नए PullToRefreshGridView पैदा करते हैं। ब्रांड PullToRefreshGridView इंस्टेंस में वहां कोई माता-पिता नहीं होगा और फिर ViewPager का एक बच्चा बन जाएगा जब ViewPager इसे आवश्यक मानता है।

बातें अधिक सरल बनाने के लिए, मैं उपयोग करने का सुझाव एक FragmentPagerAdapter या बजाय FragmentStatePagerAdapter है, जो अपनी getItem विधि में एक उचित Fragment वापस आ जाएगी। Fragment फिर onCreateView विधि में सही दृश्य वापस करेगा, जिसमें PullToRefreshGridView आप चाहते हैं। https://developer.android.com/reference/android/support/v13/app/FragmentPagerAdapter.html

संबंधित मुद्दे