You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android ListView Activity重建与点击结果重置及动画需求

解决方案与代码优化建议

兄弟,我仔细看了你的代码,先给你搞定重建Activity+重置状态+左滑动画的需求,再帮你梳理代码里的问题,给你更简单的实现思路~

一、实现重建+重置+左滑动画的核心代码

你需要先在res/anim目录下创建两个动画文件(没有anim目录就新建一个):

  • slide_in_left.xml(新Activity从左滑入):
<?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="300"/>
</set>
  • slide_out_right.xml(当前Activity向右滑出):
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="0" android:toXDelta="100%p" android:duration="300"/>
</set>

然后替换你原来的startActivity(...)为这一行代码:

finish(); startActivity(new Intent(SubjectSelectorActivity.this, SubjectSelectorActivity.class)); overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right);

解释下:finish()会销毁当前Activity,避免栈里堆积多个实例;overridePendingTransition则设置了左滑的切换动画,新页面从左边进入,旧页面从右边退出,同时新Activity会重新执行onCreate,自然重置所有状态。

二、你代码里的几个核心问题

  1. Activity实例堆积:你之前直接用startActivity启动自身,旧的Activity不会被销毁,栈里会积累多个SubjectSelectorActivity实例,不仅浪费内存,还会导致SharedPreferences的状态逻辑混乱。
  2. getView里的错误逻辑:你在Adapter的getView方法里重置counter,这绝对是个坑!getView会在ListView滚动、刷新时被多次调用,会导致counter被意外重置,完全打乱你的计数逻辑。
  3. 冗余的if判断:多个if(getCounter() == x)重复代码太多,用switch会更简洁,也不容易写错。
  4. Adapter性能与体验问题:每次getView都重新inflate布局,没有复用convertView,ListView滚动时会卡顿;而且点击选项后没有UI反馈,用户不知道自己选了哪个。

三、更简便的实现:不用重建Activity!

其实完全没必要重启Activity,直接重置状态+刷新Adapter就行,既高效又不会有栈问题:
比如在点击next按钮处理完存储后,直接重置状态并刷新:

// 处理完当前时段的存储后
SharedPreferences.Editor passEditor = getSharedPreferences("pass", MODE_PRIVATE).edit();
passEditor.remove("pass").apply(); // 清空选中的科目
adapter.notifyDataSetChanged(); // 刷新ListView,重置选中状态

同时优化你的Adapter,提升性能并添加选中反馈:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    Holder holder;
    // 复用convertView,避免重复inflate布局,提升滚动性能
    if (convertView == null) {
        holder = new Holder();
        convertView = inflater.inflate(R.layout.subject, parent, false);
        holder.tv1 = convertView.findViewById(R.id.subtext);
        holder.img = convertView.findViewById(R.id.subimg);
        convertView.setTag(holder);
    } else {
        holder = (Holder) convertView.getTag();
    }

    holder.tv1.setText(result[position]);
    holder.img.setImageResource(imageId[position]);

    // 添加选中状态的UI反馈,让用户直观看到自己选了哪个科目
    String selectedSub = getPass();
    if (selectedSub != null && selectedSub.equals(result[position])) {
        convertView.setBackgroundColor(getResources().getColor(R.color.subject_selected_bg)); // 自己在colors.xml定义一个选中背景色
    } else {
        convertView.setBackgroundColor(getResources().getColor(android.R.color.transparent));
    }

    convertView.setOnClickListener(v -> {
        SharedPreferences.Editor passe = getSharedPreferences("pass", MODE_PRIVATE).edit();
        passe.putString("pass", result[position]);
        passe.apply();
        adapter.notifyDataSetChanged(); // 点击后立即刷新UI显示选中状态
    });

    return convertView;
}

另外,把你那一堆if判断改成switch,代码更清爽:

@Override
public void onClick(View v) {
    String subposition = getPass();
    if (subposition == null) return;

    SharedPreferences counterPref = getSharedPreferences("counter", MODE_PRIVATE);
    int currentCounter = counterPref.getInt("counter", 0);
    SharedPreferences.Editor counterEditor = counterPref.edit();

    switch (currentCounter) {
        case 0:
            getSharedPreferences("MonP1", MODE_PRIVATE)
                .edit()
                .putString("MonP1", subposition)
                .apply();
            counterEditor.putInt("counter", 1).apply();
            // 重置选中状态并刷新
            getSharedPreferences("pass", MODE_PRIVATE).edit().remove("pass").apply();
            adapter.notifyDataSetChanged();
            break;
        case 1:
            getSharedPreferences("MonP2", MODE_PRIVATE)
                .edit()
                .putString("MonP2", subposition)
                .apply();
            counterEditor.putInt("counter", 2).apply();
            getSharedPreferences("pass", MODE_PRIVATE).edit().remove("pass").apply();
            adapter.notifyDataSetChanged();
            break;
        case 2:
            getSharedPreferences("MonP3", MODE_PRIVATE)
                .edit()
                .putString("MonP3", subposition)
                .apply();
            counterEditor.putInt("counter", 3).apply();
            startActivity(new Intent(SubjectSelectorActivity.this, MainActivity.class));
            break;
        case 3:
            // 重置counter,避免下次进入时状态异常
            counterEditor.putInt("counter", 0).apply();
            startActivity(new Intent(SubjectSelectorActivity.this, MainActivity.class));
            break;
    }
}

这样改完,你的代码逻辑更清晰,性能更好,用户体验也会提升~

内容的提问来源于stack exchange,提问作者Aden Diamond

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:41:00