无意间发现animateLayoutChanges这个属性,用来实现布局更新动画,也就是每次对布局做出更改后运行的预加载动画,通过给布局中增加animateLayoutChanges=“true”,就能轻易完成。
一、实现
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/shadow_activity"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<Button
android:text="添加新View"
android:onClick="onAddViewClick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></Button>
<LinearLayout
android:orientation="vertical"
android:id="@+id/linearLayout"
android:animateLayoutChanges="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
</LinearLayout>
import android.animation.LayoutTransition;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private int mCount=1;
private LinearLayout mLinearLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLinearLayout= findViewById(R.id.linearLayout);
}
public void onAddViewClick(View view) {
TextView textView = new TextView(this);
textView.setText("newItem:"+mCount++);
ViewGroup.MarginLayoutParams params =new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,130);
params.bottomMargin=10;
textView.setLayoutParams(params);
textView.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
textView.setTextColor(Color.WHITE);
textView.setGravity(Gravity.CENTER|Gravity.LEFT);
mLinearLayout.addView(textView,0);
}
}
是不是很简单?
二、在ListView中使用
同样,在ListView中设置android:animateLayoutChanges=“true”。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/shadow_activity"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<Button
android:text="添加新View"
android:onClick="onAddViewClick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></Button>
<ListView
android:id="@+id/listview"
android:animateLayoutChanges="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</LinearLayout>
这里用一个很简单的数组适配器
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private ListView mListView;
private ArrayAdapter<String> mArrayAdapter;
private List<String > mDatas;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView= findViewById(R.id.listview);
mDatas = new ArrayList<>();
mArrayAdapter =new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,mDatas);
mListView.setAdapter(mArrayAdapter);
}
public void onAddViewClick(View view) {
mDatas.add(0,"newItem"+(mDatas.size()+1));
mArrayAdapter.notifyDataSetChanged();
}
}
三、LayoutTransition
既然可以通过xml设置,当然可以代码设置了,自然会用到LayoutTransition类。
通过ViewGroup.setLayoutTransition可以对ViewGroup设置子view增删时的动画,如下面的例子,并且设置动画将在1秒钟完成。
LayoutTransition layoutTransition = new LayoutTransition();
layoutTransition.setDuration(1000);
mListView.setLayoutTransition(layoutTransition);
还可以自定义动画,如设置一个从右到左进入的效果
LayoutTransition layoutTransition = new LayoutTransition();
ObjectAnimator animator = ObjectAnimator.ofFloat(mListView, "translationX", 200, 0);
layoutTransition.setAnimator(LayoutTransition.APPEARING, animator);
mListView.setLayoutTransition(layoutTransition);
LayoutTransition有5中动画类型:
1.APPEARING :容器中出现新view上运行的动画。
2.CHANGE_APPEARING:由于容器中出现新view,其他被动要改变自身位置的view运行动画。
3.CHANGE_DISAPPEARING :由于某个view从容器中消失而,其他被动要改变自身位置的view运行的动画。
4.CHANGING:布局改变时在这些view上运行的动画,而布局更改不是由于将view添加到容器或从容器中移除而导致的。
5.DISAPPEARING:容器中消失的view上运行的动画。
而上面的例子对APPEARING设置了动画,同样setDuration也有另个一重载方式,指对那个类型设置时长。