[置顶] 打造自己的RecylerView,GridView,ListView...下拉刷新和上啦加载的动画真的很简单。
2017-11-29 18:11
369 查看
一,自定义自己项目的刷新效果:
很多时候我们项目也许需要自己的刷新效果。如果我们达不到那种自定义刷新控件的力,那么来看看这篇文章吧!!!基于(TwinklingRefreshLayout和SwipeToLoadLayout)都是给变头布局来实现的。
二,看看我们公司的需求:
刚下拉时候,有一个小医生慢慢出现变大变亮,后面一个下拉刷新的文字,当松开手时候文字变
为正在刷新中。
上啦加载时候:同样一个医生出现变大变亮。
三,实现过程:
1,需要很多的图片你不会ps么?找美工吧。反正我会我自己ps搞的图片但时候在项目中有的。
来个图片不然你们不信:我把48x48最为最大,然后ps图像大小然后逐个变小储存。
2,我们来新建一个项目吧!然后进入gradle里面写去依赖这句话
compile ‘com.lcodecorex:tkrefreshlayout:1.0.3’就可以用TwinklingRefreshLayout了。
3,我们来进行基本的布局和适配器吧这个都会的。
布局:
适配器:
最重要的来了。一个好的开源框架不可能不提供给开发者拓展的接口。那么我们去看看源码呗:
首先我们直接运行我们会发现有默认的刷新效果如下:
既然有默认的我们可以点击该控件进去看看源码:
我们会发现一些熟悉的变量:
其中有一个
我们看注释就知道头部的layout,然后我们顺藤摸瓜,找到这里:
我看到这句话:
当mHeadView为空时候我们看到有一个GoogleDotView(getContext())谷歌什么view控件来填充,我们
点进去看看呗,我们会发现我去,居然这里搞了那几个圆圈圈动画之类的:
我们发现这个GogleDotView实现了IHeaderView 接口,我们去看看吧:
好了这里我一切都清除了,我们需要定义一个view类实现这个IHeaderView,和IBottomView接口或者内部类也可以的。这里我两种都搞一稿,必进写在activity内部扩展不太好。由于我太懒,我一个类就同时实现了这两个接口,其实这样感觉少一个类挺简洁的,你们根据自己的喜好弄吧。代码如下:
第二种就是本类中写,这样真的好么。我不推荐这样写,复用性太差了代码每次写都要一大堆,自己看着办吧,我这里不贴代码了,我的Demon里面有的。运行如下图:
最后github贴出来:https://github.com/luhenchang/FreshDemon_Luhenchang.git
很多时候我们项目也许需要自己的刷新效果。如果我们达不到那种自定义刷新控件的力,那么来看看这篇文章吧!!!基于(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 4000 ="@+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 maxHeadH c619 eight * @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
相关文章推荐
- Android打造(ListView、GridView等)通用的下拉刷新、上拉自动加载的组件
- androdd下拉刷新上拉加载支持listview,scrollview,recyclerview,gridview
- 打造通用的Android下拉刷新组件(适用于ListView、GridView等各类View)
- 精通RecyclerView:打造ListView、GridView、瀑布流;学会添加分割线、 添加删除动画 、Item点击事件
- Android打造(ListView、GridView等)通用的下拉刷新、上拉自动加载的组件
- 打造通用的Android下拉刷新组件(适用于ListView、GridView等各类View)
- 打造自己的RecyclerView(二)之下拉刷新和上拉加载更多
- Android打造(ListView、GridView等)通用的下拉刷新、上拉自动加载的组件
- Android打造(ListView、GridView等)通用的下拉刷新、上拉自动加载的组件
- 打造通用的Android下拉刷新组件(适用于ListView、GridView等各类View)
- Android打造(ListView、GridView等)通用的下拉刷新、上拉自动加载的组件
- Android RecyclerView+item动画+下拉刷新,上拉加载更多,侧滑删除(易用可定制)
- 为自己记------android中listview下拉刷新和下拉加载的原理及简单实现
- RecylerView的使用(相当于Listview和 GridView)
- RecylerView---代替ListView,GridView和瀑布流的新控件
- Android仿XListView支持下拉刷新和上划加载更多的自定义RecyclerView
- Android中给listview/gridview设置动画(逐条加载条目动画)
- recycleView 多条目加载 + 下拉刷新 +GridView 与 ListView 切换
- 打造Android集合控件数据绑定(支持添加监听,支持AbsListView与RecycleView,支持异步加载等)(一)基础篇
- 自己定制ListView,上拉刷新和下拉刷新,加载网络图片,并且添加缓存机制。