
Copyright statement: welcome to reprint, reproduced please indicate the source http://prog3.com/sbdm/blog/nugongahou110
A drop-down refresh principle in the article IAndroid custom control of the imitation of the United States to refresh the groupHas been introduced in detail, this article introduces the principle of the dial animation
Car home of the drop-down refresh is divided into three states:
The first state is the to refresh pull, in this state is a dial with the distance from the dynamic change of the angle of the pointer
The second state is the to refresh release, which is an animation of the pointer angle change in this state.
The realization of the first state:
This effect we use custom View to achieve, we get from the car home APK to get the two pictures used to refresh the drop-down:
We will first picture painted on the canvas as the background, then we according to the current schedule value to dynamically rotate canvas, then chapter two pictures on canvas, we see a pointer rotation is actually a canvas in rotation.
@Override
Protected Void OnDraw(canvas Canvas) {
Super.onDraw (canvas);
The first picture / painting on canvas
Canvas.drawBitmap (finalBackGroundBitmap,Zero,Zero,Null);
/ / rotate canvas
Canvas.rotate (mCurrentProgress*Two point sevenF, x/TwoY/.Two);
The second images in painting / rotate canvas
Canvas.drawBitmap (finalPointerBitmap,Zero,Zero,Null);
}
The complete code for the custom View is as follows:
/ * *
* by Zhangqi on 15/10/17. Created
* /
Public Class AutoHome Extends View{
PrivateBackGroundBitmap Bitmap;
PublicPointerBitmap Bitmap;
Private IntX;
Private IntY;
PrivateFinalBackGroundBitmap Bitmap;
PrivateFinalPointerBitmap Bitmap;
Private FloatMCurrentProgress;
Public AutoHome(context Context) {
Super(context);
Init (context);
}
Public AutoHome(context Context, attrs AttributeSet) {
Super(context, attrs);
Init (context);
}
Public AutoHome(context AttributeSet, attrs Context,IntDefStyleAttr) {
Super(context, attrs, defStyleAttr);
Init (context);
}
Private Void Init(context Context) {
BackGroundBitmap = Bitmap.createBitmap (BitmapFactory.decodeResource (context.getResources) (R.drawable.load_icon_dial2x));
PointerBitmap = Bitmap.createBitmap (BitmapFactory.decodeResource (context.getResources) (R.drawable.load_icon_pointer2x));
}
@Override
Protected Void OnMeasure(IntWidthMeasureSpec,IntHeightMeasureSpec) {
SetMeasuredDimension (measureWidth (widthMeasureSpec), measureWidth (heightMeasureSpec));
X = getMeasuredWidth ();
Y = getMeasuredHeight ();
FinalBackGroundBitmap = Bitmap.createScaledBitmap (backGroundBitmap, x, y,False);
FinalPointerBitmap = Bitmap.createScaledBitmap (pointerBitmap, x, y,False);
}
Private Int MeasureWidth(IntWidMeasureSpec) {
IntResult =Zero;
IntSize = MeasureSpec.getSize (widMeasureSpec);
IntMode = MeasureSpec.getMode (widMeasureSpec);
If(mode = = MeasureSpec.EXACTLY) {
Result = size;
}Else{
Result = backGroundBitmap.getWidth ();
If(mode = = MeasureSpec.AT_MOST) {
Result = Math.min (result, size);
}
}
ReturnResult;
}
@Override
Protected Void OnDraw(canvas Canvas) {
Super.onDraw (canvas);
Canvas.drawBitmap (finalBackGroundBitmap,Zero,Zero,Null);
Canvas.rotate (mCurrentProgress*Two point sevenF, x/TwoY/.Two);
Canvas.drawBitmap (finalPointerBitmap,Zero,Zero,Null);
}
Public Void SetCurrentProgress(FloatProgress) {
MCurrentProgress = progress*One hundred;
}
}
Then we use SeekBar in Activity to simulate a progress value, which is passed to us custom View
Public Class 主要活动 延伸 appcompatactivity{
私人mseekbar SeekBar;
私人汽车之家mautohome;
私人 浮mcurrentprogress;
“重写”
受保护的 无效 onCreate(束savedinstancestate){
好极了onCreate(savedinstancestate);
setContentView(r.layout。activity_main);
mseekbar =(SeekBar)findViewById(r.id.seekbar);
mautohome =(Autohome)findViewById(r.id.autohome);
mseekbar setonseekbarchangelistener(。新的SeekBar。onseekbarchangelistener() {
“重写”
公共 无效 OnProgressChanged(SeekBar SeekBar,int我,布尔){
mcurrentprogress =(浮SeekBar getprogress() /()。浮SeekBar getmax());
mautohome setcurrentprogress(mcurrentprogress);
mautohome。invalidate();
}
“重写”
公共 无效 onstarttrackingtouch(SeekBar SeekBar){
}
“重写”
公共 无效 onstoptrackingtouch(SeekBar SeekBar){
}
});
}
第二个状态的实现:
第二个状态是表针在执行一个旋转的动画,我们可以将表针写成一个自定义看来,然后表盘作为背景图片,然后表针动画即可来执行旋转视图
* * * *
*由掌起15 / 10 / 27。
*
公共 类 pointerview 延伸 观{
私人 int××;
私人 int是的;
私人位图finalpointerbitmap;
私人位图pointerbitmap;
公共 pointerview(上下文上下文){
好极了(上下文);
();
}
公共 pointerview(上下文语境,attributeset attrs){
好极了(上下文属性);
();
}
公共 pointerview(上下文语境,attributeset属性,intdefstyleattr){
好极了(上下文属性,defstyleattr);
();
}
私人 无效 初始化(){
pointerbitmap =位图。CreateBitmap(BitmapFactory。decoderesource(getresources(),r.drawable。load_icon_pointer2x));
}
“重写”
受保护的 无效 onMeasure(intwidthmeasurespec,intheightmeasurespec){
setmeasureddimension(measurewidth(widthmeasurespec),measurewidth(heightmeasurespec));
x = getmeasuredwidth();
Y = getmeasuredheight();
finalpointerbitmap =位图。createscaledbitmap(pointerbitmap,X,Y,假);
}
私人 int measurewidth(intwidmeasurespec){
int结果=零;
int尺寸= measurespec GetSize(widmeasurespec);
int模式= measurespec getmode(widmeasurespec);
如果(模式= = measurespec。到底){
结果=大小;
}其他的{
结果pointerbitmap getwidth() =;
如果(模式= = measurespec。at_most){
结果=数学,最小(结果,大小);
}
}
返回结果;
}
“重写”
受保护的 无效 OnDraw(帆布帆布){
好极了OnDraw(帆布);
270 /目的是让表针初始位置为度!
帆布。二百七十,×二,/二);
drawbitmap(finalpointerbitmap画布,零,零,空);
}
}
然后我们在XML文件中这样写:
<FrameLayout
安卓:身份证=“@ +身份证/ anim_container”
安卓:layout_width=“45dp”
安卓:layout_height=“45dp”
安卓:layout_margin=“15dp”
安卓:能见度=“不见了”>
<com.zhangqi.autohomerefreshlistview.pointerview
安卓:身份证=“@ +身份证/ anim_pointer”
安卓:layout_width=“wrap_content”
安卓:layout_height=“wrap_content”
安卓:layout_gravity=“中心”/ >
<ImageView
安卓:layout_width=“wrap_content”
安卓:layout_height=“wrap_content”
安卓:SRC=“@冲/ load_icon_dial2x”/ >
< /FrameLayout>
这样就将表盘作为背景了,我们可以操作表针来执行旋转动画
<?xml version=“1”encoding=“utf-8”?>
<旋转 xmlns:Android=“http://schemas.android.com/apk/res/android”
安卓:初始度数=“0”
安卓:todegrees=“150”
安卓:pivoty=“50%”
安卓:pivotX=“50%”
安卓:持续时间=“1000”
安卓:repeatcount=“无限”
安卓:repeatmode=“反向”
>
< /旋转>
mautohomeanim =(pointerview)headerview findViewById(r.id.anim_pointer);
动画= animationutils。loadanimation(上下文,r.anim。pointer_rotate);
/ /执行动画
mautohomeanim startanimation(动画);
在ListView中
由于下拉刷新核心代码和美团下拉刷新是一样的,这里我只截取不一样的部分
私人 无效 changeheaderbystate(int状态){
开关(状态){
案例完成
headerview setpadding(。零,- headerviewheight,零,零);
/ /第一状态的观显示出来
mautohome。setvisibility(观。可见);
/ /先停止一下第二阶段观的动画
mautohomeanim。clearanimation();
/ /将第二阶段观隐藏起来
manimcontainer。setvisibility(观。走了);
打破;
案例release_to_refresh:
tv_pull_to_refresh setText(。“放开刷新”);
打破;
案例pull_to_refresh:
tv_pull_to_refresh setText(。“下拉刷新”);
/ /第一状态观显示出来
mautohome。setvisibility(观。可见);
/ /停止第二阶段动画
mautohomeanim。clearanimation();
/ /将第二阶段观隐藏
manimcontainer。setvisibility(观。走了);
打破;
案例令人耳目一新:
tv_pull_to_refresh setText(。“正在刷新”);
/ /将第一阶段观隐藏
mautohome。setvisibility(观。走了);
/ /将第二阶段观显示出来
manimcontainer。setvisibility(观。可见);
/ /先停止第二阶段动画
mautohomeanim。clearanimation();
/ /启动第二阶段动画
mautohomeanim startanimation(动画);
打破;
默认:
打破;
}
}
完整代码:
大家可以到我的GitHub上下载
- 顶
- 六
- 踩
- 零
- 猜你在找