11

Is it possible ?? as a Title said

swipe down to refresh Layout but stick the Layout not move it down along swipe gusture

Thank you - I'm using SwipeRefreshLayout

Jongz Puangput
  • 5,527
  • 10
  • 58
  • 96
  • To bring SwipeRefreshLayout only when we're on First position, just have a look at my answer: http://stackoverflow.com/a/37314774/5373110 NOTE: I have used the RecyclerView, it should be same logic for ListView with minor changes. – Meet Vora May 19 '16 at 05:57
  • @Meet , no there is not same logic in ListView too. – Rumit Patel Dec 26 '16 at 13:48
  • 参考 [Can't scroll in a ListView in a swipeRefreshLayout](https://stackoverflow.com/questions/27041416/cant-scroll-in-a-listview-in-a-swiperefreshlayout%20%E2%80%9CCan't%20scroll%20in%20a%20ListView%20in%20a%20swipeRefreshLayout%E2%80%9D) – littleOStar Aug 06 '17 at 13:46

5 Answers5

23

You try this way

listView.setOnScrollListener(new OnScrollListener() {

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}

@Override
public void onScroll(AbsListView view, int firstVisibleItem,
        int visibleItemCount, int totalItemCount) {
    boolean enable = false;
    if(listView != null && listView.getChildCount() > 0){
        // check if the first item of the list is visible
        boolean firstItemVisible = listView.getFirstVisiblePosition() == 0;
        // check if the top of the first item is visible
        boolean topOfFirstItemVisible = listView.getChildAt(0).getTop() == 0;
        // enabling or disabling the refresh layout
        enable = firstItemVisible && topOfFirstItemVisible;
    }
    swipeRefreshLayout.setEnabled(enable);
}});

This code doesn't work if listView has paddingTop

Cabezas
  • 9,329
  • 7
  • 67
  • 69
  • 1
    Thanks +1, I would set default to `true` because when your list is empty you won't be able refresh it anyway – deadfish Dec 23 '14 at 22:03
12

After my trial and error, I found one solution from

http://www.dailydevbook.de/android-swiperefreshlayout-without-overscroll/

For people who can implement SwipeRefreshLayout, in order to achieve it


STEP 1: DOWNLOAD android-support v4 (Open Source) from github

STEP 2: COPY following java class to your project src

  • SwipeRefreshLayout
  • SwipeProgressBar
  • BakedBezierInterpolator

note1- (Refactor SwipeRefreshLayout to mySwipeRefreshLayout to prevent confusing with original) note2- (Fix these classes and use the source from each other instead of v4)

STEP 3: UPDATE CODE use

  • mySwipeRefreshLayout instead of
  • SwipeRefreshLayout

STEP 4: UPDATE LAYOUT use

  • com.yourpackage.mySwipeRefreshLaout instead of
  • android.support.v4.widget.SwipeRefreshLayout

STEP 5: In your mySwipeRefreshLayout.java, find and change to a following code

private  void  updateContentOffsetTop ( int  targetTop) {
        final  int  currentTop = mTarget.getTop ();
        if  (targetTop> mDistanceToTriggerSync) {
            targetTop = ( int ) mDistanceToTriggerSync;
        } else  if  (targetTop < 0 ) {
            targetTop = 0 ;
        }
        // SetTargetOffsetTopAndBottom (targetTop - currentTop);
        setTargetOffsetTopAndBottom ( 0 ); // MOD: Prevent Scroll Down Animation
    }
maysi
  • 5,457
  • 12
  • 34
  • 62
Jongz Puangput
  • 5,527
  • 10
  • 58
  • 96
  • 1
    Please provide a better approach @Luke since this is an answer from 2014 – Jongz Puangput Oct 15 '15 at 14:32
  • Using SwipeRefreshLayout with RecyclerView will not scroll down the list. Still, I believe you were using ListView. Alex's answer is more suitable. Your solution, although correct, is not advisable because you will miss future improvements and corrections of these classes. – luksfarris Oct 15 '15 at 16:37
  • There are still year old un fixed bugs out there, if it works, you won't be missing out on anything. – Derek Beattie Dec 08 '15 at 18:07
4

Thanks to Jongz Puangput for the workaround, but I want to suggest another solution, that I find simplier.

In order to prevent pull down of the SwipeRefreshLayout's child you can provide your own child view with overriden offsetTopAndBottom method like this:

public class FixedRelativeLayout extends RelativeLayout {

    ...

    @Override
    public void offsetTopAndBottom(int offset) {
        // Ignoring movement from SwipeRefreshLayout
        super.offsetTopAndBottom(0);
    }

}

That works for me, hope it'll help anybody.

Alex Vasilkov
  • 6,215
  • 4
  • 23
  • 16
4

I was also facing same issue. try this:

guidesList.setOnScrollListener(new AbsListView.OnScrollListener() {  
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int   visibleItemCount, int totalItemCount) {

        int topRowVerticalPosition = (guidesList == null || 
            guidesList.getChildCount() == 0) ? 0 : guidesList.getChildAt(0).getTop();

        swipeContainer.setEnabled(firstVisibleItem == 0 && topRowVerticalPosition >= 0);
    }
});
Rajath
  • 11,787
  • 7
  • 48
  • 62
Noman
  • 4,049
  • 10
  • 38
  • 59
0

You can find out the recycler view currently at the top and by knowing that you can disable or enable SwipeRefreshLayout, let me give an example

let's say you use linear layout manager or grid then you can find out the recycler position from there

        LinearLayoutManager mLayoutManager;
        if (mColumnCount <= 1) {
            mLayoutManager = new LinearLayoutManager(getBaseContext());
        } else {
            mLayoutManager = new GridLayoutManager(getBaseContext(), mColumnCount);
        }

        recyclerAdapter = new RecyclerViewAdapter(allData);
        mRecycler.setAdapter(recyclerAdapter);
        mRecycler.setLayoutManager(layoutManager);

        if (mLayoutManager.findFirstCompletelyVisibleItemPosition() == 0) {
            swipeRefreshLayout.setEnabled(true);
        }
        else{
            swipeRefreshLayout.setEnabled(false);
        }

so your recycler scroll will work fine and if reach the top the swipeRefreshLayout handle the refresh event...

Angga Ari Wijaya
  • 1,759
  • 1
  • 15
  • 31