仿 <赶集生活android客户端> 的介绍动画界面 的进一步修改

简介:

第一版项目引自

http://blog.csdn.net/nekocode/article/details/20308159#reply




        最近在玩赶集生活android客户端时,发现它初次运行时的介绍页面做得不错,当用户拉到Feature上的时候会出现动画,令人感觉很生动~于是自己简单地模仿了下。

        Sample: http://pan.baidu.com/s/1i3wqEMh (具体效果可以下载该样例观看)


 


  1. package com.example.animatetest;  
  2.   
  3. import android.os.Bundle;  
  4. import android.app.Activity;  
  5. import android.view.Menu;  
  6. import android.view.View;  
  7. import android.view.ViewTreeObserver.OnGlobalLayoutListener;  
  8. import android.view.animation.Animation;  
  9. import android.view.animation.AnimationUtils;  
  10.   
  11. public class MainActivity extends Activity implements OnGlobalLayoutListener, OnScrollChangedListener {  
  12.     private ObservableScrollView mScrollView;  
  13.     private View mAnimView;  
  14.     private int mScrollViewHeight;  
  15.     private int mStartAnimateTop;  
  16.       
  17.     @Override  
  18.     protected void onCreate(Bundle savedInstanceState) {  
  19.         super.onCreate(savedInstanceState);  
  20.         setContentView(R.layout.activity_main);  
  21.           
  22.         mScrollView = (ObservableScrollView)this.findViewById(R.id.scrollView1);  
  23.         mScrollView.getViewTreeObserver().addOnGlobalLayoutListener(this);  
  24.         mScrollView.setOnScrollChangedListener(this);  
  25.           
  26.         mAnimView = this.findViewById(R.id.anim1);  
  27.         mAnimView.setVisibility(View.INVISIBLE);  
  28.     }  
  29.   
  30.     @Override  
  31.     public boolean onCreateOptionsMenu(Menu menu) {  
  32.         getMenuInflater().inflate(R.menu.main, menu);  
  33.         return true;  
  34.     }  
  35.   
  36.     @Override  
  37.     public void onGlobalLayout() {  
  38.         mScrollViewHeight = mScrollView.getHeight();  
  39.         mStartAnimateTop = mScrollViewHeight / 3 * 2;  
  40.     }  
  41.   
  42.     boolean hasStart = false;  
  43.     @Override  
  44.     public void onScrollChanged(int top, int oldTop) {  
  45.         int animTop = mAnimView.getTop() - top;  
  46.           
  47.         if(top > oldTop) {  
  48.             if(animTop < mStartAnimateTop && !hasStart) {  
  49.                 Animation anim1 = AnimationUtils.loadAnimation(this, R.anim.feature_anim2scale_in);  
  50.                 anim1.setAnimationListener(new FeatureAnimationListener(mAnimView, true));  
  51.                   
  52.                 mAnimView.startAnimation(anim1);  
  53.                 hasStart = true;  
  54.             }  
  55.         } else {  
  56.             if(animTop > mStartAnimateTop && hasStart) {  
  57.                 Animation anim1 = AnimationUtils.loadAnimation(this, R.anim.feature_alpha_out);  
  58.                 anim1.setAnimationListener(new FeatureAnimationListener(mAnimView, false));  
  59.                   
  60.                 mAnimView.startAnimation(anim1);  
  61.                 hasStart = false;  
  62.             }  
  63.         }  
  64.     }  
  65. }  

  1. package com.example.animatetest;  
  2.   
  3. import android.content.Context;  
  4. import android.util.AttributeSet;  
  5. import android.widget.ScrollView;  
  6.   
  7. public class ObservableScrollView extends ScrollView {  
  8.     private OnScrollChangedListener onScrollChangedListener;  
  9.   
  10.     public ObservableScrollView(Context context, AttributeSet attrs,  
  11.             int defStyle) {  
  12.         super(context, attrs, defStyle);  
  13.     }  
  14.   
  15.     public ObservableScrollView(Context context, AttributeSet attrs) {  
  16.         super(context, attrs);  
  17.     }  
  18.   
  19.     public ObservableScrollView(Context context) {  
  20.         super(context);  
  21.     }  
  22.       
  23.     @Override  
  24.     protected void onScrollChanged(int l, int t, int oldl, int oldt) {  
  25.         super.onScrollChanged(l, t, oldl, oldt);  
  26.         if(this.onScrollChangedListener != null) {  
  27.             onScrollChangedListener.onScrollChanged(t, oldt);  
  28.         }  
  29.     }  
  30.   
  31.     public void setOnScrollChangedListener(OnScrollChangedListener onScrollChangedListener) {  
  32.         this.onScrollChangedListener = onScrollChangedListener;  
  33.     }  
  34.   
  35. }  

  1. package com.example.animatetest;  
  2.   
  3. public abstract interface OnScrollChangedListener {  
  4.     public abstract void onScrollChanged(int top, int oldTop);  
  5. }  

  1. package com.example.animatetest;  
  2.   
  3. import android.view.View;  
  4. import android.view.animation.Animation;  
  5. import android.view.animation.Animation.AnimationListener;  
  6.   
  7. public class FeatureAnimationListener implements AnimationListener {  
  8.     private View mAnimView;  
  9.     private boolean mAnimIn;  
  10.       
  11.     public FeatureAnimationListener(View animView, boolean animIn) {  
  12.         mAnimView = animView;  
  13.         mAnimIn = animIn;  
  14.     }  
  15.   
  16.     @Override  
  17.     public void onAnimationEnd(Animation animation) {  
  18.         if(!mAnimIn) {  
  19.             mAnimView.setVisibility(View.INVISIBLE);  
  20.         }  
  21.     }  
  22.   
  23.     @Override  
  24.     public void onAnimationRepeat(Animation animation) {}  
  25.   
  26.     @Override  
  27.     public void onAnimationStart(Animation animation) {  
  28.         if(mAnimIn) {  
  29.             mAnimView.setVisibility(View.VISIBLE);  
  30.         }  
  31.     }  
  32.   
  33. }  


activity_main.xml

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"  
  3.     android:layout_height="match_parent" tools:context=".MainActivity">  
  4.     <com.example.animatetest.ObservableScrollView  
  5.         android:id="@+id/scrollView1" android:layout_width="fill_parent"  
  6.         android:layout_height="fill_parent">  
  7.         <LinearLayout android:layout_width="fill_parent"  
  8.             android:layout_height="wrap_content" android:background="@drawable/feature_bg"  
  9.             android:gravity="center_horizontal" android:orientation="vertical">  
  10.             <ImageView android:id="@+id/imageView2"  
  11.                 android:layout_width="wrap_content" android:layout_height="wrap_content"  
  12.                 android:layout_marginTop="100dp" android:src="@drawable/feature_title" />  
  13.             <ImageView android:id="@+id/imageView1"  
  14.                 android:layout_width="wrap_content" android:layout_height="wrap_content"  
  15.                 android:layout_marginTop="20dp" android:src="@drawable/feature_lv" />  
  16.             <ImageView android:id="@+id/imageView3"  
  17.                 android:layout_width="wrap_content" android:layout_height="wrap_content"  
  18.                 android:layout_marginTop="35dp" android:src="@drawable/feature_dot" />  
  19.             <ImageView android:id="@+id/imageView4"  
  20.                 android:layout_width="wrap_content" android:layout_height="wrap_content"  
  21.                 android:layout_marginTop="35dp" android:src="@drawable/feature_dot" />  
  22.             <ImageView android:id="@+id/imageView5"  
  23.                 android:layout_width="wrap_content" android:layout_height="wrap_content"  
  24.                 android:layout_marginTop="35dp" android:src="@drawable/feature_scroll_txt" />  
  25.             <ImageView android:id="@+id/imageView6"  
  26.                 android:layout_width="wrap_content" android:layout_height="wrap_content"  
  27.                 android:layout_marginTop="35dp" android:src="@drawable/feature_dot" />  
  28.             <ImageView android:id="@+id/imageView7"  
  29.                 android:layout_width="wrap_content" android:layout_height="wrap_content"  
  30.                 android:layout_marginTop="35dp" android:src="@drawable/feature_dot" />  
  31.             <LinearLayout android:id="@+id/anim1"  
  32.                 android:layout_width="match_parent" android:layout_height="wrap_content"  
  33.                 android:layout_marginTop="35dp" android:gravity="center_vertical|center_horizontal">  
  34.                 <ImageView android:id="@+id/imageView8"  
  35.                     android:layout_width="wrap_content" android:layout_height="wrap_content"  
  36.                     android:src="@drawable/feature_car" />  
  37.                 <ImageView android:id="@+id/imageView9"  
  38.                     android:layout_width="wrap_content" android:layout_height="wrap_content"  
  39.                     android:src="@drawable/feature_gift" />  
  40.                 <ImageView android:id="@+id/imageView10"  
  41.                     android:layout_width="wrap_content" android:layout_height="wrap_content"  
  42.                     android:src="@drawable/feature_money" />  
  43.             </LinearLayout>  
  44.             <ImageView android:id="@+id/imageView11"  
  45.                 android:layout_width="wrap_content" android:layout_height="wrap_content"  
  46.                 android:layout_marginTop="35dp" android:src="@drawable/feature_dot" />  
  47.             <ImageView android:id="@+id/imageView12"  
  48.                 android:layout_width="wrap_content" android:layout_height="wrap_content"  
  49.                 android:layout_marginTop="35dp" android:src="@drawable/feature_dot" />  
  50.             <ImageView android:id="@+id/imageView13"  
  51.                 android:layout_width="wrap_content" android:layout_height="wrap_content"  
  52.                 android:layout_marginTop="35dp" android:src="@drawable/feature_arrow_up" />  
  53.             <ImageView android:id="@+id/imageView14"  
  54.                 android:layout_width="wrap_content" android:layout_height="wrap_content"  
  55.                 android:layout_marginTop="35dp" android:src="@drawable/feature_jobs_txt" />  
  56.         </LinearLayout>  
  57.     </com.example.animatetest.ObservableScrollView>  
  58.   
  59. </RelativeLayout>  


feature_anim2scale_in.xml
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <scale android:interpolator="@android:anim/overshoot_interpolator"  
  3.     android:duration="200" android:pivotX="50.0%" android:pivotY="50.0%"  
  4.     android:fillAfter="true" android:fromXScale="0.0" android:toXScale="1.0"  
  5.     android:fromYScale="0.0" android:toYScale="1.0"  
  6.     xmlns:android="http://schemas.android.com/apk/res/android" />  


feature_alpha_out.xml
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <set xmlns:android="http://schemas.android.com/apk/res/android">  
  3.     <alpha android:interpolator="@android:anim/overshoot_interpolator"  
  4.         android:duration="200" android:fromAlpha="1.0" android:toAlpha="0.0" />  
  5. </set> 



然后这个DEMO我本人发现如下可以修改的地方:

    这个最好activity不要实现OnScrollChangedListener
实现类单独写多个
这样就可以有不同的策略来实现change

就把acitivity里的实现OnScrollChangedListener的类抽出来写一个DefaultOnScrollChangedListener类,
activity里就定义一个OnScrollChangedListener变量
oncreate时赋值给他DefaultOnScrollChangedListener的实例
hasStart这样用有点扯

hasStart最好包在ScrollView里

修改的代码如下:

package com.example.animatetest;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;

public class MainActivity extends Activity implements OnGlobalLayoutListener {
	private ObservableScrollView mScrollView;
	private View mAnimView;
	private int mScrollViewHeight;
	private int mStartAnimateTop;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		mScrollView = (ObservableScrollView)this.findViewById(R.id.scrollView1);
		mScrollView.getViewTreeObserver().addOnGlobalLayoutListener(this);
		
		DefaultOnScrollChangedListener listener = new DefaultOnScrollChangedListener();
		mScrollView.setOnScrollChangedListener(listener);
		
		mAnimView = this.findViewById(R.id.anim1);
		mAnimView.setVisibility(View.INVISIBLE);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public void onGlobalLayout() {
		mScrollViewHeight = mScrollView.getHeight();
		mStartAnimateTop = mScrollViewHeight / 3 * 2;
	}

    public View getmAnimView() {
        return mAnimView;
    }

    public int getmStartAnimateTop() {
        return mStartAnimateTop;
    }	
}



package com.example.animatetest;

import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ScrollView;

public class DefaultOnScrollChangedListener implements OnScrollChangedListener{
    private boolean hasStart = false;
    
    @Override
    public void onScrollChanged(Context context, int top, int oldTop) {
        View mAnimView =((MainActivity) context).getmAnimView();
        int mStartAnimateTop = ((MainActivity) context).getmStartAnimateTop();
        
        int animTop = mAnimView.getTop() - top;
        
        if(top > oldTop) {
            if(animTop < mStartAnimateTop && !hasStart) {
                Animation anim1 = AnimationUtils.loadAnimation(context, R.anim.feature_anim2scale_in);
                anim1.setAnimationListener(new FeatureAnimationListener(mAnimView, true));
                
                mAnimView.startAnimation(anim1);
                hasStart = true;
            }
        } else {
            if(animTop > mStartAnimateTop && hasStart) {
                Animation anim1 = AnimationUtils.loadAnimation(context, R.anim.feature_alpha_out);
                anim1.setAnimationListener(new FeatureAnimationListener(mAnimView, false));
                
                mAnimView.startAnimation(anim1);
                hasStart = false;
            }
        }
    }
}


package com.example.animatetest;

import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;

public class FeatureAnimationListener implements AnimationListener {
	private View mAnimView;
	private boolean mAnimIn;
	
	public FeatureAnimationListener(View animView, boolean animIn) {
		mAnimView = animView;
		mAnimIn = animIn;
	}

	@Override
	public void onAnimationEnd(Animation animation) {
		if(!mAnimIn) {
			mAnimView.setVisibility(View.INVISIBLE);
		}
	}

	@Override
	public void onAnimationRepeat(Animation animation) {}

	@Override
	public void onAnimationStart(Animation animation) {
		if(mAnimIn) {
			mAnimView.setVisibility(View.VISIBLE);
		}
	}

}



package com.example.animatetest;

import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ScrollView;

public class ObservableScrollView extends ScrollView {
	private OnScrollChangedListener onScrollChangedListener;

	public ObservableScrollView(Context context, AttributeSet attrs,
			int defStyle) {
	    super(context, attrs, defStyle);
	    //this.context = context;
	}

	public ObservableScrollView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public ObservableScrollView(Context context) {
		super(context);
	}
	
    @Override
	protected void onScrollChanged(int l, int t, int oldl, int oldt) {
		super.onScrollChanged(l, t, oldl, oldt);
		if(this.onScrollChangedListener != null) {
			onScrollChangedListener.onScrollChanged(this.getContext(), t, oldt);
		}
	}

	public void setOnScrollChangedListener(OnScrollChangedListener onScrollChangedListener) {
		this.onScrollChangedListener = onScrollChangedListener;
	}

}



package com.example.animatetest;

import android.app.Activity;
import android.content.Context;
import android.widget.ScrollView;

public abstract interface OnScrollChangedListener {
	public abstract void onScrollChanged(Context context, int top, int oldTop);
}


源代码下载地址如下:

http://download.csdn.net/detail/opzoonzhuzhengke/6999895





目录
相关文章
|
5月前
|
Android开发 开发者
Android利用SVG实现动画效果
本文介绍了如何在Android中利用SVG实现动画效果。首先通过定义`pathData`参数(如M、L、Z等)绘制一个简单的三角形SVG图形,然后借助`objectAnimator`实现动态的线条绘制动画。文章详细讲解了从配置`build.gradle`支持VectorDrawable,到创建动画文件、关联SVG与动画,最后在Activity中启动动画的完整流程。此外,还提供了SVG绘制原理及工具推荐,帮助开发者更好地理解和应用SVG动画技术。
231 30
|
5月前
|
Android开发 UED 计算机视觉
Android自定义view之线条等待动画(灵感来源:金铲铲之战)
本文介绍了一款受游戏“金铲铲之战”启发的Android自定义View——线条等待动画的实现过程。通过将布局分为10份,利用`onSizeChanged`测量最小长度,并借助画笔绘制动态线条,实现渐变伸缩效果。动画逻辑通过四个变量控制线条的增长与回退,最终形成流畅的等待动画。代码中详细展示了画笔初始化、线条绘制及动画更新的核心步骤,并提供完整源码供参考。此动画适用于加载场景,提升用户体验。
463 5
Android自定义view之线条等待动画(灵感来源:金铲铲之战)
|
5月前
|
API Android开发 开发者
Android颜色渐变动画效果的实现
本文介绍了在Android中实现颜色渐变动画效果的方法,重点讲解了插值器(TypeEvaluator)的使用与自定义。通过Android自带的颜色插值器ArgbEvaluator,可以轻松实现背景色的渐变动画。文章详细分析了ArgbEvaluator的核心代码,并演示了如何利用Color.colorToHSV和Color.HSVToColor方法自定义颜色插值器MyColorEvaluator。最后提供了完整的源码示例,包括ColorGradient视图类和MyColorEvaluator类,帮助开发者更好地理解和应用颜色渐变动画技术。
154 3
|
5月前
|
Android开发 数据安全/隐私保护 开发者
Android自定义view之模仿登录界面文本输入框(华为云APP)
本文介绍了一款自定义输入框的实现,包含静态效果、hint值浮动动画及功能扩展。通过组合多个控件完成界面布局,使用TranslateAnimation与AlphaAnimation实现hint文字上下浮动效果,支持密码加密解密显示、去除键盘回车空格输入、光标定位等功能。代码基于Android平台,提供完整源码与attrs配置,方便复用与定制。希望对开发者有所帮助。
|
5月前
|
XML Java Android开发
Android自定义view之网易云推荐歌单界面
本文详细介绍了如何通过自定义View实现网易云音乐推荐歌单界面的效果。首先,作者自定义了一个圆角图片控件`MellowImageView`,用于绘制圆角矩形图片。接着,通过将布局放入`HorizontalScrollView`中,实现了左右滑动功能,并使用`ViewFlipper`添加图片切换动画效果。文章提供了完整的代码示例,包括XML布局、动画文件和Java代码,最终展示了实现效果。此教程适合想了解自定义View和动画效果的开发者。
229 65
Android自定义view之网易云推荐歌单界面
|
5月前
|
Android开发 开发者
Android SVG动画详细例子
本文详细讲解了在Android中利用SVG实现动画效果的方法,通过具体例子帮助开发者更好地理解和应用SVG动画。文章首先展示了动画的实现效果,接着回顾了之前的文章链接及常见问题(如属性名大小写错误)。核心内容包括:1) 使用阿里图库获取SVG图形;2) 借助工具将SVG转换为VectorDrawable;3) 为每个路径添加动画绑定属性;4) 创建动画文件并关联SVG;5) 在ImageView中引用动画文件;6) 在Activity中启动动画。文末还提供了完整的代码示例和源码下载链接,方便读者实践操作。
283 65
|
5月前
|
XML Java Maven
Android线条等待动画JMWorkProgress(可添加依赖直接使用)
这是一篇关于Android线条等待动画JMWorkProgress的教程文章,作者计蒙将其代码开源至GitHub,提升可读性。文章介绍了如何通过添加依赖库使用该动画,并详细讲解了XML与Java中的配置方法,包括改变线条颜色、宽度、添加文字等自定义属性。项目已支持直接依赖集成(`implementation &#39;com.github.Yufseven:JMWorkProgress:v1.0&#39;`),开发者可以快速上手实现炫酷的等待动画效果。文末附有GitHub项目地址,欢迎访问并点赞支持!
143 26
|
5月前
|
XML Android开发 数据格式
Android中SlidingDrawer利用透明动画提示效果
本文介绍了在Android中使用`SlidingDrawer`实现带有透明动画提示效果的方法。通过XML布局配置`SlidingDrawer`的把手(handle)和内容(content),结合Activity中的代码实现动态动画效果。最终实现了交互性强、视觉效果良好的滑动抽屉功能。
Android中SlidingDrawer利用透明动画提示效果
|
5月前
|
XML Java Android开发
Android 动画之帧动画 + 补间动画 + 属性动画
本文介绍了Android开发中的三种动画类型:帧动画、补间动画和属性动画。帧动画通过依次播放一系列静态图片实现动态效果,支持Java代码与XML两种实现方式。补间动画基于起始和结束位置自动生成过渡效果,涵盖透明度、位移、旋转、缩放及组合动画等多种形式,并可搭配插值器优化动画过程。属性动画则通过改变对象属性实现动画,支持透明度、位移、旋转、缩放及组合动画,灵活性更高且适用于更复杂的场景。文中提供了详细的代码示例,帮助开发者快速上手。
289 15
|
5月前
|
Android开发 开发者
Android企业级实战-界面篇-3
本文是《Android企业级实战-界面篇》系列的第三篇,主要介绍分割线和条形跳转框的实现方法,二者常用于设置和个人中心界面。文章通过具体代码示例展示了如何实现这两种UI组件,并提供了效果图。实现前需准备`dimens.xml`、`ids.xml`、`colors.xml`等文件,部分资源可参考系列第一、二篇文章。代码中详细说明了布局文件的配置,如分割线的样式定义和条形跳转框的组件组合,帮助开发者快速上手并应用于实际项目中。

热门文章

最新文章