将这样的动画添加到 ListView 是没有问题的,我在几分钟内为普通的非自定义 ListView 构建了这个解决方案,通常这种事情适用于任何开箱即用的 ListView,这一切都在适配器中。我的答案中唯一缺少的是滑动检测,不幸的是我现在没有时间测试它。但是滑动检测并不难,如果你用谷歌搜索的话,会有很多例子。无论如何,如果您有任何问题,请随时提出。
结果:
我使用的是带有 ViewHolder 模式的简单 BaseAdapter,没什么特别的,无论如何我都会发布 getView 方法以进行澄清:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(getItemId(position) == TEST_VIEW_ID) {
TestViewModel viewModel = (TestViewModel) getItem(position);
TestRow row;
if(convertView == null) {
convertView = this.inflater.inflate(TestRow.LAYOUT, parent, false);
row = new TestRow(convertView); // Here the magic happens
convertView.setTag(row);
}
row = (TestRow) convertView.getTag();
row.bind(viewModel);
}
return convertView;
}
在我的 ViewHolder 类中,这里称为 TestRow 我为动画创建了一些辅助方法,我将在下面进一步解释它们,但这里首先是来自 TestRow 的代码:
public class TestRow {
public static final int LAYOUT = R.layout.list_item_test;
public ImageView ivLogo;
public TextView tvFadeOut;
public TextView tvSlideIn;
public TestRow(View view) {
this.ivLogo = (ImageView) view.findViewById(R.id.ivLogo);
this.tvFadeOut = (TextView) view.findViewById(R.id.tvFadeOut);
this.tvSlideIn = (TextView) view.findViewById(R.id.tvSlideIn);
this.ivLogo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// When the ImageView is clicked the animations are applied to the TextViews.
if(tvFadeOut.getVisibility() == View.VISIBLE) {
fadeOutView(tvFadeOut);
slideInView(tvSlideIn);
} else {
fadeInView(tvFadeOut);
slideOutView(tvSlideIn);
}
}
});
}
public void bind(TestViewModel viewModel) {
// Nothing to do here
}
}
这里是我用于动画的辅助方法:
private void fadeOutView(View view) {
Animation fadeOut = AnimationUtils.loadAnimation(view.getContext(), R.anim.fade_out);
if (fadeOut != null) {
fadeOut.setAnimationListener(new ViewAnimationListener(view) {
@Override
protected void onAnimationStart(View view, Animation animation) {
}
@Override
protected void onAnimationEnd(View view, Animation animation) {
view.setVisibility(View.GONE);
}
});
view.startAnimation(fadeOut);
}
}
private void fadeInView(View view) {
Animation fadeIn = AnimationUtils.loadAnimation(view.getContext(), R.anim.fade_in);
if (fadeIn != null) {
fadeIn.setAnimationListener(new ViewAnimationListener(view) {
@Override
protected void onAnimationStart(View view, Animation animation) {
view.setVisibility(View.VISIBLE);
}
@Override
protected void onAnimationEnd(View view, Animation animation) {
}
});
view.startAnimation(fadeIn);
}
}
private void slideInView(View view) {
Animation slideIn = AnimationUtils.loadAnimation(view.getContext(), R.anim.slide_in_right);
if (slideIn != null) {
slideIn.setAnimationListener(new ViewAnimationListener(view) {
@Override
protected void onAnimationStart(View view, Animation animation) {
view.setVisibility(View.VISIBLE);
}
@Override
protected void onAnimationEnd(View view, Animation animation) {
}
});
view.startAnimation(slideIn);
}
}
private void slideOutView(View view) {
Animation slideOut = AnimationUtils.loadAnimation(view.getContext(), R.anim.slide_out_right);
if (slideOut != null) {
slideOut.setAnimationListener(new ViewAnimationListener(view) {
@Override
protected void onAnimationStart(View view, Animation animation) {
}
@Override
protected void onAnimationEnd(View view, Animation animation) {
view.setVisibility(View.GONE);
}
});
view.startAnimation(slideOut);
}
}
private abstract class ViewAnimationListener implements Animation.AnimationListener {
private final View view;
protected ViewAnimationListener(View view) {
this.view = view;
}
@Override
public void onAnimationStart(Animation animation) {
onAnimationStart(this.view, animation);
}
@Override
public void onAnimationEnd(Animation animation) {
onAnimationEnd(this.view, animation);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
protected abstract void onAnimationStart(View view, Animation animation);
protected abstract void onAnimationEnd(View view, Animation animation);
}
这些是我使用的动画 xml:
淡入:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<alpha
android:fromAlpha="0"
android:toAlpha="1"
android:duration="700"/>
</set>
淡出:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<alpha
android:fromAlpha="1"
android:toAlpha="0"
android:duration="700"/>
</set>
滑入:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="100%" android:toXDelta="0%"
android:duration="700"/>
</set>
滑出:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="0%" android:toXDelta="100%"
android:duration="700"/>
</set>