Shreyash Mahajan
Shreyash Mahajan

Reputation: 23596

Android PullTo Refresh on ScrollView

I know that pullToRefresh like functionality is available in the iPhone and for the Android we have to manage it manually.

I got some example the having pullToRefresh but it works on the ListView only.

In my case I want to implement for the Scrollview. Something like PullToRefresh available in DrawFree app in Google Play.

Please see below image:

enter image description here

So, how to implement it?

Upvotes: 2

Views: 17444

Answers (2)

Dhruvil Patel
Dhruvil Patel

Reputation: 2930

This is a excellent example of implementing pull to refresh in ListView, GridView, WebView, Expandable ListView.

You can use this example and make changes according to your Views.

https://github.com/chrisbanes/Android-PullToRefresh

Upvotes: 12

Lorenzo Barbagli
Lorenzo Barbagli

Reputation: 1281

[EDIT: my solution is Gmail-like, I'm sorry if it's not exactly what you want, anyway I post the code that may be usefull for others]

I've just done it, I've already implemented it in a ListView following the example written by Joe Dailey (very good and simple). Then I revisited it to be used with ScrollView.

This is what I've done:

I set an onTouchListener to the ScrollView;

I control if the scrollView is on top (scrollView.getScrollY() == 0) Then, I use "lastY = startY" to know if I'm scrolling down or up (both the variables are activity fields).

"act.refresh()" is the method that runs the task to get data from my server.

In the onPostExecute method of your asynkTask, or in the Handler if you use hanlders, you call "finishRefresh()" method;

this is the onTouchListener:

class RefreshTouchListener implements View.OnTouchListener {

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        ScrollView scroll = (ScrollView) v;
        if (scroll.getScrollY() == 0) {
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startY = event.getY();
                lastY = startY;
                break;
            case MotionEvent.ACTION_MOVE:
                if (!refreshing && event.getY() > lastY) {

                    lastY = event.getY();
                    if (event.getY() - startY <= dragLength) {
                        double percent = 1 - (event.getY() - startY) / dragLength;
                        double weight;
                        weight = 2 * Math.pow(percent, 0.8);
                        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) progress.getLayoutParams();
                        params.weight = (float) weight;
                        progress.setLayoutParams(params);
                        progress.setIndeterminate(false);
                        progress.setPadding(0, 0, 0, 0);
                        return true;
                    } else {
                        refreshing = true;

                        act.refresh();
                        startY = 100000f;
                        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) progress.getLayoutParams();
                        params.weight = 0;
                        progress.setIndeterminate(true);
                        progress.postInvalidate();
                        progress.setLayoutParams(params);
                    }
                }
            case MotionEvent.ACTION_UP:
                startY = 100000f;
                Log.i(TAG, "action up " + event.getY());
                if (!refreshing) {
                    LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) progress.getLayoutParams();
                    params.weight = 2;
                    progress.setLayoutParams(params);
                }
            }
        }
        return false;
    }
}

this is the finishRefresh() method:

public void finishRefresh() {
    progress.setIndeterminate(false);
    progress.postInvalidate();
    LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) progress.getLayoutParams();
    params.weight = 2;
    progress.setLayoutParams(params);
    refreshing = false;
}

this is the code to generate the layout, with the progressBar and everything else:

private void createProgressBarLayout() {
    topMargin = -Math.round(6 * act.metrics.density);
    dragLength = Math.round(act.screen_size.y / 2.5f);

    LinearLayout top = new LinearLayout(this);
    top.setGravity(Gravity.TOP);
    top.setOrientation(LinearLayout.HORIZONTAL);

    content_rel_layout = (RelativeLayout) findViewById(R.id.rel_layout_name);
    content_rel_layout.addView(top);
    ViewGroup.LayoutParams topParams = top.getLayoutParams();
    topParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
    topParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
    top.setLayoutParams(topParams);

    FrameLayout left = new FrameLayout(this);
    progress = new ProgressBar(this, null, android.R.attr.progressBarStyleHorizontal);
    progress.setProgress(100);
    progress.setIndeterminate(false);
    // progress.setBackgroundResource(R.drawable.progress_bar);
    FrameLayout right = new FrameLayout(this);

    top.addView(left);
    top.addView(progress);
    top.addView(right);

    LinearLayout.LayoutParams leftParams = (LinearLayout.LayoutParams) left.getLayoutParams();
    leftParams.weight = 1;
    leftParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
    leftParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
    leftParams.topMargin = topMargin;
    left.setLayoutParams(leftParams);

    LinearLayout.LayoutParams progressParams = (LinearLayout.LayoutParams) progress.getLayoutParams();
    progressParams.weight = 2;
    progressParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
    progressParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
    progressParams.topMargin = topMargin;

    progress.setLayoutParams(progressParams);

    LinearLayout.LayoutParams rightParams = (LinearLayout.LayoutParams) right.getLayoutParams();
    rightParams.weight = 1;
    rightParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
    rightParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
    rightParams.topMargin = topMargin;

    right.setLayoutParams(rightParams);

    ScrollView sv = (ScrollView) findViewById(R.id.prof_mon4_vert_scroll);
    sv.setOnTouchListener(new RefreshTouchListener());
}

Please feel free to ask me for every doubt! Enjoy

Upvotes: 4

Related Questions