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,自然重置所有状态。
二、你代码里的几个核心问题
- Activity实例堆积:你之前直接用
startActivity启动自身,旧的Activity不会被销毁,栈里会积累多个SubjectSelectorActivity实例,不仅浪费内存,还会导致SharedPreferences的状态逻辑混乱。 - getView里的错误逻辑:你在Adapter的
getView方法里重置counter,这绝对是个坑!getView会在ListView滚动、刷新时被多次调用,会导致counter被意外重置,完全打乱你的计数逻辑。 - 冗余的if判断:多个
if(getCounter() == x)重复代码太多,用switch会更简洁,也不容易写错。 - 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
相关产品推荐
相关产品推荐

