热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

android动画详解(收藏)

找了好多关于android动画的文章,感觉这一篇文章写得真心好,特地收藏一下!3.0以前,android支持两种动画模式&#

找了好多关于android动画的文章,感觉这一篇文章写得真心好,特地收藏一下!

3.0以前,android支持两种动画模式,tween animation,frame animation,在android3.0中又引入了一个新的动画系统:property animation,这三种动画模式在SDK中被称为property animation,view animation,drawable animation。 可通过NineOldAndroids项目在3.0之前的系统中使用Property Animation

1. View Animation(Tween Animation)

View Animation(Tween Animation):补间动画,给出两个关键帧,通过一些算法将给定属性值在给定的时间内在两个关键帧间渐变。

View animation只能应用于View对象,而且只支持一部分属性,如支持缩放旋转而不支持背景颜色的改变。

而且对于View animation,它只是改变了View对象绘制的位置,而没有改变View对象本身,比如,你有一个Button,坐标(100,100),Width:200,Height:50,而你有一个动画使其变为Width:100,Height:100,你会发现动画过程中触发按钮点击的区域仍是(100,100)-(300,150)。

View Animation就是一系列View形状的变换,如大小的缩放,透明度的改变,位置的改变,动画的定义既可以用代码定义也可以用XML定义,当然,建议用XML定义。

可以给一个View同时设置多个动画,比如从透明至不透明的淡入效果,与从小到大的放大效果,这些动画可以同时进行,也可以在一个完成之后开始另一个。

用XML定义的动画放在/res/anim/文件夹内,XML文件的根元素可以为,,,,interpolator元素或(表示以上几个动画的集合,set可以嵌套)。默认情况下,所有动画是同时进行的,可以通过startOffset属性设置各个动画的开始偏移(开始时间)来达到动画顺序播放的效果。

可以通过设置interpolator属性改变动画渐变的方式,如AccelerateInterpolator,开始时慢,然后逐渐加快。默认为AccelerateDecelerateInterpolator。

定义好动画的XML文件后,可以通过类似下面的代码对指定View应用动画。

ImageView spaceshipImage = (ImageView)findViewById(R.id.spaceshipImage);
Animation hyperspaceJumpAnimation=AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);
spaceshipImage.startAnimation(hyperspaceJumpAnimation);

2. Drawable Animation(Frame Animation)

Drawable Animation(Frame Animation):帧动画,就像GIF图片,通过一系列Drawable依次显示来模拟动画的效果。在XML中的定义方式如下:

<animation-list xmlns:android&#61;"http://schemas.android.com/apk/res/android"android:oneshot&#61;"true"><item android:drawable&#61;"&#64;drawable/rocket_thrust1" android:duration&#61;"200" /><item android:drawable&#61;"&#64;drawable/rocket_thrust2" android:duration&#61;"200" /><item android:drawable&#61;"&#64;drawable/rocket_thrust3" android:duration&#61;"200" />
animation-list>

必须以为根元素&#xff0c;以表示要轮换显示的图片&#xff0c;duration属性表示各项显示的时间。XML文件要放在/res/drawable/目录下。示例&#xff1a;

protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
imageView &#61; (ImageView) findViewById(R.id.imageView1);
imageView.setBackgroundResource(R.drawable.drawable_anim);
anim &#61; (AnimationDrawable) imageView.getBackground();
}

public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() &#61;&#61; MotionEvent.ACTION_DOWN) {
anim.stop();
anim.start();
return true;
}
return super.onTouchEvent(event);
}

我在实验中遇到两点问题&#xff1a;

  1. 要在代码中调用Imageview的setBackgroundResource方法&#xff0c;如果直接在XML布局文件中设置其src属性当触发动画时会FC。
  2. 在动画start()之前要先stop()&#xff0c;不然在第一次动画之后会停在最后一帧&#xff0c;这样动画就只会触发一次。
  3. 最后一点是SDK中提到的&#xff0c;不要在onCreate中调用start&#xff0c;因为AnimationDrawable还没有完全跟Window相关联&#xff0c;如果想要界面显示时就开始动画的话&#xff0c;可以在onWindowFoucsChanged()中调用start()。

3. Property Animation

属性动画&#xff0c;这个是在Android 3.0中才引进的&#xff0c;以前学WPF时里面的动画机制好像就是这个&#xff0c;它更改的是对象的实际属性&#xff0c;在View Animation&#xff08;Tween Animation&#xff09;中&#xff0c;其改变的是View的绘制效果&#xff0c;真正的View的属性保持不变&#xff0c;比如无论你在对话中如何缩放Button的大小&#xff0c;Button的有效点击区域还是没有应用动画时的区域&#xff0c;其位置与大小都不变。而在Property Animation中&#xff0c;改变的是对象的实际属性&#xff0c;如Button的缩放&#xff0c;Button的位置与大小属性值都改变了。而且Property Animation不止可以应用于View&#xff0c;还可以应用于任何对象。Property Animation只是表示一个值在一段时间内的改变&#xff0c;当值改变时要做什么事情完全是你自己决定的。

在Property Animation中&#xff0c;可以对动画应用以下属性&#xff1a;

  • Duration&#xff1a;动画的持续时间
  • TimeInterpolation&#xff1a;属性值的计算方式&#xff0c;如先快后慢
  • TypeEvaluator&#xff1a;根据属性的开始、结束值与TimeInterpolation计算出的因子计算出当前时间的属性值
  • Repeat Count and behavoir&#xff1a;重复次数与方式&#xff0c;如播放3次、5次、无限循环&#xff0c;可以此动画一直重复&#xff0c;或播放完时再反向播放
  • Animation sets&#xff1a;动画集合&#xff0c;即可以同时对一个对象应用几个动画&#xff0c;这些动画可以同时播放也可以对不同动画设置不同开始偏移
  • Frame refreash delay&#xff1a;多少时间刷新一次&#xff0c;即每隔多少时间计算一次属性值&#xff0c;默认为10ms&#xff0c;最终刷新时间还受系统进程调度与硬件的影响

3.1 Property Animation的工作方式

对于下图的动画&#xff0c;这个对象的X坐标在40ms内从0移动到40 pixel.按默认的10ms刷新一次&#xff0c;这个对象会移动4次&#xff0c;每次移动40/4&#61;10pixel。

也可以改变属性值的改变方法&#xff0c;即设置不同的interpolation&#xff0c;在下图中运动速度先逐渐增大再逐渐减小

下图显示了与上述动画相关的关键对象

ValueAnimator  表示一个动画&#xff0c;包含动画的开始值&#xff0c;结束值&#xff0c;持续时间等属性。

ValueAnimator封装了一个TimeInterpolator&#xff0c;TimeInterpolator定义了属性值在开始值与结束值之间的插值方法。

ValueAnimator还封装了一个TypeAnimator&#xff0c;根据开始、结束值与TimeIniterpolator计算得到的值计算出属性值。

ValueAnimator根据动画已进行的时间跟动画总时间&#xff08;duration&#xff09;的比计算出一个时间因子&#xff08;0~1&#xff09;&#xff0c;然后根据TimeInterpolator计算出另一个因子&#xff0c;最后TypeAnimator通过这个因子计算出属性值&#xff0c;如上例中10ms时&#xff1a;

首先计算出时间因子&#xff0c;即经过的时间百分比&#xff1a;t&#61;10ms/40ms&#61;0.25

经插值计算(inteplator)后的插值因子:大约为0.15&#xff0c;上述例子中用了AccelerateDecelerateInterpolator&#xff0c;计算公式为&#xff08;input即为时间因子&#xff09;&#xff1a;

(Math.cos((input &#43; 1) * Math.PI) / 2.0f) &#43; 0.5f;

最后根据TypeEvaluator计算出在10ms时的属性值&#xff1a;0.15*&#xff08;40-0&#xff09;&#61;6pixel。上例中TypeEvaluator为FloatEvaluator&#xff0c;计算方法为 &#xff1a;

public Float evaluate(float fraction, Number startValue, Number endValue) {float startFloat &#61; startValue.floatValue();return startFloat &#43; fraction * (endValue.floatValue() - startFloat);
}

参数分别为上一步的插值因子&#xff0c;开始值与结束值。

3.2 ValueAnimator

ValueAnimator包含Property Animation动画的所有核心功能&#xff0c;如动画时间&#xff0c;开始、结束属性值&#xff0c;相应时间属性值计算方法等。应用Property Animation有两个步聚&#xff1a;

  1. 计算属性值
  2. 根据属性值执行相应的动作&#xff0c;如改变对象的某一属性。

ValuAnimiator只完成了第一步工作&#xff0c;如果要完成第二步&#xff0c;需要实现ValueAnimator.onUpdateListener接口&#xff0c;这个接口只有一个函数onAnimationUpdate()&#xff0c;在这个函数中会传入ValueAnimator对象做为参数&#xff0c;通过这个ValueAnimator对象的getAnimatedValue()函数可以得到当前的属性值如&#xff1a;

ValueAnimator animation &#61; ValueAnimator.ofFloat(0f, 1f);
animation.setDuration(1000);
animation.addUpdateListener(new AnimatorUpdateListener() {
&#64;Override
public void onAnimationUpdate(ValueAnimator animation) {
Log.i("update", ((Float) animation.getAnimatedValue()).toString());
}
});
animation.setInterpolator(new CycleInterpolator(3));
animation.start();

此示例中只是向Logcat输出了一些信息&#xff0c;可以改为想做的工作。

Animator.AnimatorListener

onAnimationStart()onAnimationEnd()onAnimationRepeat()//当动画被取消时调用&#xff0c;同时会调用onAnimationEnd().
onAnimationCancel()

ValueAnimator.AnimatorUpdateListener

onAnimationUpdate()  //通过监听这个事件在属性的值更新时执行相应的操作&#xff0c;对于ValueAnimator一般要监听此事件执行相应的动作&#xff0c;不然Animation没意义&#xff0c;在ObjectAnimator&#xff08;继承自ValueAnimator&#xff09;中会自动更新属性&#xff0c;如无必要不必监听。在函数中会传递一个ValueAnimator参数&#xff0c;通过此参数的getAnimatedValue()取得当前动画属性值。

可以继承AnimatorListenerAdapter而不是实现AnimatorListener接口来简化操作&#xff0c;这个类对AnimatorListener中的函数都定义了一个空函数体&#xff0c;这样我们就只用定义想监听的事件而不用实现每个函数却只定义一空函数体。

ObjectAnimator oa&#61;ObjectAnimator.ofFloat(tv, "alpha", 0f, 1f);
oa.setDuration(
3000);
oa.addListener(
new AnimatorListenerAdapter(){public void on AnimationEnd(Animator animation){Log.i("Animation","end");}
});
oa.start();

3.3 ObjectAnimator

继承自ValueAnimator&#xff0c;要指定一个对象及该对象的一个属性&#xff0c;当属性值计算完成时自动设置为该对象的相应属性&#xff0c;即完成了Property Animation的全部两步操作。实际应用中一般都会用ObjectAnimator来改变某一对象的某一属性&#xff0c;但用ObjectAnimator有一定的限制&#xff0c;要想使用ObjectAnimator&#xff0c;应该满足以下条件&#xff1a;

  • 对象应该有一个setter函数&#xff1a;set&#xff08;驼峰命名法&#xff09;
  • 如上面的例子中&#xff0c;像ofFloat之类的工场方法&#xff0c;第一个参数为对象名&#xff0c;第二个为属性名&#xff0c;后面的参数为可变参数&#xff0c;如果values…参数只设置了一个值的话&#xff0c;那么会假定为目的值&#xff0c;属性值的变化范围为当前值到目的值&#xff0c;为了获得当前值&#xff0c;该对象要有相应属性的getter方法&#xff1a;get
  • 如果有getter方法&#xff0c;其应返回值类型应与相应的setter方法的参数类型一致。

如果上述条件不满足&#xff0c;则不能用ObjectAnimator&#xff0c;应用ValueAnimator代替。

tv&#61;(TextView)findViewById(R.id.textview1);
btn
&#61;(Button)findViewById(R.id.button1);
btn.setOnClickListener(
new OnClickListener() {&#64;Overridepublic void onClick(View v) {ObjectAnimator oa&#61;ObjectAnimator.ofFloat(tv, "alpha", 0f, 1f);oa.setDuration(3000);oa.start();}
});

把一个TextView的透明度在3秒内从0变至1。

根据应用动画的对象或属性的不同&#xff0c;可能需要在onAnimationUpdate函数中调用invalidate()函数刷新视图。

3.4 通过AnimationSet应用多个动画

AnimationSet提供了一个把多个动画组合成一个组合的机制&#xff0c;并可设置组中动画的时序关系&#xff0c;如同时播放&#xff0c;顺序播放等。

以下例子同时应用5个动画&#xff1a;

  1. 播放anim1&#xff1b;
  2. 同时播放anim2,anim3,anim4&#xff1b;
  3. 播放anim5。

AnimatorSet bouncer &#61; new AnimatorSet();
bouncer.play(anim1).before(anim2);
bouncer.play(anim2).with(anim3);
bouncer.play(anim2).with(anim4)
bouncer.play(anim5).after(amin2);
animatorSet.start();

3.5 TypeEvalutors

根据属性的开始、结束值与TimeInterpolation计算出的因子计算出当前时间的属性值&#xff0c;android提供了以下几个evalutor&#xff1a;

  • IntEvaluator&#xff1a;属性的值类型为int&#xff1b;
  • FloatEvaluator&#xff1a;属性的值类型为float&#xff1b;
  • ArgbEvaluator&#xff1a;属性的值类型为十六进制颜色值&#xff1b;
  • TypeEvaluator&#xff1a;一个接口&#xff0c;可以通过实现该接口自定义Evaluator。

自定义TypeEvalutor很简单&#xff0c;只需要实现一个方法&#xff0c;如FloatEvalutor的定义&#xff1a;

public class FloatEvaluator implements TypeEvaluator {public Object evaluate(float fraction, Object startValue, Object endValue) {float startFloat &#61; ((Number) startValue).floatValue();return startFloat &#43; fraction * (((Number) endValue).floatValue() - startFloat);}
}

根据动画执行的时间跟应用的Interplator&#xff0c;会计算出一个0~1之间的因子&#xff0c;即evalute函数中的fraction参数&#xff0c;通过上述FloatEvaluator应该很好看出其意思。

3.6 TimeInterplator

Time interplator定义了属性值变化的方式&#xff0c;如线性均匀改变&#xff0c;开始慢然后逐渐快等。在Property Animation中是TimeInterplator&#xff0c;在View Animation中是Interplator&#xff0c;这两个是一样的&#xff0c;在3.0之前只有Interplator&#xff0c;3.0之后实现代码转移至了TimeInterplator。Interplator继承自TimeInterplator&#xff0c;内部没有任何其他代码。

  • AccelerateInterpolator          加速&#xff0c;开始时慢中间加速
  • DecelerateInterpolator         减速&#xff0c;开始时快然后减速
  • AccelerateDecelerateInterolator    先加速后减速&#xff0c;开始结束时慢&#xff0c;中间加速
  • AnticipateInterpolator        反向 &#xff0c;先向相反方向改变一段再加速播放
  • AnticipateOvershootInterpolator    反向加回弹&#xff0c;先向相反方向改变&#xff0c;再加速播放&#xff0c;会超出目的值然后缓慢移动至目的值
  • BounceInterpolator         跳跃&#xff0c;快到目的值时值会跳跃&#xff0c;如目的值100&#xff0c;后面的值可能依次为85&#xff0c;77&#xff0c;70&#xff0c;80&#xff0c;90&#xff0c;100
  • CycleIinterpolator         循环&#xff0c;动画循环一定次数&#xff0c;值的改变为一正弦函数&#xff1a;Math.sin(2 * mCycles * Math.PI * input)
  • LinearInterpolator         线性&#xff0c;线性均匀改变
  • OvershottInterpolator        回弹&#xff0c;最后超出目的值然后缓慢改变到目的值
  • TimeInterpolator           一个接口&#xff0c;允许你自定义interpolator&#xff0c;以上几个都是实现了这个接口

3.7 当Layout改变时应用动画

ViewGroup中的子元素可以通过setVisibility使其Visible、Invisible或Gone&#xff0c;当有子元素可见性改变时(VISIBLE、GONE)&#xff0c;可以向其应用动画&#xff0c;通过LayoutTransition类应用此类动画&#xff1a;

transition.setAnimator(LayoutTransition.DISAPPEARING, customDisappearingAnim);

通过setAnimator应用动画&#xff0c;第一个参数表示应用的情境&#xff0c;可以以下4种类型&#xff1a;

  • APPEARING        当一个元素在其父元素中变为Visible时对这个元素应用动画
  • CHANGE_APPEARING    当一个元素在其父元素中变为Visible时&#xff0c;因系统要重新布局有一些元素需要移动&#xff0c;对这些要移动的元素应用动画
  • DISAPPEARING       当一个元素在其父元素中变为GONE时对其应用动画
  • CHANGE_DISAPPEARING   当一个元素在其父元素中变为GONE时&#xff0c;因系统要重新布局有一些元素需要移动&#xff0c;这些要移动的元素应用动画.

第二个参数为一Animator。

mTransitioner.setStagger(LayoutTransition.CHANGE_APPEARING, 30);

此函数设置动画延迟时间&#xff0c;参数分别为类型与时间。

3.8 Keyframes

keyFrame是一个 时间/值 对&#xff0c;通过它可以定义一个在特定时间的特定状态&#xff0c;即关键帧&#xff0c;而且在两个keyFrame之间可以定义不同的Interpolator&#xff0c;就好像多个动画的拼接&#xff0c;第一个动画的结束点是第二个动画的开始点。KeyFrame是抽象类&#xff0c;要通过ofInt(),ofFloat(),ofObject()获得适当的KeyFrame&#xff0c;然后通过PropertyValuesHolder.ofKeyframe获得PropertyValuesHolder对象&#xff0c;如以下例子&#xff1a;

Keyframe kf0 &#61; Keyframe.ofInt(0, 400);
Keyframe kf1
&#61; Keyframe.ofInt(0.25f, 200);
Keyframe kf2
&#61; Keyframe.ofInt(0.5f, 400);
Keyframe kf4
&#61; Keyframe.ofInt(0.75f, 100);
Keyframe kf3
&#61; Keyframe.ofInt(1f, 500);
PropertyValuesHolder pvhRotation
&#61; PropertyValuesHolder.ofKeyframe("width", kf0, kf1, kf2, kf4, kf3);
ObjectAnimator rotationAnim
&#61; ObjectAnimator.ofPropertyValuesHolder(btn2, pvhRotation);
rotationAnim.setDuration(
2000);

上述代码的意思为&#xff1a;设置btn对象的width属性值使其&#xff1a;

  • 开始时 Width&#61;400
  • 动画开始1/4时 Width&#61;200
  • 动画开始1/2时 Width&#61;400
  • 动画开始3/4时 Width&#61;100
  • 动画结束时 Width&#61;500
第一个参数为时间百分比&#xff0c;第二个参数是在第一个参数的时间时的属性值。
定义了一些Keyframe后&#xff0c;通过PropertyValuesHolder类的方法ofKeyframe一个PropertyValuesHolder对象&#xff0c;然后通过ObjectAnimator.ofPropertyValuesHolder获得一个Animator对象。
用下面的代码可以实现同样的效果&#xff08;上述代码时间值是线性&#xff0c;变化均匀&#xff09;&#xff1a;

ObjectAnimator oa&#61;ObjectAnimator.ofInt(btn2, "width", 400,200,400,100,500);
oa.setDuration(2000);
oa.start();

3.9 Animating Views

在View Animation中&#xff0c;对View应用Animation并没有改变View的属性&#xff0c;动画的实现是通过其Parent View实现的&#xff0c;在View被drawn时Parents View改变它的绘制参数&#xff0c;draw后再改变参数invalidate&#xff0c;这样虽然View的大小或旋转角度等改变了&#xff0c;但View的实际属性没变&#xff0c;所以有效区域还是应用动画之前的区域&#xff0c;比如你把一按钮放大两倍&#xff0c;但还是放大这前的区域可以触发点击事件。为了改变这一点&#xff0c;在Android 3.0中给View增加了一些参数并对这些参数增加了相应的getter/setter函数&#xff08;ObjectAnimator要用这些函数改变这些属性&#xff09;&#xff1a;

  • translationX,translationY: View相对于原始位置的偏移量
  • rotation,rotationX,rotationY: 旋转&#xff0c;rotation用于2D旋转角度&#xff0c;3D中用到后两个
  • scaleX,scaleY: 缩放比
  • x,y: View的最终坐标&#xff0c;是View的left&#xff0c;top位置加上translationX&#xff0c;translationY
  • alpha: 透明度
跟位置有关的参数有3个&#xff0c;以X坐标为例&#xff0c;可以通过getLeft(),getX(),getTranslateX()获得&#xff0c;若有一Button btn2&#xff0c;布局时其坐标为&#xff08;40,0&#xff09;&#xff1a;

//应用动画之前
btn2.getLeft(); //40
btn2.getX(); //40
btn2.getTranslationX(); //0
//应用translationX动画
ObjectAnimator oa&#61;ObjectAnimator.ofFloat(btn2,"translationX", 200);
oa.setDuration(2000);
oa.start();
/*应用translationX动画后
btn2.getLeft(); //40
btn2.getX(); //240
btn2.getTranslationX(); //200
*/
//应用X动画&#xff0c;假设没有应用之前的translationX动画
ObjectAnimator oa&#61;ObjectAnimator.ofFloat(btn2, "x", 200);
oa.setDuration(2000);
oa.start();
/*应用X动画后
btn2.getLeft(); //40
btn2.getX(); //200
btn2.getTranslationX(); //160
*/

无论怎样应用动画&#xff0c;原来的布局时的位置通过getLeft()获得&#xff0c;保持不变&#xff1b;
X是View最终的位置&#xff1b;
translationX为最终位置与布局时初始位置这差。
所以若就用translationX即为在原来基础上移动多少&#xff0c;X为最终多少
getX()的值为getLeft()与getTranslationX()的和
对于X动画&#xff0c;源代码是这样的&#xff1a;

case X:
info.mTranslationX &#61; value - mView.mLeft;
break;

Property Animation也可以在XML中定义

  • - AnimatorSet
  • - ValueAnimator
  • - ObjectAnimator
XML文件应放大/res/animator/中&#xff0c;通过以下方式应用动画&#xff1a;

AnimatorSet set &#61; (AnimatorSet) AnimatorInflater.loadAnimator(myContext, R.anim.property_animator);
set.setTarget(myObject);
set.start();

3.10 ViewPropertyAnimator

如果需要对一个View的多个属性进行动画可以用ViewPropertyAnimator类&#xff0c;该类对多属性动画进行了优化&#xff0c;会合并一些invalidate()来减少刷新视图&#xff0c;该类在3.1中引入。

以下两段代码实现同样的效果&#xff1a; 

PropertyValuesHolder pvhX &#61; PropertyValuesHolder.ofFloat("x", 50f);
PropertyValuesHolder pvhY &#61; PropertyValuesHolder.ofFloat("y", 100f);
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();

myView.animate().x(50f).y(100f);



作者&#xff1a;AngelDevil
出处&#xff1a;www.cnblogs.com/angeldevil

欢迎访问我的个人站点&#xff1a;angeldevil.me

转载请注明出处&#xff01;



推荐阅读
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • 在一对一直播源码使用过程中,有时会出现软键盘切换闪屏问题,就是当切换表情的时候屏幕会跳动,因此要对一对一直播源码表情面板无缝切换进行优化。 ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • 开发笔记:(002)spring容器中bean初始化销毁时执行的方法及其3种实现方式
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了(002)spring容器中bean初始化销毁时执行的方法及其3种实现方式相关的知识,希望对你有一定的参考价值。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 本文介绍了Android中的assets目录和raw目录的共同点和区别,包括获取资源的方法、目录结构的限制以及列出资源的能力。同时,还解释了raw目录中资源文件生成的ID,并说明了这些目录的使用方法。 ... [详细]
  • Activiti7流程定义开发笔记
    本文介绍了Activiti7流程定义的开发笔记,包括流程定义的概念、使用activiti-explorer和activiti-eclipse-designer进行建模的方式,以及生成流程图的方法。还介绍了流程定义部署的概念和步骤,包括将bpmn和png文件添加部署到activiti数据库中的方法,以及使用ZIP包进行部署的方式。同时还提到了activiti.cfg.xml文件的作用。 ... [详细]
  • 基于移动平台的会展导游系统APP设计与实现的技术介绍与需求分析
    本文介绍了基于移动平台的会展导游系统APP的设计与实现过程。首先,对会展经济和移动互联网的概念进行了简要介绍,并阐述了将会展引入移动互联网的意义。接着,对基础技术进行了介绍,包括百度云开发环境、安卓系统和近场通讯技术。然后,进行了用户需求分析和系统需求分析,并提出了系统界面运行流畅和第三方授权等需求。最后,对系统的概要设计进行了详细阐述,包括系统前端设计和交互与原型设计。本文对基于移动平台的会展导游系统APP的设计与实现提供了技术支持和需求分析。 ... [详细]
  • 今天就跟大家聊聊有关怎么在Android应用中实现一个换肤功能,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根 ... [详细]
  • 【CTF 攻略】第三届 SSCTF 全国网络安全大赛—线上赛 Writeup
    【CTF 攻略】第三届 SSCTF 全国网络安全大赛—线上赛 Writeup ... [详细]
author-avatar
yanna00799
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有