乐趣区

关于java:Android中LayoutAnimation的分析一

PS:本文系转载文章,浏览原文可读性会更好,文章开端有原文链接

ps:源码是基于 android api 27 来剖析的

LayoutAnimation 是用于对布局或 ViewGroup 的子 View 进行动画解决,每个子 View 的动画在不同的工夫进行开始,然而应用的都是雷同的动画。只有应用 LayoutAnimation 进行布局动画,那么它的实现要依赖布局动画控制器来实现;布局动画控制器是用来干什么的呢?它是用于计算每个子项的动画开始执行的偏移工夫。

LayoutAnimation 控制器有 2 种,一种是 LayoutAnimationController,另外一种是 GridLayoutAnimationController,其实 GridLayoutAnimationController 是继承于 LayoutAnimationController,性能都差不多,只是比 LayoutAnimationController 多了几个性能参数;当初咱们先写 demo 看一下成果,而后再剖析一下相干的源码;

1、LayoutAnimationController demo

1、1 xml 的形式进行动画

(1)在 app 目录下的 build.gradle 文件增加 RecyclerView 的依赖:

implementation “com.android.support:recyclerview-v7:26+”

(2)新建一个 Activity,名叫 LayoutAnimationControllerActivity:

public class LayoutAnimationControllerActivity extends AppCompatActivity {

RecyclerView mRv;
@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_layout_animation_controller);
    mRv = findViewById(R.id.rv);
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
    linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
    mRv.setLayoutManager(linearLayoutManager);
    mRv.setAdapter(new LayoutAnimationControllerAdapter(this));
}

}

(3)LayoutAnimationControllerActivity 对应的布局文件 activity_layout_animation_controller.xml:

<?xml version=”1.0″ encoding=”utf-8″?>
<android.support.v7.widget.RecyclerView

xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutAnimation="@anim/layout_animation_fall_down"
tools:context=".LayoutAnimationControllerActivity">

</android.support.v7.widget.RecyclerView>

(4)在 res 目录下新建一个 anim 文件夹,在 anim 目录下新建一个 layoutAnimation 对应的 xml 文件 layout_animation_fall_down.xml:

layout_animation_fall_down.xml

<layoutAnimation xmlns:android=”http://schemas.android.com/apk/res/android”

android:animation="@anim/item_animation_drop_down"
android:animationOrder="normal"
android:delay="85%" />

(5)在 anim 文件夹上面新建一个 animation 对应的 xml 文件 item_animation_drop_down.xml:

item_animation_drop_down.xml

<set xmlns:android=”http://schemas.android.com/apk/res/android”

android:duration="800"
android:shareInterpolator="@android:anim/decelerate_interpolator">
<translate
    android:fromYDelta="-20%"
    android:toYDelta="0" />
<alpha
    android:fromAlpha="0"
    android:toAlpha="1" />
<scale
    android:fromXScale="105%"
    android:fromYScale="105%"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toXScale="100%"
    android:toYScale="100%" />

</set>

(6)RecyclerView 对应的 Adapter 实现类 LayoutAnimationControllerAdapter:

public class LayoutAnimationControllerAdapter extends RecyclerView.Adapter<LayoutAnimationControllerAdapter.LinearViewHolder> {

private Context mContext;

public LayoutAnimationControllerAdapter(Context context) {mContext = context;}

@NonNull
@Override
public LayoutAnimationControllerAdapter.LinearViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View item = LayoutInflater.from(mContext).inflate(R.layout.item_1, parent, false);
    return new LinearViewHolder(item);
}

@Override
public void onBindViewHolder(@NonNull LayoutAnimationControllerAdapter.LinearViewHolder holder, final int position) {holder.mTv.setText("第" + (position+1) + "个条目");
}

@Override
public int getItemCount() {return 100;}

class LinearViewHolder extends RecyclerView.ViewHolder {
    TextView mTv;
    public LinearViewHolder(View itemView) {super(itemView);
        mTv = itemView.findViewById(R.id.tv);
    }
}

}

(7)LayoutAnimationControllerAdapter 对应的 item 布局文件 item_1.xml:

<?xml version=”1.0″ encoding=”utf-8″?>
<TextView

xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tv"
android:layout_marginTop="10px"
android:text="你好"
android:layout_width="match_parent"
android:background="#00FF00"
android:layout_height="50px">

</TextView>

程序运行后,成果如下所示:

1、2 Java 的形式进行动画

(1)咱们在 xml 的形式进行动画的根底上进行批改,新建一个 Activity,名叫 LayoutAnimationController2Activity:

public class LayoutAnimationController2Activity extends AppCompatActivity {

RecyclerView mRv;
@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_layout_animation_controller2);
    mRv = findViewById(R.id.rv);
    final Animation animation = AnimationUtils.loadAnimation(this, R.anim.item_animation_drop_down);
    LayoutAnimationController layoutAnimation = new LayoutAnimationController(animation);
    layoutAnimation.setDelay(0.85f);
    layoutAnimation.setOrder(LayoutAnimationController.ORDER_NORMAL);
    mRv.setLayoutAnimation(layoutAnimation);
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
    linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
    mRv.setLayoutManager(linearLayoutManager);
    mRv.setAdapter(new LayoutAnimationControllerAdapter(this));
}

}

(2)LayoutAnimationController2Activity 对应的布局文件 activity_layout_animation_controller2.xml(留神:RecyclerView 中没有增加 layoutAnimation 属性):

<?xml version=”1.0″ encoding=”utf-8″?>
<android.support.v7.widget.RecyclerView

xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LayoutAnimationController2Activity">

</android.support.v7.widget.RecyclerView>

程序我就不再运行了,它的成果是跟 1、1 xml 的形式进行动画的成果是一样的;Java 的形式进行动画,通过 AnimationUtils 加载 animation 对应的 xml 文件;通过用 LayoutAnimationController 的 setDelay 和 setOrder 办法实现 layoutAnimation 对应 xml 文件中的 delay 和 animationOrder 属性。

2、2 GridLayoutAnimationController demo

2、1 xml 的形式进行动画

(1)新建一个 Activity,名叫 GridLayoutAnimationActivity:

public class GridLayoutAnimationActivity extends AppCompatActivity {

GridView mGv;
GridAdapter mGrideAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_grid_layout_animation);
    mGv = findViewById(R.id.gv);
    List<String> list = new ArrayList<String>();
    for (int i = 0; i < 100;i++) {list.add("item--"+i);
    }
    mGrideAdapter = new GridAdapter(this,list);
    mGv.setAdapter(mGrideAdapter);
}

}

(2) GridLayoutAnimationActivity 对应的布局文件 activity_grid_layout_animation.xml:

<?xml version=”1.0″ encoding=”utf-8″?>
<GridView

xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/gv"
android:layout_width="match_parent"
android:layout_height="100dp"
android:numColumns="4"
android:horizontalSpacing="10dp"
android:verticalSpacing="10dp"
android:layoutAnimation="@anim/layout_animation_grid"
tools:context=".GridLayoutAnimationActivity">

</GridView>

(3)在 anim 目录下新建一个 layoutAnimation 对应的 xml 文件 layout_animation_grid.xml:

layout_animation_grid.xml

<gridLayoutAnimation xmlns:android=”http://schemas.android.com/apk/res/android”

android:rowDelay="0%"
android:columnDelay="60%"
android:directionPriority="column"
android:animation="@anim/slide_in_left"/>

(4)在 anim 文件夹上面新建一个 animation 对应的 xml 文件 slide_in_left.xml:

slide_in_left.xml

<?xml version=”1.0″ encoding=”utf-8″?>
<set xmlns:android=”http://schemas.android.com/apk/res/android” android:duration=”1000″>

<translate android:fromXDelta="-50%p" android:toXDelta="0"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0" />

</set>

(5)GridView 对应的 Adapter 实现类 GridAdapter:

public class GridAdapter extends BaseAdapter {

private Context mContext;
private List<String> mList;

public GridAdapter(Context context,List<String> list) {
    mContext = context;
    mList = list;
}
public View getView(int position, View convertView, ViewGroup parent) {View item = LayoutInflater.from(mContext).inflate(R.layout.item_grid,parent,false);
    return item;
}

public final int getCount() {return mList == null ? 0 : mList.size();
}

public final Object getItem(int position) {return null;}

public final long getItemId(int position) {return position;}

}

(6)GridAdapter 对应的 item 布局文件 item_grid.xml

<?xml version=”1.0″ encoding=”utf-8″?>
<TextView

xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:text="hellow"
android:layout_height="wrap_content">

</TextView>

程序运行后,成果如下所示:

2、2 Java 的形式进行动画

(1) 咱们在 xml 的形式进行动画的根底上进行批改,新建一个 Activity,名叫 GridLayoutAnimation2Activity:

public class GridLayoutAnimation2Activity extends AppCompatActivity {

GridView mGv;
GridAdapter mGrideAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_grid_layout_animation2);
    mGv = findViewById(R.id.gv);
    List<String> list = new ArrayList<String>();
    for (int i = 0; i < 100;i++) {list.add("item--"+i);
    }
    final Animation animation = AnimationUtils.loadAnimation(this, R.anim.slide_in_left);
    GridLayoutAnimationController layoutAnimation = new GridLayoutAnimationController(animation);
    layoutAnimation.setDirectionPriority(GridLayoutAnimationController.PRIORITY_COLUMN);
    layoutAnimation.setColumnDelay(0.6f);
    layoutAnimation.setRowDelay(0f);
    mGv.setLayoutAnimation(layoutAnimation);
    mGrideAdapter = new GridAdapter(this,list);
    mGv.setAdapter(mGrideAdapter);
}

}

(2) GridLayoutAnimation2Activity 对应的布局文件 activity_grid_layout_animation2.xml(留神:这里的 GridView 也没有增加 layoutAnimation 属性):

<?xml version=”1.0″ encoding=”utf-8″?>
<GridView

xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/gv"
android:layout_width="match_parent"
android:layout_height="100dp"
android:numColumns="4"
android:horizontalSpacing="10dp"
android:verticalSpacing="10dp"
tools:context=".GridLayoutAnimation2Activity">

</GridView>

程序我就不再运行了,它跟 2、1 xml 的形式进行动画的成果是一样的;Java 的形式进行动画,通过 AnimationUtils 加载 animation 对应的 xml 文件;通过用 GridLayoutAnimationController 的 setDirectionPriority、setColumnDelay 和 setRowDelay 办法实现 layoutAnimation 对应 xml 文件中的 directionPriority、columnDelay 和 rowDelay 属性。

咱们对 LayoutAnimationController demo(xml 的形式进行动画)中 layout_animation_fall_down.xml 文件的 layoutAnimation 标签中的属性进行阐明:

(1)animation:定义布局或视图组中每一项要执行的动画文件。

(2)delay:设置动画的提早,0% 示意所有我的项目同时进行动画,100% 示意每个我的项目实现其动画后再开始下一个我的项目,15% 示意我的项目动画达到 15% 时开始下一一个我的项目的动画。

(3)animationOrder:管制子项目动画的程序,默认有三种类型,normal 示意依据布局的天然程序,如果是垂直方向,则会从上到下进行动画,如果是程度方向,则从左到右进行动画;reverse 和 normal 是反着来的;random 示意随机呈现子项目动画。

咱们再对 GridLayoutAnimationController demo(xml 的形式进行动画)中 layout_animation_grid.xml 文件的 gridLayoutAnimation 标签中的属性进行阐明并拓展一个 direction 属性:

(1)rowDelay:每一行动画开始的提早。

(2)columnDelay:每一列动画开始的提早。

(3)directionPriority:方向优先级,row 示意行优先,column 示意列优先,none 示意同时进行;例如,列优先,则一列一列的执行动画,第一列执行实现后再执行第二列,其余的同样这样推理。

这篇文章写到这里先告一段落了,然而还没完,下一篇会持续剖析它们的源码。

图片

关注微信公众号,浏览更多文章

退出移动版