Android特效专辑(一)(二)
水波纹过渡特效(首页)
也是今天看到的一个特效,感觉挺漂亮的,最近也一直在筹划一个APP,就想把他当做APP的首页,然后加些处理,关于首页APP的特效等我完工了再贴出来吧,现在先把这个特效给分享出来,只是稍微改动了一点点而已。
我们先创建一个UIUtils,转换一些单位
packagecom.lgl.test;
importandroid.content.Context;
importandroid.util.DisplayMetrics;
importandroid.view.WindowManager;
publicclassUiUtils{
staticpublicintgetScreenWidthPixels(Contextcontext){
DisplayMetricsdm=newDisplayMetrics();
((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay()
.getMetrics(dm);
returndm.widthPixels;
}
staticpublicintdipToPx(Contextcontext,intdip){
return(int)(dipgetScreenDensity(context)+0.5f);
}
staticpublicfloatgetScreenDensity(Contextcontext){
try{
DisplayMetricsdm=newDisplayMetrics();
((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay()
.getMetrics(dm);
returndm.density;
}catch(Exceptione){
returnDisplayMetrics.DENSITY_DEFAULT;
}
}
然后写一个WaterRippleView类继承View
packagecom.lgl.test;
importandroid.content.Context;
importandroid.graphics.Canvas;
importandroid.graphics.DrawFilter;
importandroid.graphics.Paint;
importandroid.graphics.Paint.Style;
importandroid.graphics.PaintFlagsDrawFilter;
importandroid.util.AttributeSet;
importandroid.view.View;
publicclassWaterRippleViewextendsView{
//波纹颜色
privatestaticfinalintWAVE_PAINT_COLOR=0x880000aa;
//y=Asin(wx+b)+h
privatestaticfinalfloatSTRETCH_FACTOR_A=20;
privatestaticfinalintOFFSET_Y=0;
//第一条水波移动速度
privatestaticfinalintTRANSLATE_X_SPEED_ONE=7;
//第二条水波移动速度
privatestaticfinalintTRANSLATE_X_SPEED_TWO=5;
privatefloatmCycleFactorW;
privateintmTotalWidth,mTotalHeight;
privatefloat[]mYPositions;
privatefloat[]mResetOneYPositions;
privatefloat[]mResetTwoYPositions;
privateintmXOffsetSpeedOne;
privateintmXOffsetSpeedTwo;
privateintmXOneOffset;
privateintmXTwoOffset;
privatePaintmWavePaint;
privateDrawFiltermDrawFilter;
publicWaterRippleView(Contextcontext,AttributeSetattrs){
super(context,attrs);
//将dp转化为px,用于控制不同分辨率上移动速度基本一致
mXOffsetSpeedOne=UiUtils.dipToPx(context,TRANSLATE_X_SPEED_ONE);
mXOffsetSpeedTwo=UiUtils.dipToPx(context,TRANSLATE_X_SPEED_TWO);
//初始绘制波纹的画笔
mWavePaint=newPaint();
//去除画笔锯齿
mWavePaint.setAntiAlias(true);
//设置风格为实线
mWavePaint.setStyle(Style.FILL);
//设置画笔颜色
mWavePaint.setColor(WAVE_PAINT_COLOR);
mDrawFilter=newPaintFlagsDrawFilter(0,Paint.ANTI_ALIAS_FLAG
|Paint.FILTER_BITMAP_FLAG);
}
@Override
protectedvoidonDraw(Canvascanvas){
super.onDraw(canvas);
//从canvas层面去除绘制时锯齿
canvas.setDrawFilter(mDrawFilter);
resetPositonY();
for(inti=0;i
//减400只是为了控制波纹绘制的y的在屏幕的位置,大家可以改成一个变量,然后动态改变这个变量,从而形成波纹上升下降效果
//绘制第一条水波纹
canvas.drawLine(i,mTotalHeight-mResetOneYPositions[i]-400,i,
mTotalHeight,mWavePaint);
//绘制第二条水波纹
canvas.drawLine(i,mTotalHeight-mResetTwoYPositions[i]-400,i,
mTotalHeight,mWavePaint);
}
//改变两条波纹的移动点
mXOneOffset+=mXOffsetSpeedOne;
mXTwoOffset+=mXOffsetSpeedTwo;
//如果已经移动到结尾处,则重头记录
if(mXOneOffset>=mTotalWidth){
mXOneOffset=0;
}
if(mXTwoOffset>mTotalWidth){
mXTwoOffset=0;
}
//引发view重绘,一般可以考虑延迟20-30ms重绘,空出时间片
postInvalidate();
}
privatevoidresetPositonY(){
//mXOneOffset代表当前第一条水波纹要移动的距离
intyOneInterval=mYPositions.length-mXOneOffset;
//使用System.arraycopy方式重新填充第一条波纹的数据
System.arraycopy(mYPositions,mXOneOffset,mResetOneYPositions,0,
yOneInterval);
System.arraycopy(mYPositions,0,mResetOneYPositions,yOneInterval,
mXOneOffset);
intyTwoInterval=mYPositions.length-mXTwoOffset;
System.arraycopy(mYPositions,mXTwoOffset,mResetTwoYPositions,0,
yTwoInterval);
System.arraycopy(mYPositions,0,mResetTwoYPositions,yTwoInterval,
mXTwoOffset);
}
@Override
protectedvoidonSizeChanged(intw,inth,intoldw,intoldh){
super.onSizeChanged(w,h,oldw,oldh);
//记录下view的宽高
mTotalWidth=w;
mTotalHeight=h;
//用于保存原始波纹的y值
mYPositions=newfloat[mTotalWidth];
//用于保存波纹一的y值
mResetOneYPositions=newfloat[mTotalWidth];
//用于保存波纹二的y值
mResetTwoYPositions=newfloat[mTotalWidth];
//将周期定为view总宽度
mCycleFactorW=(float)(2Math.PI/mTotalWidth);
//根据view总宽度得出所有对应的y值
for(inti=0;i mYPositions[i]=(float)(STRETCH_FACTOR_A
Math.sin(mCycleFactorWi)+OFFSET_Y);
}
}
}
然后你就可以绑定在布局上就可以使用了
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
是不是感觉特效还可以,后开在cmd里看了下CPU,还是放弃了!...
ViewPager渲染背景颜色渐变(引导页)
图片用的是官方的,嘿嘿
这个做起来,其实也就是加了一个监听变色的效果,我们来写一下把;
layout_main.xml
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:id="@+id/ColorAnimationView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="30dp"/>
android:layout_width="match_parent"
android:layout_height="match_parent">
MainActivity
packagecom.lgl.viewpager;
importandroid.annotation.SuppressLint;
importandroid.os.Bundle;
importandroid.support.v4.app.Fragment;
importandroid.support.v4.app.FragmentActivity;
importandroid.support.v4.app.FragmentManager;
importandroid.support.v4.app.FragmentStatePagerAdapter;
importandroid.support.v4.view.ViewPager;
importandroid.util.Log;
importandroid.view.LayoutInflater;
importandroid.view.View;
importandroid.view.ViewGroup;
importandroid.widget.Button;
importandroid.widget.ImageView;
publicclassMainActivityextendsFragmentActivity{
privatestaticfinalint[]resource=newint[]{R.drawable.welcome1,
R.drawable.welcome4,R.drawable.welcome3,R.drawable.welcome4};
privatestaticfinalStringTAG=MainActivity.class.getSimpleName();
privateButtonbtn_go;
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_go=(Button)findViewById(R.id.btn_go);
MyFragmentStatePageradpter=newMyFragmentStatePager(
getSupportFragmentManager());
ColorAnimationViewcolorAnimationView=(ColorAnimationView)findViewById(R.id.ColorAnimationView);
ViewPagerviewPager=(ViewPager)findViewById(R.id.viewPager);
//设置adapter
viewPager.setAdapter(adpter);
//监听滑动
colorAnimationView.setmViewPager(viewPager,resource.length);
colorAnimationView
.setOnPageChangeListener(newViewPager.OnPageChangeListener(){
@Override
publicvoidonPageScrolled(intposition,
floatpositionOffset,intpositionOffsetPixels){
Log.e("TAG","onPageScrolled");
}
@Override
publicvoidonPageSelected(intposition){
//Button显示或隐藏
if(position==3){
btn_go.setVisibility(View.VISIBLE);
}else{
btn_go.setVisibility(View.GONE);
}
Log.e("TAG","onPageSelected");
}
@Override
publicvoidonPageScrollStateChanged(intstate){
Log.e("TAG","onPageScrollStateChanged");
}
});
}
publicclassMyFragmentStatePagerextendsFragmentStatePagerAdapter{
publicMyFragmentStatePager(FragmentManagerfm){
super(fm);
}
@Override
publicFragmentgetItem(intposition){
returnnewMyFragment(position);
}
@Override
publicintgetCount(){
returnresource.length;
}
}
@SuppressLint("ValidFragment")
publicclassMyFragmentextendsFragment{
privateintposition;
publicMyFragment(intposition){
this.position=position;
}
@Override
publicViewonCreateView(LayoutInflaterinflater,ViewGroupcontainer,
BundlesavedInstanceState){
ImageViewimageView=newImageView(getActivity());
imageView.setImageResource(resource[position]);
returnimageView;
}
}
}
ColorAnimationView
packagecom.lgl.viewpager;
importandroid.animation.Animator;
importandroid.animation.ArgbEvaluator;
importandroid.animation.ObjectAnimator;
importandroid.animation.ValueAnimator;
importandroid.content.Context;
importandroid.support.v4.view.ViewPager;
importandroid.util.AttributeSet;
importandroid.view.View;
publicclassColorAnimationViewextendsViewimplements
ValueAnimator.AnimatorUpdateListener,Animator.AnimatorListener{
privatestaticfinalintRED=0xffFF8080;
privatestaticfinalintBLUE=0xff8080FF;
privatestaticfinalintWHITE=0xffffffff;
privatestaticfinalintGREEN=0xff80ff80;
privatestaticfinalintDURATION=3000;
ValueAnimatorcolorAnim=null;
privatePageChangeListenermPageChangeListener;
ViewPager.OnPageChangeListeneronPageChangeListener;
publicvoidsetOnPageChangeListener(
ViewPager.OnPageChangeListeneronPageChangeListener){
this.onPageChangeListener=onPageChangeListener;
}
/
这是你唯一需要关心的方法
@parammViewPager
你必须在设置Viewpager的Adapter这后,才能调用这个方法。
@paramobj
,这个obj实现了ColorAnimationView.OnPageChangeListener,实现回调
@paramcount
,viewpager数据的数量
@paramcolors
int...colors,你需要设置的颜色变化值~~如何你传人空,那么触发默认设置的颜色动画
/
publicvoidsetmViewPager(ViewPagermViewPager,intcount,int...colors){
if(mViewPager.getAdwww.shanxiwang.netapter()==null){
thrownewIllegalStateException(
"ViewPagerdoesnothaveadapterinstance.");
}
mPageChangeListener.setViewPagerChildCount(count);
mViewPager.setOnPageChangeListener(mPageChangeListener);
if(colors.length==0){
createDefaultAnimation();
}else{
createAnimation(colors);
}
}
publicColorAnimationView(Contextcontext){
this(context,null,0);
}
publicColorAnimationView(Contextcontext,AttributeSetattrs){
this(context,attrs,0);
}
publicColorAnimationView(Contextcontext,AttributeSetattrs,
intdefStyleAttr){
super(context,attrs,defStyleAttr);
mPageChangeListener=newPageChangeListener();
}
privatevoidseek(longseekTime){
if(colorAnim==null){
createDefaultAnimation();
}
colorAnim.setCurrentPlayTime(seekTime);
}
privatevoidcreateAnimation(int...colors){
if(colorAnim==null){
colorAnim=ObjectAnimator.ofInt(this,"backgroundColor",colors);
colorAnim.setEvaluator(newArgbEvaluator());
colorAnim.setDuration(DURATION);
colorAnim.addUpdateListener(this);
}
}
privatevoidcreateDefaultAnimation(){
colorAnim=ObjectAnimator.ofInt(this,"backgroundColor",WHITE,RED,
BLUE,GREEN,WHITE);
colorAnim.setEvaluator(newArgbEvaluator());
colorAnim.setDuration(DURATION);
colorAnim.addUpdateListener(this);
}
@Override
publicvoidonAnimationStart(Animatoranimation){
}
@Override
publicvoidonAnimationEnd(Animatoranimation){
}
@Override
publicvoidonAnimationCancel(Animatoranimation){
}
@Override
publicvoidonAnimationRepeat(Animatoranimation){
}
@Override
publicvoidonAnimationUpdate(ValueAnimatoranimation){
invalidate();
}
privateclassPageChangeListenerimplementsViewPager.OnPageChangeListener{
privateintviewPagerChildCount;
publicvoidsetViewPagerChildCount(intviewPagerChildCount){
this.viewPagerChildCount=viewPagerChildCount;
}
publicintgetViewPagerChildCount(){
returnviewPagerChildCount;
}
@Override
publicvoidonPageScrolled(intposition,floatpositionOffset,
intpositionOffsetPixels){
intcount=getViewPagerChildCount()-1;
if(count!=0){
floatlength=(position+positionOffset)/count;
intprogress=(int)(lengthDURATION);
ColorAnimationView.this.seek(progress);
}
if(onPageChangeListener!=null){
onPageChangeListener.onPageScrolled(position,positionOffset,
positionOffsetPixels);
}
}
@Override
publicvoidonPageSelected(intposition){
if(onPageChangeListener!=null){
onPageChangeListener.onPageSelected(position);
}
}
@Override
publicvoidonPageScrollStateChanged(intstate){
if(onPageChangeListener!=null){
onPageChangeListener.onPageScrollStateChanged(state);
}
}
}
}
扁平化Button
大家看到这个button是不是挺好看的,这里用到了一个shape属性
|
|