2017-05-19 1 views
0

私は、リストビューをプルするときにデータをリロードするためにPullToRefreshListViewを使用しています。PullToRefreshListViewの上にスペースが残る

しかし私の問題は、リフレッシュ後、レイアウトはリストビューの上にスペースを残してしまうことです。以下の画像を参照してください: enter image description here

上部のスペースを削除します。ビューをView.GONEに設定しようとしましたが、まだ小さなスペースが残っています。

ここにPullToRefreshListView.javaのコードを示します。 package com.markupartist.android.widget;

import android.content.Context; 
import android.graphics.Color; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.ViewGroup; 
import android.view.animation.LinearInterpolator; 
import android.view.animation.RotateAnimation; 
import android.widget.AbsListView; 
import android.widget.ImageView; 
import android.widget.ListAdapter; 
import android.widget.ListView; 
import android.widget.ProgressBar; 
import android.widget.RelativeLayout; 
import android.widget.TextView; 
import android.widget.AbsListView.OnScrollListener; 



public class PullToRefreshListView extends ListView implements OnScrollListener { 

    private static final int TAP_TO_REFRESH = 1; 
    private static final int PULL_TO_REFRESH = 2; 
    private static final int RELEASE_TO_REFRESH = 3; 
    private static final int REFRESHING = 4; 

    private static final String TAG = "PullToRefreshListView"; 

    private OnRefreshListener mOnRefreshListener; 

    /** 
    * Listener that will receive notifications every time the list scrolls. 
    */ 
    private OnScrollListener mOnScrollListener; 
    private LayoutInflater mInflater; 

    private RelativeLayout mRefreshView; 
    private TextView mRefreshViewText; 
    private ImageView mRefreshViewImage; 
    private ProgressBar mRefreshViewProgress; 
    private TextView mRefreshViewLastUpdated; 

    private int mCurrentScrollState; 
    private int mRefreshState; 

    private RotateAnimation mFlipAnimation; 
    private RotateAnimation mReverseFlipAnimation; 

    private int mRefreshViewHeight; 
    private int mRefreshOriginalTopPadding; 
    private int mLastMotionY; 

    private boolean mBounceHack; 

    public PullToRefreshListView(Context context) { 
     super(context); 
     init(context); 
    } 

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

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

    private void init(Context context) { 
     // Load all of the animations we need in code rather than through XML 
     mFlipAnimation = new RotateAnimation(0, -180, 
       RotateAnimation.RELATIVE_TO_SELF, 0.5f, 
       RotateAnimation.RELATIVE_TO_SELF, 0.5f); 
     mFlipAnimation.setInterpolator(new LinearInterpolator()); 
     mFlipAnimation.setDuration(250); 
     mFlipAnimation.setFillAfter(true); 
     mReverseFlipAnimation = new RotateAnimation(-180, 0, 
       RotateAnimation.RELATIVE_TO_SELF, 0.5f, 
       RotateAnimation.RELATIVE_TO_SELF, 0.5f); 
     mReverseFlipAnimation.setInterpolator(new LinearInterpolator()); 
     mReverseFlipAnimation.setDuration(250); 
     mReverseFlipAnimation.setFillAfter(true); 

     mInflater = (LayoutInflater) context.getSystemService(
       Context.LAYOUT_INFLATER_SERVICE); 

     mRefreshView = (RelativeLayout) mInflater.inflate(
       R.layout.pull_to_refresh_header, this, false); 
     mRefreshViewText = 
      (TextView) mRefreshView.findViewById(R.id.pull_to_refresh_text); 
     mRefreshViewImage = 
      (ImageView) mRefreshView.findViewById(R.id.pull_to_refresh_image); 
     mRefreshViewProgress = 
      (ProgressBar) mRefreshView.findViewById(R.id.pull_to_refresh_progress); 
     mRefreshViewLastUpdated = 
      (TextView) mRefreshView.findViewById(R.id.pull_to_refresh_updated_at); 

     mRefreshViewImage.setMinimumHeight(50); 
     mRefreshView.setOnClickListener(new OnClickRefreshListener()); 
     mRefreshOriginalTopPadding = mRefreshView.getPaddingTop(); 

     mRefreshState = TAP_TO_REFRESH; 

     addHeaderView(mRefreshView); 

     super.setOnScrollListener(this); 

     measureView(mRefreshView); 
     mRefreshViewHeight = mRefreshView.getMeasuredHeight(); 
    } 

    @Override 
    protected void onAttachedToWindow() { 
     super.onAttachedToWindow(); 
     setSelection(1); 
    } 

    @Override 
    public void setAdapter(ListAdapter adapter) { 
     super.setAdapter(adapter); 
     setSelection(1); 
    } 

    /** 
    * Set the listener that will receive notifications every time the list 
    * scrolls. 
    * 
    * @param l The scroll listener. 
    */ 
    @Override 
    public void setOnScrollListener(OnScrollListener l) { 
     mOnScrollListener = l; 
    } 

    /** 
    * Register a callback to be invoked when this list should be refreshed. 
    * 
    * @param onRefreshListener The callback to run. 
    */ 
    public void setOnRefreshListener(OnRefreshListener onRefreshListener) { 
     mOnRefreshListener = onRefreshListener; 
    } 

    /** 
    * Set a text to represent when the list was last updated. 
    * @param lastUpdated Last updated at. 
    */ 
    public void setLastUpdated(CharSequence lastUpdated) { 
     if (lastUpdated != null) { 
      mRefreshViewLastUpdated.setVisibility(View.VISIBLE); 
      mRefreshViewLastUpdated.setText(lastUpdated); 
     } else { 
      mRefreshViewLastUpdated.setVisibility(View.GONE); 
     } 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     final int y = (int) event.getY(); 
     mBounceHack = false; 

     switch (event.getAction()) { 
      case MotionEvent.ACTION_UP: 
       if (!isVerticalScrollBarEnabled()) { 
        setVerticalScrollBarEnabled(true); 
       } 
       if (getFirstVisiblePosition() == 0 && mRefreshState != REFRESHING) { 
        if ((mRefreshView.getBottom() >= mRefreshViewHeight 
          || mRefreshView.getTop() >= 0) 
          && mRefreshState == RELEASE_TO_REFRESH) { 
         // Initiate the refresh 
         mRefreshState = REFRESHING; 
         prepareForRefresh(); 
         onRefresh(); 
        } else if (mRefreshView.getBottom() < mRefreshViewHeight 
          || mRefreshView.getTop() <= 0) { 
         // Abort refresh and scroll down below the refresh view 
         resetHeader(); 
         setSelection(1); 
        } 
       } 
       break; 
      case MotionEvent.ACTION_DOWN: 
       mLastMotionY = y; 
       break; 
      case MotionEvent.ACTION_MOVE: 
       applyHeaderPadding(event); 
       break; 
     } 
     return super.onTouchEvent(event); 
    } 

    private void applyHeaderPadding(MotionEvent ev) { 
     // getHistorySize has been available since API 1 
     int pointerCount = ev.getHistorySize(); 

     for (int p = 0; p < pointerCount; p++) { 
      if (mRefreshState == RELEASE_TO_REFRESH) { 
       if (isVerticalFadingEdgeEnabled()) { 
        setVerticalScrollBarEnabled(false); 
       } 

       int historicalY = (int) ev.getHistoricalY(p); 

       // Calculate the padding to apply, we divide by 1.7 to 
       // simulate a more resistant effect during pull. 
       int topPadding = (int) (((historicalY - mLastMotionY) 
         - mRefreshViewHeight)/1.7); 

       mRefreshView.setPadding(
         mRefreshView.getPaddingLeft(), 
         topPadding, 
         mRefreshView.getPaddingRight(), 
         mRefreshView.getPaddingBottom()); 
      } 
     } 
    } 

    /** 
    * Sets the header padding back to original size. 
    */ 
    private void resetHeaderPadding() { 
     Log.i("top padding", "" + mRefreshOriginalTopPadding); 
     mRefreshView.setPadding(
       mRefreshView.getPaddingLeft(), 
       0, 
       mRefreshView.getPaddingRight(), 
       mRefreshView.getPaddingBottom()); 
    } 


    /** 
    * Resets the header to the original state. 
    */ 
    private void resetHeader() { 
     if (mRefreshState != TAP_TO_REFRESH) { 
      mRefreshState = TAP_TO_REFRESH; 

      resetHeaderPadding(); 

      // Set refresh view text to the pull label 
      //mRefreshViewText.setText(R.string.pull_to_refresh_tap_label); 
      //mRefreshViewText.setVisibility(View.GONE); 
      // Replace refresh drawable with arrow drawable 
      mRefreshViewImage.setImageResource(R.drawable.ic_pulltorefresh_arrow); 
      // Clear the full rotation animation 
      mRefreshViewImage.clearAnimation(); 
      // Hide progress bar and arrow. 
      mRefreshViewImage.setVisibility(View.GONE); 
      mRefreshViewProgress.setVisibility(View.GONE); 
      //this.setSelectionAfterHeaderView(); 
     } 
    } 

    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); 
    } 

    @Override 
    public void onScroll(AbsListView view, int firstVisibleItem, 
      int visibleItemCount, int totalItemCount) { 
     // When the refresh view is completely visible, change the text to say 
     // "Release to refresh..." and flip the arrow drawable. 
     if (mCurrentScrollState == SCROLL_STATE_TOUCH_SCROLL 
       && mRefreshState != REFRESHING) { 
      if (firstVisibleItem == 0) { 
       mRefreshViewImage.setVisibility(View.VISIBLE); 
       if ((mRefreshView.getBottom() >= mRefreshViewHeight + 20 
         || mRefreshView.getTop() >= 0) 
         && mRefreshState != RELEASE_TO_REFRESH) { 
        mRefreshViewText.setText(R.string.pull_to_refresh_release_label); 
        mRefreshViewImage.clearAnimation(); 
        mRefreshViewImage.startAnimation(mFlipAnimation); 
        mRefreshState = RELEASE_TO_REFRESH; 
       } else if (mRefreshView.getBottom() < mRefreshViewHeight + 20 
         && mRefreshState != PULL_TO_REFRESH) { 
        mRefreshViewText.setText(R.string.pull_to_refresh_pull_label); 
        if (mRefreshState != TAP_TO_REFRESH) { 
         mRefreshViewImage.clearAnimation(); 
         mRefreshViewImage.startAnimation(mReverseFlipAnimation); 
        } 
        mRefreshState = PULL_TO_REFRESH; 
       } 
      } else { 
       mRefreshViewImage.setVisibility(View.GONE); 
       resetHeader(); 

      } 
     } else if (mCurrentScrollState == SCROLL_STATE_FLING 
       && firstVisibleItem == 0 
       && mRefreshState != REFRESHING) { 
      Log.i("I am here", ""); 
      setSelection(1); 
      mBounceHack = true; 
     } else if (mBounceHack && mCurrentScrollState == SCROLL_STATE_FLING) { 
      setSelection(1); 

     } 

     if (mOnScrollListener != null) { 
      mOnScrollListener.onScroll(view, firstVisibleItem, 
        visibleItemCount, totalItemCount); 

     } 
    } 

    @Override 
    public void onScrollStateChanged(AbsListView view, int scrollState) { 
     mCurrentScrollState = scrollState; 

     if (mCurrentScrollState == SCROLL_STATE_IDLE) { 
      mBounceHack = false; 
     } 

     if (mOnScrollListener != null) { 
      mOnScrollListener.onScrollStateChanged(view, scrollState); 
     } 
    } 

    public void prepareForRefresh() { 
     resetHeaderPadding(); 

     mRefreshViewImage.setVisibility(View.GONE); 
     // We need this hack, otherwise it will keep the previous drawable. 
     mRefreshViewImage.setImageDrawable(null); 
     mRefreshViewProgress.setVisibility(View.VISIBLE); 

     // Set refresh view text to the refreshing label 
     mRefreshViewText.setText(R.string.pull_to_refresh_refreshing_label); 


     mRefreshState = REFRESHING; 
    } 

    public void onRefresh() { 
     Log.d(TAG, "onRefresh"); 

     if (mOnRefreshListener != null) { 
      mOnRefreshListener.onRefresh(); 
     } 
    } 

    /** 
    * Resets the list to a normal state after a refresh. 
    * @param lastUpdated Last updated at. 
    */ 
    public void onRefreshComplete(CharSequence lastUpdated) { 
     setLastUpdated(lastUpdated); 
     onRefreshComplete(); 
    } 

    /** 
    * Resets the list to a normal state after a refresh. 
    */ 
    public void onRefreshComplete() {   
     Log.d(TAG, "onRefreshComplete"); 

     resetHeader(); 

     // If refresh view is visible when loading completes, scroll down to 
     // the next item. 
     if (getFirstVisiblePosition() == 0) { 
      invalidateViews(); 
      setSelection(1); 

     } 
     resetHeader(); 
    } 

    /** 
    * Invoked when the refresh view is clicked on. This is mainly used when 
    * there's only a few items in the list and it's not possible to drag the 
    * list. 
    */ 
    private class OnClickRefreshListener implements OnClickListener { 

     @Override 
     public void onClick(View v) { 
      if (mRefreshState != REFRESHING) { 
       prepareForRefresh(); 
       onRefresh(); 
      } 
     } 

    } 

    /** 
    * Interface definition for a callback to be invoked when list should be 
    * refreshed. 
    */ 
    public interface OnRefreshListener { 
     /** 
     * Called when the list should be refreshed. 
     * <p> 
     * A call to {@link PullToRefreshListView #onRefreshComplete()} is 
     * expected to indicate that the refresh has completed. 
     */ 
     public void onRefresh(); 
    } 
} 

答えて

1

私はただ、無効リストビューonrefreshリスナーとリストビューをリフレッシュする代わりに、プルの 使用android.support.v4.widget.SwipeRefreshLayoutにあなたをお勧めします。それは非常に使いやすいです。

<android.support.v4.widget.SwipeRefreshLayout 
     android:id="@+id/refreshLater" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
    > 

    ***Place Your listview here***   

    </android.support.v4.widget.SwipeRefreshLayout > 

あなたはこのようにそれにリフレッシュリスナーを設定することができます。

public SwipeRefreshLayout swipeRefreshLayout; 
swipeRefreshLayout = (SwipeRefreshLayout)findViewById(R.id.refreshLater); 
swipeRefreshLayout.setOnRefreshListener(this); 

you can do needed code in the below override method: 

@Override 
public void onRefresh() 
{ 
    swipeRefreshLayout.setRefreshing(false); 
} 
+0

ありがとうございました!これはとても簡単に実装できました! –

関連する問題