为Android ListView添加滚动时左滑进入动画(基于ArrayAdapter)
实现ListView列表项滚动时左侧滑入动画的正确方式
我看到你想要给ListView滚动时的列表项添加左侧滑入的动画,思路方向是对的,但现有代码里有几个关键问题需要修正,让我一步步帮你解决:
第一步:确认动画文件的正确配置
首先你需要把动画定义在res/anim/slide_left.xml中,用<set>标签包裹位移动画和透明度动画,确保两个动画可以同时执行:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="100%p" android:toXDelta="0" android:duration="500"/> <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="300"/> </set>
第二步:修正WordAdapter中的错误
你的Adapter代码里有两个核心问题:
- 当
convertView为null时,你初始化了新的listItemView,但却调用convertView.startAnimation(animation)——这时候convertView还是null,会直接触发空指针异常 - 没有处理视图复用的场景,直接给复用视图播放动画会导致滚动时重复播放,影响体验
修正后的基础版本(仅首次加载视图时播放动画)
public class WordAdapter extends ArrayAdapter<Word> { public WordAdapter(Context context, ArrayList<Word> words) { super(context, 0, words); } @Override public View getView(int position, View convertView, ViewGroup parent) { View listItemView = convertView; if (listItemView == null) { listItemView = LayoutInflater.from(getContext()).inflate(R.layout.activity_vocab, parent, false); // 只有新创建的视图才播放滑入动画 Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.slide_left); listItemView.startAnimation(animation); } Word currentWord = getItem(position); TextView englishView = listItemView.findViewById(R.id.englishWord); englishView.setText(currentWord.getmEnglishWord()); TextView translatedView = listItemView.findViewById(R.id.translatedWord); translatedView.setText(currentWord.getmTranslatedWordWord()); TextView exampleView = listItemView.findViewById(R.id.exampleWord); exampleView.setText(currentWord.getmExample()); return listItemView; } }
进阶优化版本(每个列表项仅播放一次动画,适配视图复用)
如果希望每个列表项不管是否被复用,都只播放一次滑入动画,可以添加一个标记记录已动画的位置:
public class WordAdapter extends ArrayAdapter<Word> { // 记录已经播放过动画的列表项位置 private HashMap<Integer, Boolean> animatedPositions = new HashMap<>(); public WordAdapter(Context context, ArrayList<Word> words) { super(context, 0, words); } @Override public View getView(int position, View convertView, ViewGroup parent) { View listItemView = convertView; if (listItemView == null) { listItemView = LayoutInflater.from(getContext()).inflate(R.layout.activity_vocab, parent, false); } Word currentWord = getItem(position); TextView englishView = listItemView.findViewById(R.id.englishWord); englishView.setText(currentWord.getmEnglishWord()); TextView translatedView = listItemView.findViewById(R.id.translatedWord); translatedView.setText(currentWord.getmTranslatedWordWord()); TextView exampleView = listItemView.findViewById(R.id.exampleWord); exampleView.setText(currentWord.getmExample()); // 判断当前位置是否已经播放过动画,未播放则执行 if (!animatedPositions.containsKey(position)) { Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.slide_left); listItemView.startAnimation(animation); animatedPositions.put(position, true); } return listItemView; } }
内容的提问来源于stack exchange,提问作者Noor




