打造自己的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
- 打造自己的RecylerView,GridView,ListView...下拉刷新和上啦加载的动画真的很简单。
- ListView,GridView的下拉刷新和上拉加载。
- Android打造(ListView、GridView等)通用的下拉刷新、上拉自动加载的组件
- Android打造(ListView、GridView等)通用的下拉刷新、上拉自动加载的组件
- Android打造(ListView、GridView等)通用的下拉刷新、上拉自动加载的组件
- Android打造(ListView、GridView等)通用的下拉刷新、上拉自动加载的组件
- RecycleView的上啦加载下拉刷新
- 支持下拉刷新和上啦加载的SwipeRefreshLayout
- 为自己记------android中listview下拉刷新和下拉加载的原理及简单实现
- RecylerView的使用(相当于Listview和 GridView)
- gridview的上拉刷新下拉加载
- GridView的下拉刷新上拉加载
- 再也不用担心下拉刷新,上拉加载啦!-自定义ListView对上拉刷新,上拉加载的详解
- ListView的上拉加载和下拉刷新的使用
- 原来Android ListView下拉刷新真的很简单
- 下拉刷新+上拉加载的listview
- listview的上拉刷新,下拉加载
- listview的上拉加载,下拉刷新
- ESP8266 基础篇:mbedTLS 内存开销分析
- Socket:同步异步 和 阻塞非阻塞的区别
- 我花了两天把接外包的血泪写了出来
- maven新建项目出错webapp 1.0
- redis集群
- 打造自己的RecylerView,GridView,ListView...下拉刷新和上啦加载的动画真的很简单。
- ajax请求添加自定义header参数
- 用Notpad++编辑Linux上的文件
- jqGrid获取表数据
- 微信小程序支付开发笔记1--获取openId
- Java之——编写Shell启动/停止tomcat
- 欢迎使用CSDN-markdown编辑器
- respondsToSelector相关的方法
- 深入理解拉格朗日乘子法(Lagrange Multiplier) 和KKT条件