You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

为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代码里有两个核心问题:

  1. convertView为null时,你初始化了新的listItemView,但却调用convertView.startAnimation(animation)——这时候convertView还是null,会直接触发空指针异常
  2. 没有处理视图复用的场景,直接给复用视图播放动画会导致滚动时重复播放,影响体验

修正后的基础版本(仅首次加载视图时播放动画)

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

火山引擎 最新活动