Code Monkey home page Code Monkey logo

ultimaterefreshview's Introduction

Download

UltimateRefreshView

预览

功能

  • 支持ListView,RecycleView,ScrollView,WebView
  • 一行代码指定是否支持上拉加载,下拉刷新
  • 自由定制刷新时头部和尾部的动画效果

使用方式

首先,是引入库

compile 'com.reoobter:ultrapullview:1.0.0'

其次,实现各自的动画效果

这里我们就以美团APP顶部下拉刷新的动画为例来看看如何实现动画效果

meituan_header_refresh_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:gravity="center"
              android:background="@color/white"
              android:orientation="vertical">
    <ImageView
        android:id="@+id/loading"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_margin="10dp"
        android:scaleX="0"
        android:scaleY="0"
        android:src="@drawable/pull_image"/>
</LinearLayout>

这个布局文件很简单,整个只有一个ImageView。我们的实现思路,就是在不同的结点修改ImageView的内容,从而呈现出整个下拉刷新时所有的动画效果。那么这些结点是哪些呢?

public class MeiTuanHeaderAdapter extends BaseHeaderAdapter {

    private ImageView loading;
    private int viewHeight;
    private float pull_distance=0;

    public MeiTuanHeaderAdapter(Context context) {
        super(context);
    }

    @Override
    public View getHeaderView() {
        View mView = mInflater.inflate(R.layout.meituan_header_refresh_layout, null, false);
        loading = (ImageView) mView.findViewById(R.id.loading);
        MeasureTools.measureView(mView);
        viewHeight = mView.getMeasuredHeight();
        return mView;
    }

    @Override
    public void pullViewToRefresh(int deltaY) {
        //这里乘以0.3 是因为UltimateRefreshView 源码中对于滑动有0.3的阻尼系数,为了保持一致
        pull_distance=pull_distance+deltaY*0.3f;
        float scale = pull_distance / viewHeight;
        loading.setScaleX(scale);
        loading.setScaleY(scale);

    }


    @Override
    public void releaseViewToRefresh(int deltaY) {
        loading.setImageResource(R.drawable.mei_tuan_loading_pre);
        AnimationDrawable mAnimationDrawable= (AnimationDrawable) loading.getDrawable();
        mAnimationDrawable.start();
    }

    @Override
    public void headerRefreshing() {
        loading.setImageResource(R.drawable.mei_tuan_loading);
        AnimationDrawable mAnimationDrawable= (AnimationDrawable) loading.getDrawable();
        mAnimationDrawable.start();
    }

    @Override
    public void headerRefreshComplete() {
        loading.setImageResource(R.drawable.pull_image);
        loading.setScaleX(0);
        loading.setScaleY(0);
        pull_distance=0;
    }
}

通过代码我们可以总结出有4个重要的结点

  • 下拉进行时,这个时候随着手指滑动,整个顶部的view逐渐显示出来
  • 顶部view完全被下拉出来,这个时候顶部view已经完全显示出来了,手指释放(抬起)后将进入下一个结点。
  • 正在刷新进行时,刷新进行时,这个结点就是刷新动画执行的时候。
  • 刷新完成,在这个结点触发了刷新完成的动作

为了实现美团顶部刷新动画的效果,在第一个结点我们便开始执行动画,根据刷新的位移比,使用scale动画逐渐放大初始图片(绿色椭圆);在第二个结点,这个结点一般都很短暂,这个时候顶部已经完全展示,执行了小人偶翻转出现的动画;在第三个结点,这个结点一般是比较耗时的,在这里用帧动画播放了一个小人偶左右摇摆的动画;最后,在第四个结点,将所有内容初始化到下拉之前的状态,方便下次下拉刷星动画的执行。这样就完成了一次下拉刷新的动画效果。

最后,将动画效果适配到UltimateRefreshView之上

这里就以ListView为例。

首先是布局实现:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:tools="http://schemas.android.com/tools"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:background="@color/white"
             tools:context=".subfragment.ListViewFragment"
    >

    <com.sak.ultilviewlib.UltimateRefreshView
        android:id="@+id/refreshView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white"
        android:orientation="vertical">

        <ListView
            android:id="@+id/listView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="none"/>

    </com.sak.ultilviewlib.UltimateRefreshView>

</FrameLayout>

布局文件很简单,将所要实现的下拉刷新的控件放在UltimateRefreshView控件内即可。

public class ListViewFragment extends Fragment {
    private UltimateRefreshView mUltimateRefreshView;

    private int page = 0;
    private int PER_PAGE_NUM = 15;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_list_view, container, false);
        initView(view);
        return view;
    }

    private void initView(View view) {
        View headview = LayoutInflater.from(getContext()).inflate(R.layout.list_headview_layout,
                null, false);
        ListView listView = (ListView) view.findViewById(R.id.listView);
        final List<String> datas = new ArrayList<>();
        for (int i = 0; i < PER_PAGE_NUM; i++) {
            datas.add("this is item " + i);
        }
        final ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_list_item_1, datas);
        listView.setAdapter(adapter);
        listView.addHeaderView(headview);
        mUltimateRefreshView = (UltimateRefreshView) view.findViewById(R.id.refreshView);
        mUltimateRefreshView.setBaseHeaderAdapter(new MeiTuanHeaderAdapter(getContext()));
        mUltimateRefreshView.setBaseFooterAdapter();
        mUltimateRefreshView.setOnHeaderRefreshListener(new OnHeaderRefreshListener() {
            @Override
            public void onHeaderRefresh(UltimateRefreshView view) {
                page = 0;
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        datas.clear();
                        for (int i = page * PER_PAGE_NUM; i < PER_PAGE_NUM; i++) {
                            datas.add("this is item " + i);
                        }
                        adapter.notifyDataSetChanged();
                        mUltimateRefreshView.onHeaderRefreshComplete();
                    }
                }, 2000);
            }
        });

        mUltimateRefreshView.setOnFooterRefreshListener(new OnFooterRefreshListener() {
            @Override
            public void onFooterRefresh(UltimateRefreshView view) {
                page++;
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        for (int i = page * PER_PAGE_NUM; i < (page + 1) * PER_PAGE_NUM; i++) {
                            datas.add("this is item " + i);
                        }
                        adapter.notifyDataSetChanged();
                        mUltimateRefreshView.onFooterRefreshComplete();
                    }
                }, 200);
            }
        });
    }

}

效果图

更多详细说明

ultimaterefreshview's People

Contributors

rebooters avatar wongxd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

ultimaterefreshview's Issues

Not issue just asking

How to disable the header refreshing??
because i just want to use the footer refreshing

Nested Scrollview not supporting with this library

<com.sak.ultilviewlib.UltimateRefreshView
android:id="@+id/pullToRefresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <androidx.core.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="none">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <LinearLayout
                    android:id="@+id/infoLayout"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="16dp"
                    android:layout_marginTop="24dp"
                    android:layout_marginEnd="16dp"
                    android:layout_marginBottom="32dp"
                    android:baselineAligned="false"
                    android:orientation="horizontal"
                    android:visibility="visible">

                    <FrameLayout
                        android:id="@+id/taxFree"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_weight="0.25">

                        <androidx.appcompat.widget.AppCompatTextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_gravity="center"
                            android:drawableTop="@drawable/ic_dash_taxfree"
                            android:drawablePadding="4dp"
                            android:gravity="center_horizontal"
                            android:lineSpacingExtra="6sp"
                            android:text="@string/HOM_00004"
                            android:textColor="@color/descColor"
                            android:textSize="10sp"
                            tools:ignore="SmallSp" />

                    </FrameLayout>

                    <FrameLayout
                        android:id="@+id/plus"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_weight="0.25">

                        <androidx.appcompat.widget.AppCompatTextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_gravity="center"
                            android:drawableTop="@drawable/ic_home_plus"
                            android:drawablePadding="4dp"
                            android:gravity="center_horizontal"
                            android:lineSpacingExtra="6sp"
                            android:text="@string/HOM_00009"
                            android:textColor="@color/descColor"
                            android:textSize="10sp"
                            tools:ignore="SmallSp" />

                    </FrameLayout>

                    <FrameLayout
                        android:id="@+id/bookings"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_weight="0.25">

                        <androidx.appcompat.widget.AppCompatTextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_gravity="center"
                            android:drawableTop="@drawable/ic_dash_bookings"
                            android:drawablePadding="4dp"
                            android:gravity="center_horizontal"
                            android:lineSpacingExtra="6sp"
                            android:text="@string/BOOK_00001"
                            android:textColor="@color/descColor"
                            android:textSize="10sp"
                            tools:ignore="SmallSp" />

                    </FrameLayout>

                    <FrameLayout
                        android:id="@+id/cityGuide"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_weight="0.25">

                        <androidx.appcompat.widget.AppCompatTextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_gravity="center"
                            android:drawableTop="@drawable/ic_dash_guide"
                            android:drawablePadding="4dp"
                            android:gravity="center_horizontal"
                            android:lineSpacingExtra="6sp"
                            android:text="@string/HOM_00006"
                            android:textColor="@color/descColor"
                            android:textSize="10sp"
                            android:visibility="visible"
                            tools:ignore="SmallSp" />
                    </FrameLayout>

                </LinearLayout>

                <androidx.appcompat.widget.AppCompatTextView
                    android:id="@+id/homeTitle"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="16dp"
                    android:layout_marginEnd="16dp"
                    android:fontFamily="@font/notosans_bold"
                    android:maxLines="1"
                    android:textColor="@color/headingColor"
                    android:textSize="16sp"
                    android:visibility="gone" />

                <androidx.appcompat.widget.AppCompatTextView
                    android:id="@+id/homeDesc"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="16dp"
                    android:layout_marginTop="5dp"
                    android:layout_marginEnd="16dp"
                    android:ellipsize="end"
                    android:fontFamily="@font/notosans_regular"
                    android:textColor="@color/descColor"
                    android:textSize="14sp"
                    android:visibility="gone" />

                <androidx.recyclerview.widget.RecyclerView
                    android:id="@+id/homeCMS"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_marginBottom="32dp"
                    app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

                <LinearLayout
                    android:id="@+id/feedbackLayout"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="29dp"
                    android:orientation="vertical"
                    android:visibility="gone">

                    <androidx.appcompat.widget.AppCompatTextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        android:fontFamily="@font/notosans_regular"
                        android:text="@string/HOM_00007"
                        android:textColor="@color/darkBlack"
                        android:textSize="14sp" />

                    <androidx.appcompat.widget.AppCompatTextView
                        android:id="@+id/sendFeedback"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        android:fontFamily="@font/notosans_bold"
                        android:text="@string/HOM_00008"
                        android:textColor="@color/colorAccent"
                        android:textSize="14sp" />

                </LinearLayout>

            </LinearLayout>

        </androidx.core.widget.NestedScrollView>
    </com.sak.ultilviewlib.UltimateRefreshView>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.