x写控件挺麻烦的,因为有很多细节要处理好,列表控件使用太频繁了,网上也各种自定义的方法,一般的listview自定义肯定会联想到加个头部,然后监听事件加动画,其实方式很多种,今天记录的方式是另外一种方式,个人觉得复用性更强,写好了可以通用,思路就是在不动原列表控件的情况下给它上面 ...
x写控件挺麻烦的,因为有很多细节要处理好,列表控件使用太频繁了,网上也各种自定义的方法,一般的listview自定义肯定会联想到加个头部,然后监听事件加动画,其实方式很多种,今天记录的方式是另外一种方式,个人觉得复用性更强,写好了可以通用,思路就是在不动原列表控件的情况下给它上面套个壳,然后让壳来操作刷新显示,这样的话是不是以后要用的时候加个壳就行了,而且我可以基本上不管里面的控件是什么。
下载地址: http://download.csdn.net/detail/u010864175/9805339
<??><LinearLayout ="http://schemas.android.com/apk/res/android" ="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="cn.com.listwebview.demo.MainActivity"> <cn.com.listwebview.demo.ListRefreshLayout android:id="@+id/refreshLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#f4a148" android:orientation="vertical" > <ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#dff19a" android:divider="#595958"/> <!--<android.support.v7.widget.RecyclerView--> <!--android:id="@+id/recyclerview"--> <!--android:divider="#ffff0000"--> <!--android:dividerHeight="10dp"--> <!--android:background="#dff19a"--> <!--android:layout_width="match_parent"--> <!--android:layout_height="match_parent" />--> </cn.com.listwebview.demo.ListRefreshLayout></LinearLayout>
有了头部还得要漂亮的动画啊,增强体验,动画就随自己配置了,本身控件的动画就是两个箭头我这里是加了个自定义的视图来做动画,绘制了几个圆圈,可以根据自己的需要调制,毕竟头部是一个小的容器布局,展示的头部也都是在这个布局里面,所以可以任意搭配。
底部就简单的以同样的思路来做的了,同样是通过滑动上拉来展示刷新的底部和启动动画(个人觉得滑动后加载体验好点,不太喜欢直接滑到顶就显示加载了),底部实现简单了点,就添加了一个底部的布局(这里添加是加载好
HeaderView
package cn.com.listwebview.demo;import android.animation.ValueAnimator;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.util.AttributeSet;import android.view.View;import android.view.animation.DecelerateInterpolator;import cn.com.listwebview.demo.utils.DensityUtil;/** * Created by LiuZhen on 2017/3/28. */public class HeaderView extends View { private Paint mPath; ValueAnimator animator1, animator2; private float r; float fraction1; float fraction2; boolean animating = false; private int num = 5; private int cir_x = 0; public HeaderView(Context context) { this(context, null, 0); } public HeaderView(Context context, AttributeSet attrs) { this(context, attrs,0); } public HeaderView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { r = DensityUtil.dp2px(getContext(), 6); mPath = new Paint(); mPath.setAntiAlias(true); mPath.setColor(Color.rgb(114, 114, 114)); animator1 = ValueAnimator.ofFloat(1f, 1.2f, 1f, 0.8f);//从左到右过渡 animator1.setDuration(800); animator1.setInterpolator(new DecelerateInterpolator());//DecelerateInterpolator减速插补器 animator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { fraction1 = (float) animation.getAnimatedValue();//监听动画运动值 invalidate(); } }); animator1.setRepeatCount(ValueAnimator.INFINITE);//设置重复次数为无限次 animator1.setRepeatMode(ValueAnimator.REVERSE);//RESTART是直接重新播放 animator2 = ValueAnimator.ofFloat(1f, 0.8f, 1f, 1.2f); animator2.setDuration(800); animator2.setInterpolator(new DecelerateInterpolator()); animator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { fraction2 = (float) animation.getAnimatedValue(); } }); animator2.setRepeatCount(ValueAnimator.INFINITE); animator2.setRepeatMode(ValueAnimator.REVERSE); } @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(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; } } else { switch (i) { 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, 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, mPath); break; case 2: mPath.setAlpha(255); mPath.setColor(getResources().getColor(R.color.Blue)); canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, r, 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, 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, mPath); break; } } } } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); if (animator1 != null) animator1.cancel(); if (animator2 != null) animator2.cancel(); } public View getView() { return this; } public void onPullingDown(float fraction) { setScaleX(1 + fraction / 2); setScaleY(1 + fraction / 2); animating = false; if (animator1.isRunning()) { animator1.cancel(); invalidate(); } if (animator2.isRunning()) animator2.cancel(); } public void startAnim() { animating = true; if (!animator1.isRunning()) animator1.start(); if (!animator2.isRunning()) animator2.start(); } public void reset() { animating false; if (animator1.isRunning()) animator1.cancel(); if (animator2.isRunning()) animator2.cancel(); invalidate(); }}= HeaderView
<??><FrameLayout ="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/iv_listview_header_arrow_left" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:minWidth="30dip" android:visibility="visible" android:src='/images/loading.gif' data-original="@drawable/common_listview_headview_red_arrow" /> <ImageView android:id="@+id/iv_listview_header_arrow_right" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical|right" android:minWidth="30dip" android:visibility="visible" android:src='/images/loading.gif' data-original="@drawable/common_listview_headview_red_arrow" /> <!--<!– android:indeterminateDrawable="@drawable/common_progressbar",--> <!--利用rotate旋转动画 + shape的颜色变化 构造ProgressBar的旋转颜色 –>--> <!--<ProgressBar--> <!--android:padding="10dp"--> <!--android:id="@+id/pb_listview_header"--> <!--android:layout_width="wrap_content"--> <!--android:layout_height="wrap_content"--> <!--android:layout_gravity="center_vertical"--> <!----> <!--android:visibility="gone" />--></FrameLayout>
原标题:listview reclyerview上下拉刷新
关键词:ie
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:
admin#shaoqun.com
(#换成@)。