ViewGroup
ViewGroup也是自定义View中的一种,可以根据自己的想法将不同的View添加进去,也可以理解为一个存放View的数组容器。ViewGroup是一种特殊的视图可以包含其他视图(称为子View)的视图组基类的布局和视图的容器。这个类也定义了viewgroup.layoutparams类作为基类的布局参数。
要有一个继承于ViewGroup的类。重写其中的onMeasure()方法和onLayout()方法,两个构造器
用于测量ViewGroup的宽和高的方法onMeasure(),,用法和自定义的View一样;
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width =getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec);
height=getDefaultSize(getSuggestedMinimumHeight(),heightMeasureSpec);
//设置子View的宽和高
measureChildren(width, height);
}
用于放添加的子View的onLayout()方法,把子View放到这个布局上;
protected void onLayout(boolean changed, int l, int t, int r, int b) {
}
}
得到子View的大小位置如下:
child.layout(l,t,r,b);给其子View分配宽和高位置
l:相对于父View的左边的位置,t:相对于父View的d顶部边的位置
r:相对于父View的右边的位置,b:相对于父View的底边的位置
child1.getMeasuredWidth()子View的宽,
child1.getMeasuredHeight()子View的高
MyViewGroup.java
public class MyViewGroup extends ViewGroup{
private int width;
private int height;
public MyViewGroup(Context context) {
super(context);
}
public MyViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width =getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec);
height=getDefaultSize(getSuggestedMinimumHeight(),heightMeasureSpec);
measureChildren(width, height); //设置子View的宽和高
}
//把子View放到这个布局上的方法
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
//getChildAt(0)得到布局中特定位置的子View,参数为获得子View的位置的顺序
View child1=getChildAt(0);
View child2=getChildAt(1);
View child3=getChildAt(2);
View child4=getChildAt(3);
//child.layout(l,t,r,b);给其子View分配宽和高位置
//l:相对于父View的左边的位置,t:相对于父View的d顶部边的位置
//r:相对于父View的右边的位置,b:相对于父View的底边的位置
//child1.getMeasuredWidth()子View的宽,
//child1.getMeasuredHeight()子View的高
if (child1!=null){
child1.layout(0,0,child1.getMeasuredWidth(),child1.getMeasuredHeight());
}
if (child2!=null){
child2.layout(r-child2.getMeasuredWidth(),0,r,child2.getMeasuredHeight());
}
if (child3!=null){
child3.layout(0,b-child3.getMeasuredHeight(),child3.getMeasuredWidth(),b);
}
if (child4!=null){
child4.layout(r-child4.getMeasuredWidth(),b-child4.getMeasuredHeight(),r,b);
}
}
}
activity_viewgroup.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/imagebac">
<com.example.administrator.canvas.widget.MyViewGroup
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="100dp"
android:layout_height="100dp"
android:text="我是左上角"/>
<Button
android:layout_width="100dp"
android:layout_height="100dp"
android:text="我是右上角吗"/>
<Button
android:layout_width="100dp"
android:layout_height="100dp"
android:text="我就是左下角,不服!"/>
<Button
android:layout_width="100dp"
android:layout_height="100dp"
android:text="我可能是右下角"/>
</com.example.administrator.canvas.widget.MyViewGroup>
</LinearLayout>
MyViewGroup.java
public class MyViewGroupActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_viewgroup);
}
}
动画
Animation
Animation提供进行补间动画的类,做动画可以让图片进行平移,旋转,缩放,设置透明度等。
设置动画的类Animation,所有的平移,旋转,缩放,设置透明度都是Animation的子类。提供类进行补间动画,包括:AlphaAnimation:设置透明度渐变的、控制对象的阿尔法级别的动画。
AlphaAnimation (float fromAlpha, float toAlpha)
在代码中创建动画对象时使用的构造器,
参数:
fromAlpha设置初始的Alpha值,
toAlpha设置最后的Alpha值TranslateAnimation:控制对象的平面位置的动画
TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)
在代码中创建平面移动的动画时的构造器
fromXDelta 起始的X轴坐标
toXDelta 最终的X轴坐标
fromYDelta 起始的轴坐标
toYDelta 最终的Y轴坐标RotateAnimation:控制对象的旋转的动画。
RotateAnimation (float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
在代码中创建平面里旋转动画时的构造器
fromDegrees起始旋转的角度,
toDegrees旋转后的角度
pivotXValue、pivotYValue旋转中心点的x、y的坐标
pivotXType、pivotYType指定旋转中心的坐标值得类型ScaleAnimation:控制对象的缩放大小的动画
ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY)
在代码中创建缩放大小动画时的构造器
fromX、fromY起始的宽和高
toX、toY缩放后的宽和高
pivotX、pivotY缩放点的坐标
setDuration()用来显示动画的时长,参数为毫秒数
alphaAnimation.setDuration(3000);
调用startAnimation()启用控件动画,参数为Animation或子类的实例对象
mImageZun.startAnimation(set);
实例:MyAnimationActivity.java
public class MyAnimationActivity extends AppCompatActivity implements View.OnClickListener{
private Button btn_StartAnimation;
private ImageView mImageView;
private ImageView mImageZun;
private ImageView mImageRotate;
private ImageView mImageViewScale;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animation);
mImageView= (ImageView) findViewById(R.id.image_smallgirl);
mImageZun= (ImageView) findViewById(R.id.image_translate);
mImageRotate= (ImageView) findViewById(R.id.image_rotate);
mImageViewScale= (ImageView) findViewById(R.id.image_scale);
btn_StartAnimation= (Button) findViewById(R.id.btn_startnimation);
btn_StartAnimation.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btn_startnimation:
AlphaAnimation alphaAnimation=new AlphaAnimation(0.0f,1.0f);
alphaAnimation.setDuration(3000);
mImageView.startAnimation(alphaAnimation);
TranslateAnimation translateAnimation=new TranslateAnimation(-mImageZun.getWidth(),0,0,0);
translateAnimation.setDuration(3000);
mImageZun.startAnimation(translateAnimation);
RotateAnimation rotateAnimation=new RotateAnimation(0,720);
rotateAnimation.setDuration(3000);
mImageRotate.startAnimation(rotateAnimation);
ScaleAnimation scaleAnimation=new ScaleAnimation(1,0.5f,1,0.5f);
scaleAnimation.setDuration(3000);
mImageViewScale.startAnimation(scaleAnimation);
break;
}
}
}
activity_animation.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/color_wallpaper5">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:id="@+id/btn_startnimation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="动起来"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/image_smallgirl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/smallgirl"
android:onClick="startAnimation"/>
<ImageView
android:id="@+id/image_rotate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/smallgirl"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/image_translate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/zun"/>
<ImageView
android:id="@+id/image_scale"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/zun"/>
</LinearLayout>
</LinearLayout>
</ScrollView>
AnimatorInflater 用户加载属性动画的xml文件
Repeat count and behavior:重复次数、以及重复模式;可以定义重复多少次;重复时从头开始,还是反向。
AnimationSet控制一组动画的执行:线性,一起,每个动画的先后执行等。
还可以将这些动画加到一个控件上去,就要用到AnimationSet,
可以使一组动画的运用在一起。每个动画的转型是由连成一个单一的变换。如果AnimationSet设置,它的子类也设置一些属性(例如,持续时间或fillBefore),AnimationSet的值覆盖子类的属性值。
AnimationSet(boolean shareInterpolator)用来创建Animation对象实例,参数为动画属性之间是否相互影响,同样用startAnimation(Animation)启动控件动画
AnimationSet set=new AnimationSet(false);
AlphaAnimation alphaAnimation=new AlphaAnimation(0.0f,1.0f);
alphaAnimation.setDuration(3000);
TranslateAnimation translateAnimation=new TranslateAnimation(-mImageZun.getWidth(),0,0,0);
translateAnimation.setDuration(3000);
RotateAnimation(0,720);
rotateAnimation.setDuration(3000);
ScaleAnimation(1,0.5f,1,0.5f);
scaleAnimation.setDuration(3000);
//addAnimation(alphaAnimation)将动画属性添加到AnimationSet里面
set.addAnimation(alphaAnimation);
set.addAnimation(translateAnimation);
set.addAnimation(rotateAnimation);
set.addAnimation(scaleAnimation);
mImageZun.startAnimation(set);
还可以在XML中设置动画属性
interpolator用来限制动画的变化率,允许基本的动画效果(α,规模,平移,旋转)被加速,减速,反复等,包含了以下几种interpolator:
1、LinearInterpolator变化率恒定的interpolator即线性变化的
2、CycleInterpolator动画的变化在一个特定的周期数目内反复,变化率遵循正弦模式,repeatCount用来指定反复变化的次数
3、AccelerateInterpolator变化率开始慢,慢慢加速,最后变化率加快,变化率加速变化
4、BounceInterpolator在变化结束的末端反弹
5、DecelerateInterpolator变化率开始加速后来减速
6、PathInterpolator可以遍历一个从(0,0)到(1,1)的路径的Interpolator
android:interpolator="@android:anim/cycle_interpolator"
android:repeatCount="0"
首先在res中创建anmi类型的文件夹,在其中创建文件,文件内容如下:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/cycle_interpolator"
>
<rotate android:fromDegrees="0"
android:repeatCount="0"
android:toDegrees="720"
android:duration="3000"
android:pivotX="50%"
android:pivotY="50%"
></rotate>
<scale android:startOffset="3000"
android:duration="3000"
android:pivotY="50%"
android:pivotX="50%"
android:repeatMode="restart"
android:fromXScale="0.5"
android:toXScale="1.0"
android:fromYScale="0.5"
android:toYScale="1.0"></scale>
</set>
在MyAnimationActivity.java中调用即可。
Animation animation=AnimationUtils.loadAnimation(getApplicationContext(), R.anim.animation);//AnimationUtils定义与动画工作的常用工具。从资源中加载一个动画对象。
mImageZun.startAnimation(animation);
Animator
首先在activity_animation.xml中的ImageView中添加点击事件
activity_animation.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/color_wallpaper5">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<ImageView
android:id="@+id/image_translate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/zun"
android:layout_centerInParent="true"
android:onClick="startAnimation"/>
/>
</RelativeLayout>
</LinearLayout>
</ScrollView>
MyAnimationActivity.java
public class MyAnimationActivity extends AppCompatActivity implements {
private ImageView mImageZun;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animation);
mImageZun= (ImageView) findViewById(R.id.image_translate);
ObjectAnimator线性变化
public void startAnimation(View view){
ObjectAnimator.ofFloat(mImageZun, "scaleY", 0.0f, 1.0f).setDuration(3000).start();
}
在XML中添加动画
首先在res创建一个animator类型的文件夹,在其创建一个文件,内容如下:
animator.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:duration="1000"
android:propertyName="scaleX"
android:valueFrom="0.1"
android:valueTo="1"
></objectAnimator>
<objectAnimator
android:duration="1000"
android:propertyName="scaleY"
android:valueFrom="0.1"
android:valueTo="1"
></objectAnimator>
</set>
MyAnimationActivity.java
public class MyAnimationActivity extends AppCompatActivity implements {
private ImageView mImageZun;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animation);
mImageZun= (ImageView) findViewById(R.id.image_translate);
//ObjectAnimator线性变化
public void startAnimation(View view){
// ObjectAnimator.ofFloat(mImageZun, "scaleY", 0.0f, 1.0f).setDuration(3000).start();
Animator objectAnimator= AnimatorInflater.loadAnimator(getApplication(),R.animator.animator);
objectAnimator.setTarget(mImageZun);
objectAnimator.start();
}
Layout Animations
主要使用LayoutTransition为布局的容器设置动画,当容器中的视图层次发生变化时存在过渡的动画效果。
LayoutTransition.APPEARING 当一个View在ViewGroup中出现时,对此View设置的动画
LayoutTransition.CHANGE_APPEARING 当一个View在ViewGroup中出现时,对此View对其他View位置造成影响,对其他View设置的动画
LayoutTransition.DISAPPEARING 当一个View在ViewGroup中消失时,对此View设置的动画
LayoutTransition.CHANGE_DISAPPEARING 当一个View在ViewGroup中消失时,对此View对其他View位置造成影响,对其他View设置的动画
LayoutTransition.CHANGE 不是由于View出现或消失造成对其他View位置造成影响,然后对其他View设置的动画。
注意动画到底设置在谁身上,此View还是其他View。
activity_linearlayout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_addbutton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="添加按钮"/>
<LinearLayout
android:id="@+id/linearlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"></LinearLayout>
</LinearLayout>
MyLinearLayoutActivity.java
public class MyLinearlayoutActivity extends Activity{
private Button btn_AddBtn;
private LinearLayout mLinearLayout;
private int count=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_linearlayout);
btn_AddBtn= (Button) findViewById(R.id.btn_addbutton);
mLinearLayout= (LinearLayout) findViewById(R.id.linearlayout);
LayoutTransition transition=new LayoutTransition();
transition.setDuration(1500);
transition.setAnimator(LayoutTransition.APPEARING, AnimatorInflater.loadAnimator(getApplicationContext(), R.animator.animator));
transition.setAnimator(LayoutTransition.CHANGE_APPEARING,transition.getAnimator(LayoutTransition.CHANGE_APPEARING));
transition.setAnimator(LayoutTransition.DISAPPEARING,transition.getAnimator(LayoutTransition.DISAPPEARING));
// transition.setAnimator(LayoutTransition.APPEARING,transition.getAnimator(LayoutTransition.CHANGE_DISAPPEARING));
mLinearLayout.setLayoutTransition(transition);
btn_AddBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
count++;
Button btn=new Button(MyLinearlayoutActivity.this);
ViewGroup.LayoutParams params=new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
btn.setLayoutParams(params);
btn.setText("按钮"+count);
btn.setScaleX(0f);
btn.setScaleY(0f);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
mLinearLayout.addView(btn);
}
});
}
}