如何解决跳转至ListActivity时的界面跳动问题?
我有多个Activity,其他Activity的转场动画都很流畅,但每次导航到下面这个ListActivity时,界面都会出现跳动现象。我已经重写了动画类,但跳动问题依然存在。想请教下该如何解决?会不会是UI线程过载导致的?
public class ListActivity extends AppCompatActivity implements RecyclerViewAdapter.OnItemClickListener { RecyclerViewAdapter recyclerViewAdapter; RecyclerView recyclerView; private FirebaseFirestore db = FirebaseFirestore.getInstance(); private CollectionReference dbRef = db.collection("Archives"); Context context; FloatingActionButton fab; Item clickedItem; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list); overridePendingTransition(R.anim.fade_in, R.anim.fade_out); recyclerView = findViewById(R.id.recyclerView); fab = findViewById(R.id.fab); Toolbar toolbar = findViewById(R.id.toolbar); if (toolbar != null) { setSupportActionBar(toolbar); getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setHomeButtonEnabled(true); } toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); overridePendingTransition(R.anim.fade_in, R.anim.fade_out); } }); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(ListActivity.this, EnterDataActivity.class); startActivity(intent); } }); setUpAdapter(); } private void setUpAdapter() { Query query = dbRef.orderBy("fname", Query.Direction.DESCENDING); FirestoreRecyclerOptions<Item> options = new FirestoreRecyclerOptions.Builder<Item>() .setQuery(query, Item.class) .build(); recyclerViewAdapter = new RecyclerViewAdapter(options, ListActivity.this); recyclerViewAdapter.notifyDataSetChanged(); recyclerView.setHasFixedSize(true); recyclerView.setLayoutManager(new LinearLayoutManager(context)); recyclerView.setAdapter(recyclerViewAdapter); recyclerViewAdapter.setOnItemClickListener(ListActivity.this); } @Override public void onStart() { super.onStart(); recyclerViewAdapter.startListening(); } @Override public void onStop() { super.onStop(); recyclerViewAdapter.stopListening(); } @Override public void onItemClick(DocumentSnapshot documentSnapshot, int position) { clickedItem = documentSnapshot.toObject(Item.class); clickedItem.setId((documentSnapshot.getId())); Intent intent = new Intent(ListActivity.this, DetailActivity.class); intent.putExtra(First_Name, clickedItem.getFname()); intent.putExtra(Middle_Name, clickedItem.getMname()); intent.putExtra(Sur_Name, clickedItem.getSname()); intent.putExtra(Email, clickedItem.getEmail()); intent.putExtra(phone, clickedItem.getPhone()); intent.putExtra(city, clickedItem.getCity()); intent.putExtra(parents_Name, clickedItem.getParentsName()); intent.putExtra(parents_Phone, clickedItem.getParentsContact()); intent.putExtra(dob, clickedItem.getDob()); intent.putExtra(emergency, clickedItem.getEmergency()); intent.putExtra(profile_Picture, clickedItem.getProfilePicture()); overridePendingTransition(R.anim.fade_in, R.anim.fade_out); startActivityForResult(intent, 45); } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if ((requestCode == 45 && resultCode == RESULT_OK && data != null)) { String fname = data.getStringExtra(First_Name); String mname = data.getStringExtra(Middle_Name); String sname = data.getStringExtra(Sur_Name); String email = data.getStringExtra(Email); String Phone = data.getStringExtra(phone); String City = data.getStringExtra(city); String pname = data.getStringExtra(parents_Name); String pphone = data.getStringExtra(parents_Phone); String Dob = data.getStringExtra(dob); String Emergency = data.getStringExtra(emergency); String profile = data.getStringExtra(profile_Picture); Item items = new Item(fname, mname, sname, email, Phone, City, pname, pphone, Dob, Emergency, profile); db.collection("Archives").document(clickedItem.getId()) .set(items).addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void aVoid) { Toast.makeText(ListActivity.this, "Updated Successfully", Toast.LENGTH_LONG).show(); } }); } } }
我帮你梳理了代码里几个可能导致转场跳动的点,咱们逐一排查:
1. 未初始化的Context导致布局异常
你在setUpAdapter()里用了new LinearLayoutManager(context),但代码里只声明了Context context,却没给它赋值!这会让布局管理器初始化出问题,RecyclerView的布局计算混乱,直接引发转场时的跳动。
修复方法:
在onCreate里给context赋值:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list); context = this; // 加上这行,初始化context // ... 其他代码 }
2. 无意义的notifyDataSetChanged()调用
刚创建完recyclerViewAdapter就调用notifyDataSetChanged()完全没必要——此时Firestore还没开始加载数据,这行代码只会触发不必要的布局刷新,干扰转场动画的流畅性。
修复方法:
直接删掉这行代码:
// recyclerViewAdapter.notifyDataSetChanged(); // 移除这行无效代码
3. 转场动画的调用时机错误
你在onCreate里直接调用了overridePendingTransition,但此时Activity的布局还没完全初始化完成,动画和布局绘制冲突就会导致跳动。另外,onItemClick里把overridePendingTransition放在startActivityForResult之前也是错误的顺序。
修复方法:
- 移除
onCreate里的overridePendingTransition调用,转场动画更合理的设置时机是在启动当前Activity的前一个页面中,或者在当前Activity的onResume之后处理。 - 调整
onItemClick里的代码顺序:
startActivityForResult(intent, 45); overridePendingTransition(R.anim.fade_in, R.anim.fade_out); // 移到startActivityForResult之后
4. UI线程过载的排查与优化
如果上面的修改后还有跳动,就得考虑UI线程是否被阻塞。Firestore的startListening()是后台加载数据,但数据返回后更新RecyclerView是在UI线程,如果数据量太大或者Item布局复杂,就会卡顿。
优化建议:
- 给Firestore查询添加分页:用
limit()限制单次加载的数据量,配合startAfter()实现分页加载,避免一次性渲染大量Item。 - 优化Item布局:减少布局嵌套层级,用Android Studio的
Layout Inspector检查过度绘制问题,尽量用ConstraintLayout替代嵌套的LinearLayout/RelativeLayout。 - 保持
recyclerView.setHasFixedSize(true)开启(你已经加了这行,做得很好),它能减少RecyclerView的重绘次数。
5. 转场动画本身的问题
检查你的fade_in和fade_out动画文件,确保没有多余的位移属性。比如如果动画里不小心加了translateX/translateY,就会导致界面跳动。
示例正确的淡入动画(fade_in.xml):
<?xml version="1.0" encoding="utf-8"?> <alpha xmlns:android="http://schemas.android.com/apk/res/android" android:duration="300" android:fromAlpha="0.0" android:toAlpha="1.0" />
淡出动画(fade_out.xml):
<?xml version="1.0" encoding="utf-8"?> <alpha xmlns:android="http://schemas.android.com/apk/res/android" android:duration="300" android:fromAlpha="1.0" android:toAlpha="0.0" />
按上面的步骤逐一排查,应该能解决转场跳动的问题。
内容的提问来源于stack exchange,提问作者user11318019

