您的位置:首页 > 其它

[置顶] 打造自己的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,我们来进行基本的布局和适配器吧这个都会的。

布局:

<?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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐