Analysis of LayoutAnimation in Android

Posted by grantc2 on Wed, 08 Dec 2021 07:59:47 +0100

PS: This article is a reprint of the article. Reading the original text will be more readable. There is a link to the original text at the end of the article

ps: the source code is analyzed based on android api 27

LayoutAnimation is used to animate the sub views of the layout or ViewGroup. The animation of each sub View starts at different times, but the same animation is used. As long as LayoutAnimation is used for layout animation, its implementation depends on the layout animation controller; What is the layout animation controller used for? It is used to calculate the offset time at which the animation of each child begins to execute.

There are two kinds of LayoutAnimation controllers, one is LayoutAnimationController and the other is GridLayoutAnimationController. In fact, GridLayoutAnimationController inherits from LayoutAnimationController and has similar functions, but has several more function parameters than LayoutAnimationController; Now let's write a demo to see the effect, and then analyze the relevant source code;

1,LayoutAnimationController demo

1. 1. Use XML to animate

(1) Add the RecyclerView dependency in the build.gradle file in the app Directory:

implementation "com.android.support:recyclerview-v7:26+"

(2) Create a new Activity named 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) Layout file activity corresponding to LayoutAnimationControllerActivity_ 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) Create an anim folder in the res directory and an XML file layout corresponding to layoutAnimation in the anim directory_ 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) Create a new XML file item corresponding to animation under the animation folder_ 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) The Adapter implementation class corresponding to RecyclerView 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("The first" + (position+1) + "Entries");
}

@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) Item layout file item corresponding to LayoutAnimationControllerAdapter_ 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="Hello"
android:layout_width="match_parent"
android:background="#00FF00"
android:layout_height="50px">

</TextView>

After the program runs, the effect is as follows:

1. 2 animation in Java

(1) We modify the animation based on xml and create a new Activity named 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) Layout file activity corresponding to LayoutAnimationController2activity_layout_animation_controller2.xml (Note: layoutAnimation attribute is not added in RecyclerView):

<?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>

I won't run the program anymore. Its effect is the same as that of 1 and 1 xml animation; The animation is carried out in Java, and the xml file corresponding to the animation is loaded through AnimationUtils; The delay and animationOrder attributes in the corresponding xml file of layoutAnimation are implemented by using setDelay and setOrder methods of LayoutAnimationController.

2,2 GridLayoutAnimationController demo

2. 1. Use XML to animate

(1) Create a new Activity named 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) Layout file activity corresponding to gridlayoutanimationactivity_ 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) Create a new XML file layout corresponding to layoutAnimation in the anim directory_ 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) Create a new XML file slide corresponding to animation under the animation folder_ 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) Adapter implementation class corresponding to GridView 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) Item layout file item corresponding to GridAdapter_ 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>

After the program runs, the effect is as follows:

2. 2 animation in Java

(1) We modify the animation based on xml and create a new Activity named 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) Layout file activity corresponding to gridlayoutanimation2activity_grid_layout_animation2.xml (Note: the GridView here does not add layoutAnimation attribute):

<?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>

I won't run the program anymore. The effect of animation is the same as that of 2 and 1 xml; The animation is carried out in Java, and the xml file corresponding to the animation is loaded through AnimationUtils; The directionPriority, columnDelay and rowDelay attributes in the corresponding xml file of layoutAnimation are realized by using the setDirectionPriority, setColumnDelay and setRowDelay methods of GridLayoutAnimationController.

We animate the layout in the LayoutAnimationController demo (XML)_ animation_ fall_ The attributes in the layoutAnimation tag of the down.xml file are described:

(1) Animation: defines the animation file to be executed for each item in the layout or view group.

(2) Delay: delay in setting animation. 0% means that all projects are animated at the same time, 100% means that each project will start the next project after completing its animation, and 15% means that the animation of the next project will start when the project animation reaches 15%.

(3) animationOrder: controls the animation sequence of sub projects. There are three types by default. Normal means that the animation will be performed from top to bottom in the vertical direction and from left to right in the horizontal direction according to the natural order of the layout; reverse and normal are opposite; random indicates that sub item animation appears randomly.

Let's then animate the layout in the GridLayoutAnimationController demo (XML)_ animation_ Describe the attributes in the gridLayoutAnimation tag of the grid.xml file and expand a direction attribute:

(1) rowDelay: the delay at the beginning of each line of animation.

(2) Column delay: the delay at the beginning of each column animation.

(3) directionPriority: direction priority. Row indicates row priority, column indicates column priority, and none indicates simultaneous; For example, if columns have priority, the animation will be executed one by one. After the execution of the first column is completed, the second column will be executed. The same reasoning applies to others.

This article has come to an end here, but it is not finished. The next article will continue to analyze their source code.

picture

Pay attention to WeChat official account and read more articles

Topics: Java Android