打造自己的RecylerView,GridView,ListView...下拉刷新和上啦加载的动画真的很简单。

来源:互联网 发布:香奁润色 知乎 编辑:程序博客网 时间:2024/06/05 01:19

一,自定义自己项目的刷新效果:

很多时候我们项目也许需要自己的刷新效果。如果我们达不到那种自定义刷新控件的力,那么来看看这篇文章吧!!!基于(TwinklingRefreshLayout和SwipeToLoadLayout)都是给变头布局来实现的。

二,看看我们公司的需求:

刚下拉时候,有一个小医生慢慢出现变大变亮,后面一个下拉刷新的文字,当松开手时候文字变
为正在刷新中。
上啦加载时候:同样一个医生出现变大变亮。

这里写图片描述

三,实现过程:
1,需要很多的图片你不会ps么?找美工吧。反正我会我自己ps搞的图片但时候在项目中有的。
来个图片不然你们不信:我把48x48最为最大,然后ps图像大小然后逐个变小储存。
这里写图片描述
2,我们来新建一个项目吧!然后进入gradle里面写去依赖这句话
compile ‘com.lcodecorex:tkrefreshlayout:1.0.3’就可以用TwinklingRefreshLayout了。

3,我们来进行基本的布局和适配器吧这个都会的。
布局:

<?xml version="1.0" encoding="utf-8"?><com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:id="@+id/refreshLayout"    android:scrollbars="none"    android:layout_height="match_parent"    >    <android.support.v7.widget.RecyclerView        android:background="#ffffff"        android:layout_below="@+id/ling_item1"        android:id="@+id/activity_last_infor_rv"        android:layout_width="match_parent"        android:layout_height="wrap_content"/></com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout>

适配器:

/** * Created by ls on 2017/11/14. */public class LastInforAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {    private Context mContext;    private List<String> mData;    public LastInforAdapter(Context mContext, List<String> mData) {        this.mContext = mContext;        this.mData = mData;    }    @Override    public int getItemCount() {        return mData == null ? 0 : mData.size();    }    @Override    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        View view = LayoutInflater.from(mContext).inflate(R.layout.my_item, null);        FirstViewHolder holder = new FirstViewHolder(view, mContext);        return holder;    }    @Override    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {        FirstViewHolder holder1 = (FirstViewHolder) holder;        holder1.setData(mData.get(position), position);    }    class FirstViewHolder extends RecyclerView.ViewHolder {        private Context mContex;        private TextView first_view;        public FirstViewHolder(View itemView, Context mContex) {            super(itemView);            this.mContex = mContex;            first_view=itemView.findViewById(R.id.tv_my);        }        public void setData(String str, final int position) {           first_view.setText(str);        }    }}

最重要的来了。一个好的开源框架不可能不提供给开发者拓展的接口。那么我们去看看源码呗:

首先我们直接运行我们会发现有默认的刷新效果如下:

这里写图片描述

这里写图片描述

既然有默认的我们可以点击该控件进去看看源码:
我们会发现一些熟悉的变量:

 //子控件    private View mChildView;    //头部layout    protected FrameLayout mHeadLayout;    private IHeaderView mHeadView;    private IBottomView mBottomView;    //底部高度    private float mBottomHeight;    //底部layout    private FrameLayout mBottomLayout;    //刷新的状态    protected boolean isRefreshing;    //加载更多的状态    protected boolean isLoadingmore;    //是否需要加载更多,默认需要    protected boolean enableLoadmore = true;    //是否需要下拉刷新,默认需要    protected boolean enableRefresh = true;    //是否在越界回弹的时候显示下拉图标    protected boolean isOverlayRefreshShow = true;

其中有一个

//头部layout    protected FrameLayout mHeadLayout;

我们看注释就知道头部的layout,然后我们顺藤摸瓜,找到这里:

 //添加头部        if (mHeadLayout == null) {            FrameLayout headViewLayout = new FrameLayout(getContext());            LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0);            layoutParams.gravity = Gravity.TOP;            headViewLayout.setLayoutParams(layoutParams);            mHeadLayout = headViewLayout;            this.addView(mHeadLayout);//addView(view,-1)添加到-1的位置            if (mHeadView == null) setHeaderView(new GoogleDotView(getContext()));        }        //添加底部        if (mBottomLayout == null) {            FrameLayout bottomViewLayout = new FrameLayout(getContext());            LayoutParams layoutParams2 = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0);            layoutParams2.gravity = Gravity.BOTTOM;            bottomViewLayout.setLayoutParams(layoutParams2);            mBottomLayout = bottomViewLayout;            this.addView(mBottomLayout);            if (mBottomView == null) {                BottomProgressView mProgressView = new BottomProgressView(getContext());                setBottomView(mProgressView);            }        }

我看到这句话:

 if (mHeadView == null) setHeaderView(new GoogleDotView(getContext()));

当mHeadView为空时候我们看到有一个GoogleDotView(getContext())谷歌什么view控件来填充,我们
点进去看看呗,我们会发现我去,居然这里搞了那几个圆圈圈动画之类的:

 @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        int w = getMeasuredWidth() / num - 10;        for (int i = 0; i < num; i++) {            if (animating) {                switch (i) {                    //                    case 0:                    //                        mPath.setAlpha(35);                    //                        mPath.setColor(getResources().getColor(R.color.Orange));                    //                        canvas.drawCircle(getMeasuredWidth() / 2 - cir_x * 3 - 3 * w / 3 * 2, getMeasuredHeight() / 2, r*fraction2, mPath);                    //                        break;                    case 0:                        mPath.setAlpha(105);                        mPath.setColor(getResources().getColor(R.color.Yellow));                        canvas.drawCircle(getMeasuredWidth() / 2 - cir_x * 2 - 2 * w / 3 * 2, getMeasuredHeight() / 2, r * fraction2, mPath);                        break;                    case 1:                        mPath.setAlpha(145);                        mPath.setColor(getResources().getColor(R.color.Green));                        canvas.drawCircle(getMeasuredWidth() / 2 - cir_x * 1 - w / 3 * 2, getMeasuredHeight() / 2, r * fraction2, mPath);                        break;                    case 2:                        mPath.setAlpha(255);                        mPath.setColor(getResources().getColor(R.color.Blue));                        canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, r * fraction1, mPath);                        break;                    case 3:                        mPath.setAlpha(145);                        mPath.setColor(getResources().getColor(R.color.Orange));                        canvas.drawCircle(getMeasuredWidth() / 2 + cir_x * 1 + w / 3 * 2, getMeasuredHeight() / 2, r * fraction2, mPath);                        break;                    case 4:                        mPath.setAlpha(105);                        mPath.setColor(getResources().getColor(R.color.Yellow));                        canvas.drawCircle(getMeasuredWidth() / 2 + cir_x * 2 + 2 * w / 3 * 2, getMeasuredHeight() / 2, r * fraction2, mPath);                        break;                    //                    case 6

我们发现这个GogleDotView实现了IHeaderView 接口,我们去看看吧:

public interface IHeaderView {    View getView();    /**     * 下拉准备刷新动作     * @param fraction  当前下拉高度与总高度的比     * @param maxHeadHeight     * @param headHeight     */    void onPullingDown(float fraction,float maxHeadHeight,float headHeight);    /**     * 下拉释放过程     * @param fraction     * @param maxHeadHeight     * @param headHeight     */    void onPullReleasing(float fraction,float maxHeadHeight,float headHeight);    void startAnim(float maxHeadHeight,float headHeight);    void onFinish();}

好了这里我一切都清除了,我们需要定义一个view类实现这个IHeaderView,和IBottomView接口或者内部类也可以的。这里我两种都搞一稿,必进写在activity内部扩展不太好。由于我太懒,我一个类就同时实现了这两个接口,其实这样感觉少一个类挺简洁的,你们根据自己的喜好弄吧。代码如下:

public class MyGoleView extends View implements IHeaderView, IBottomView {    private Context mcontext;    //这个是下拉式上部的显示文本    private TextView refrush_tv;    //最后给这个图片设置动画就可以了。    private ImageView refrush_image;    //设置帧动画用的    private AnimationDrawable animationDrawable;    //这个用来判断是下拉还是上拉    private int up_down = 0;//默认为上哈哈其他就为下了。    public MyGoleView(Context context, int up_down) {        super(context);        this.mcontext = context;        this.up_down = up_down;    }    public MyGoleView(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);    }    @Override    public View getView() {        if (up_down == 0) {            View view = LayoutInflater.from(mcontext).inflate(R.layout.refrush_header, null);            refrush_tv = view.findViewById(R.id.refrush_tv);            refrush_image = view.findViewById(R.id.refrush_image);            return view;        } else {            View view = LayoutInflater.from(mcontext).inflate(R.layout.refrush_bootom, null);            refrush_image = view.findViewById(R.id.refrush_image1);            return view;        }    }    @Override    public void onPullingUp(float fraction, float maxHeadHeight, float headHeight) {         //这里当上啦过过程中的操锁自己试试看。我懒不想研究了。    }    @Override    public void onPullingDown(float fraction, float maxHeadHeight, float headHeight) {       //我在上啦过程中布局里面没有设置文字哦!!看看我的item就知道了        if (refrush_tv != null) {            refrush_tv.setText("下拉刷新");        }    }    @Override    public void onPullReleasing(float fraction, float maxHeadHeight, float headHeight) {        if (refrush_tv != null) {            refrush_tv.setText("正在刷新中");        }    }    @Override    public void startAnim(float maxHeadHeight, float headHeight) {        //这里是我们的动画哦!!!        refrush_image.setBackgroundResource(R.drawable.anim_loading_view);        animationDrawable = (AnimationDrawable)                refrush_image.getBackground();        animationDrawable.start();    }    @Override    public void onFinish() {        animationDrawable.stop();    }}

第二种就是本类中写,这样真的好么。我不推荐这样写,复用性太差了代码每次写都要一大堆,自己看着办吧,我这里不贴代码了,我的Demon里面有的。运行如下图:

这里写图片描述

这里写图片描述

最后github贴出来:https://github.com/luhenchang/FreshDemon_Luhenchang.git

阅读全文
0 0
原创粉丝点击