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

Xamarin Android如何防止Activity重启?解决MP3播放器横竖屏问题

解决Xamarin Android中Activity因屏幕旋转重启的问题

嘿,我看你已经尝试添加了configChanges配置,但还是碰到Activity重启、歌曲中断的问题对吧?其实只靠Manifest配置还不够,得配合代码处理配置变化,才能完全避免重启并保留播放状态。下面给你一步步来的解决方案:

1. 确认Activity的ConfigurationChanges配置正确

在Xamarin里,直接给Activity类加特性配置比手动改AndroidManifest.xml更方便,而且不容易出错:

[Activity(
    Label = "PlaylistActivity",
    // 必须包含这三个配置项,API13+屏幕旋转需要ScreenSize
    ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.KeyboardHidden,
    // 如果你要支持横竖屏切换,这里别设死竖屏,改成Sensor或者FullSensor
    ScreenOrientation = ScreenOrientation.Sensor
)]
public class PlaylistActivity : Activity
{
    // 你的Activity代码
}

划重点:如果之前你把ScreenOrientation设成了Portrait,一定要改过来,不然根本没法切换到横屏!

2. 重写OnConfigurationChanged方法处理布局切换

加了上面的配置后,系统就不会重启Activity了,而是会调用OnConfigurationChanged方法。我们要在这里手动更新布局,同时保存并恢复播放状态:

首先,在Activity里定义好播放相关的变量,方便保存状态:

private MediaPlayer _mediaPlayer;
private int _currentPlayPosition;
private bool _isPlaying;
// 记录当前显示的是列表还是详情页
private bool _showingSongDetail;
// UI控件引用
private LinearLayout _songListLayout;
private LinearLayout _songDetailLayout;

然后在OnCreate里初始化这些变量和UI。接下来重写OnConfigurationChanged:

public override void OnConfigurationChanged(Configuration newConfig)
{
    base.OnConfigurationChanged(newConfig);

    // 第一步:保存当前播放状态和进度
    if (_mediaPlayer != null)
    {
        _currentPlayPosition = _mediaPlayer.CurrentPosition;
        _isPlaying = _mediaPlayer.IsPlaying;
        if (_isPlaying)
            _mediaPlayer.Pause(); // 先暂停,避免切换布局时卡顿
    }

    // 第二步:保存当前UI状态(比如是否显示详情页)
    _showingSongDetail = _songDetailLayout.Visibility == ViewStates.Visible;

    // 第三步:加载对应方向的布局
    // 如果横竖屏有单独的布局文件,就判断方向加载;如果是同一个布局自适应,直接调用SetContentView就行
    if (newConfig.Orientation == Orientation.Landscape)
        SetContentView(Resource.Layout.PlaylistActivity_Landscape);
    else
        SetContentView(Resource.Layout.PlaylistActivity_Portrait);

    // 第四步:重新初始化UI控件引用
    InitUiControls(); // 这个方法里重新FindViewById所有控件

    // 第五步:恢复UI状态(比如回到之前显示的列表/详情页)
    if (_showingSongDetail)
    {
        _songListLayout.Visibility = ViewStates.Gone;
        _songDetailLayout.Visibility = ViewStates.Visible;
    }
    else
    {
        _songListLayout.Visibility = ViewStates.Visible;
        _songDetailLayout.Visibility = ViewStates.Gone;
    }

    // 第六步:恢复播放状态
    if (_isPlaying && _mediaPlayer != null)
    {
        _mediaPlayer.SeekTo(_currentPlayPosition);
        _mediaPlayer.Start();
    }
}

3. 避坑提醒

  • 别在OnConfigurationChanged里重新创建MediaPlayer:因为Activity没重启,OnCreate只执行一次,播放组件应该在OnCreate里初始化好,切换布局时复用它,不然会导致歌曲从头播放。
  • 不要遗漏ConfigChanges.ScreenSize:API 13及以上的系统,屏幕旋转会触发屏幕尺寸变化,必须把这个加上,不然系统还是会重启Activity。
  • 测试时注意系统设置:有些手机的“自动旋转”开关要打开,不然不会触发方向变化。

额外优化(可选)

如果你的播放逻辑比较复杂,或者想让状态更稳定,可以用Android的ViewModel来保存播放状态和UI状态,这样即使系统因内存紧张回收了Activity,重新创建时也能恢复状态。不过针对你现在的屏幕旋转场景,上面的方法已经完全够用了。

内容的提问来源于stack exchange,提问作者Yousaf Haroon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:03:23