Fragment中ListView自定义BaseAdapter按钮跳转Activity的共享元素过渡失效
Hey, I’ve dealt with similar head-scratchers when implementing shared element transitions in Fragment+ViewPager+ListView setups. The fact that Main2Activity only shows up after rotating the screen tells me the Activity is actually being created, but the transition animation is getting stuck or the window isn’t rendering properly. Let’s walk through the key fixes:
1. Use Unique Transition Names for Reusable List Items
ListView reuses item views, so if all your buttons have the same fixed transitionName, the system gets confused—this is a super common culprit for wonky transitions.
- Set dynamic transition names in your Adapter:
In thegetViewmethod, assign a unique transition name to each button using your item’s ID (or any unique identifier):
@Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false); holder = new ViewHolder(convertView); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } YourListItem item = getItem(position); // Assign unique transition name tied to the item holder.shareButton.setTransitionName("share_btn_" + item.getId()); // Handle button click holder.shareButton.setOnClickListener(v -> launchMain2Activity(v, item)); return convertView; } private void launchMain2Activity(View sharedView, YourListItem item) { Activity activity = (Activity) sharedView.getContext(); Intent intent = new Intent(activity, Main2Activity.class); intent.putExtra("TRANSITION_NAME", sharedView.getTransitionName()); // Pass any other data you need... // Create transition options ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation( activity, sharedView, sharedView.getTransitionName() ); // Start the activity with transition activity.startActivity(intent, options.toBundle()); }
- Match the transition name in Main2Activity:
Make sure the target view in Main2Activity has the exact same transition name. You can set it dynamically using the extra from the intent:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ... setup code View targetView = findViewById(R.id.target_shared_view); String transitionName = getIntent().getStringExtra("TRANSITION_NAME"); targetView.setTransitionName(transitionName); }
2. Enable Window Content Transitions
If your Main2Activity doesn’t have content transitions enabled, the shared element animation can’t run—and this can cause the Activity to fail to render properly until a configuration change (like rotating the screen).
- Option 1: Enable via theme:
Add these lines to your Main2Activity’s theme instyles.xml:
<style name="AppTheme.Main2Activity" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="android:windowContentTransitions">true</item> <!-- Optional: Specify transition types --> <item name="android:windowSharedElementEnterTransition">@android:transition/move</item> <item name="android:windowSharedElementExitTransition">@android:transition/move</item> </style>
Then link the theme to your Activity in AndroidManifest.xml:
<activity android:name=".Main2Activity" android:theme="@style/AppTheme.Main2Activity"/>
- Option 2: Enable via code (must call before setContentView!):
@Override protected void onCreate(Bundle savedInstanceState) { // Enable transitions first getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); getWindow().setSharedElementEnterTransition(TransitionInflater.from(this).inflateTransition(android.R.transition.move)); getWindow().setSharedElementExitTransition(TransitionInflater.from(this).inflateTransition(android.R.transition.move)); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); // ... rest of your setup }
3. Ensure Fragment & ListView Are Fully Initialized
ViewPager preloads adjacent fragments, but sometimes the ListView or its adapter might not be fully ready when the button is clicked. Make sure you initialize the ListView in the Fragment’s onViewCreated method (not onCreate) to guarantee the view hierarchy is complete:
@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); ListView listView = view.findViewById(R.id.fragment_list_view); YourAdapter adapter = new YourAdapter(getContext(), yourDataList); listView.setAdapter(adapter); }
4. Fix Context & Activity Startup Logic
Using the wrong context to start the Activity can cause transition issues. Always use the Fragment’s attached Activity context when creating transition options:
// In your Adapter's click handler, get the Activity from the view's context Activity activity = (Activity) v.getContext(); // Then create options and start the activity as shown earlier
5. Rule Out Animation Conflicts
If your button has its own click animations (like ripple effects), they might interfere with the shared element transition. Try temporarily disabling the button’s ripple to test:
<!-- In your list item layout, remove or override the ripple --> <Button android:id="@+id/share_button" android:background="@null" android:clickable="true" android:focusable="true"/>
Or clear animations in the click handler:
holder.shareButton.setOnClickListener(v -> { v.clearAnimation(); launchMain2Activity(v, item); });
Go through these steps one by one—most likely the unique transition name or missing window transition setup is the root cause. Let me know if you hit any snags!
内容的提问来源于stack exchange,提问作者Dev b

