最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android開發(fā)教程之屏幕變更事件

 更新時(shí)間:2025年09月28日 10:26:28   作者:咖啡の貓  
Android屏幕變更事件(如旋轉(zhuǎn)、尺寸調(diào)整)會(huì)觸發(fā)Activity重建,導(dǎo)致狀態(tài)丟失和性能問(wèn)題,這篇文章主要介紹了Android開發(fā)教程之屏幕變更事件的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下

一、什么是屏幕變更事件?

當(dāng)設(shè)備的配置(Configuration) 發(fā)生變化時(shí),Android 系統(tǒng)會(huì)觸發(fā) Configuration Change 事件。

常見的配置變更類型

變更類型示例
orientation屏幕旋轉(zhuǎn)(豎屏 ↔ 橫屏)
screenLayout屏幕尺寸/密度變化(如折疊屏展開)
keyboardHidden軟鍵盤彈出/隱藏
fontScale系統(tǒng)字體大小調(diào)整
locale系統(tǒng)語(yǔ)言切換
uiMode夜間模式開啟/關(guān)閉

?? 默認(rèn)行為:系統(tǒng)會(huì)銷毀并重建 Activity(調(diào)用 onDestroy() → onCreate()),以便加載適配新配置的資源。

二、默認(rèn)行為:Activity 重建

生命周期流程

Activity A (豎屏)
    ↓ 用戶旋轉(zhuǎn)屏幕
onPause() → onStop() → onDestroy()
    ↓ 系統(tǒng)重建
onCreate() → onStart() → onResume()
    → Activity A (橫屏)

問(wèn)題與挑戰(zhàn)

  • 狀態(tài)丟失onCreate() 中初始化的數(shù)據(jù)可能丟失。
  • 性能損耗:重復(fù)執(zhí)行 setContentView()、數(shù)據(jù)庫(kù)查詢、網(wǎng)絡(luò)請(qǐng)求。
  • 用戶體驗(yàn)差:頁(yè)面閃退或重新加載。

三、方案一:允許重建 + 正確保存狀態(tài)

如果選擇接受默認(rèn)重建行為,必須確保關(guān)鍵數(shù)據(jù)不丟失。

1. 使用 onSaveInstanceState() 保存臨時(shí)狀態(tài)

public class MainActivity extends AppCompatActivity {
    private String userInput;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        EditText editText = findViewById(R.id.edit_text);
        
        // 恢復(fù)保存的狀態(tài)
        if (savedInstanceState != null) {
            userInput = savedInstanceState.getString("USER_INPUT");
            editText.setText(userInput);
        }
    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        // 保存用戶輸入
        EditText editText = findViewById(R.id.edit_text);
        outState.putString("USER_INPUT", editText.getText().toString());
    }
}

適用場(chǎng)景:輕量級(jí)狀態(tài)(如文本框內(nèi)容、滾動(dòng)位置)。
不適用:大數(shù)據(jù)、文件句柄、網(wǎng)絡(luò)連接。

2. 使用 ViewModel 保留復(fù)雜數(shù)據(jù)

public class MainViewModel extends ViewModel {
    private MutableLiveData<List<String>> dataList = new MutableLiveData<>();

    public LiveData<List<String>> getDataList() {
        return dataList;
    }

    public void loadData() {
        // 模擬耗時(shí)加載
        new Handler().postDelayed(() -> {
            List<String> data = Arrays.asList("Item 1", "Item 2", "Item 3");
            dataList.setValue(data);
        }, 2000);
    }
}
// 在 Activity 中使用
viewModel = new ViewModelProvider(this).get(MainViewModel.class);
viewModel.getDataList().observe(this, list -> {
    // 更新 UI,即使 Activity 重建,數(shù)據(jù)依然存在
    adapter.submitList(list);
});

優(yōu)勢(shì):生命周期獨(dú)立于 Activity,配置變更時(shí)不銷毀。

四、方案二:阻止重建 + 手動(dòng)處理變更

通過(guò)在 AndroidManifest.xml 中聲明 android:configChanges,可阻止系統(tǒng)自動(dòng)重建 Activity。

1. 聲明要自行處理的配置變更

<activity
    android:name=".MainActivity"
    android:exported="true"
    android:configChanges="orientation|screenSize|keyboardHidden"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

?? 關(guān)鍵屬性說(shuō)明

  • orientation:屏幕方向變更(橫/豎屏)
  • screenSize:屏幕尺寸變化(API 13+,常與 orientation 同時(shí)使用)
  • keyboardHidden:軟鍵盤顯示/隱藏

2. 重寫 onConfigurationChanged() 方法

@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // 判斷當(dāng)前屏幕方向
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "已切換到橫屏", Toast.LENGTH_SHORT).show();
        // 動(dòng)態(tài)調(diào)整 UI
        adjustForLandscape();
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        Toast.makeText(this, "已切換到豎屏", Toast.LENGTH_SHORT).show();
        adjustForPortrait();
    }
}

3. 動(dòng)態(tài)調(diào)整 UI 示例

private void adjustForLandscape() {
    // 橫屏下隱藏某些 View
    findViewById(R.id.ad_banner).setVisibility(View.GONE);
    
    // 調(diào)整 RecyclerView 布局管理器
    RecyclerView recyclerView = findViewById(R.id.recycler_view);
    recyclerView.setLayoutManager(new GridLayoutManager(this, 2));
}

private void adjustForPortrait() {
    // 豎屏下顯示廣告
    findViewById(R.id.ad_banner).setVisibility(View.VISIBLE);
    
    // 恢復(fù)線性布局
    RecyclerView recyclerView = findViewById(R.id.recycler_view);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
}

優(yōu)點(diǎn):避免 Activity 重建,提升性能。
缺點(diǎn):需手動(dòng)處理所有 UI 變化,代碼復(fù)雜度增加。

五、為不同屏幕提供專屬布局

最優(yōu)雅的適配方式是使用 資源限定符(Resource Qualifiers),讓系統(tǒng)自動(dòng)加載合適的布局。

1. 創(chuàng)建橫屏專用布局

res/
├── layout/
│   └── activity_main.xml          # 豎屏布局
└── layout-land/
    └── activity_main.xml          # 橫屏布局

2. 橫屏布局示例(layout-land/activity_main.xml)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <!-- 左側(cè)列表 -->
    <fragment
        android:id="@+id/fragment_list"
        android:name="com.example.NewsListFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />

    <!-- 右側(cè)詳情 -->
    <FrameLayout
        android:id="@+id/detail_container"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="2" />

</LinearLayout>

優(yōu)勢(shì):完全解耦,UI 設(shè)計(jì)自由度高,適合平板或大屏設(shè)備。

六、高級(jí)技巧與最佳實(shí)踐

1. 監(jiān)聽軟鍵盤彈出/隱藏

// 在 onConfigurationChanged 中判斷
if (newConfig.keyboardHidden == Configuration.KEYBOARDHIDDEN_NO) {
    // 軟鍵盤彈出
} else if (newConfig.keyboardHidden == Configuration.KEYBOARDHIDDEN_YES) {
    // 軟鍵盤隱藏
}

2. 折疊屏與多窗口支持

<!-- 支持多窗口 -->
<activity
    android:name=".MainActivity"
    android:resizeableActivity="true"
    android:supportsPictureInPicture="true"
    android:configChanges="orientation|screenSize|smallestScreenSize">
</activity>

3. 使用 Jetpack Compose 實(shí)現(xiàn)響應(yīng)式 UI

@Composable
fun ResponsiveLayout() {
    val configuration = LocalConfiguration.current
    val isLandscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE

    if (isLandscape) {
        Row { /* 橫屏布局 */ }
    } else {
        Column { /* 豎屏布局 */ }
    }
}

七、常見問(wèn)題與避坑指南

  • android:configChanges 不生效?確保同時(shí)聲明 orientation 和 screenSize(API 13+)。

  • 橫屏布局未加載?檢查文件夾命名是否正確(layout-land),且無(wú)拼寫錯(cuò)誤。

  • ViewModel 數(shù)據(jù)在重建后丟失?確保使用 ViewModelProvider(this) 而非 ViewModelProvider(requireActivity())。

  • 動(dòng)畫在旋轉(zhuǎn)后中斷?將動(dòng)畫邏輯放在 ViewModel 或使用 onRetainNonConfigurationInstance()。

八、結(jié)語(yǔ)

到此這篇關(guān)于Android開發(fā)教程之屏幕變更事件的文章就介紹到這了,更多相關(guān)Android屏幕變更事件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 如何使用Flutter實(shí)現(xiàn)生成二維碼

    如何使用Flutter實(shí)現(xiàn)生成二維碼

    這篇文章主要為大家詳細(xì)介紹了如何使用 Flutter 創(chuàng)建二維碼,并實(shí)現(xiàn)一些常見的自定義選項(xiàng),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-11-11
  • Android開發(fā)之permission動(dòng)態(tài)權(quán)限獲取詳解

    Android開發(fā)之permission動(dòng)態(tài)權(quán)限獲取詳解

    這篇文章主要為大家詳細(xì)介紹了Android開發(fā)之permission動(dòng)態(tài)權(quán)限獲取,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • Listview加載的性能優(yōu)化是如何實(shí)現(xiàn)的

    Listview加載的性能優(yōu)化是如何實(shí)現(xiàn)的

    在android開發(fā)中Listview是一個(gè)很重要的組件,它以列表的形式根據(jù)數(shù)據(jù)的長(zhǎng)自適應(yīng)展示具體內(nèi)容,用戶可以自由的定義listview每一列的布局,接下來(lái)通過(guò)本文給大家介紹Listview加載的性能優(yōu)化是如何實(shí)現(xiàn)的,對(duì)listview性能優(yōu)化相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧
    2016-01-01
  • Android?WebView基礎(chǔ)舉例詳解

    Android?WebView基礎(chǔ)舉例詳解

    在Android開發(fā)中Webview是一個(gè)重要的組件,它允許我們?cè)谠鷳?yīng)用中內(nèi)嵌網(wǎng)頁(yè)內(nèi)容,提供混合式應(yīng)用的用戶體驗(yàn),這篇文章主要給大家介紹了關(guān)于Android?WebView基礎(chǔ)的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-07-07
  • Android 代碼寫控件代替XML簡(jiǎn)單實(shí)例

    Android 代碼寫控件代替XML簡(jiǎn)單實(shí)例

    這篇文章主要介紹了Android 代碼寫控件代替XML簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • Kotlin編程基礎(chǔ)數(shù)據(jù)類型示例詳解

    Kotlin編程基礎(chǔ)數(shù)據(jù)類型示例詳解

    這篇文章主要為大家介紹了Kotlin編程基礎(chǔ)數(shù)據(jù)類型示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Android自定義控件簡(jiǎn)單實(shí)現(xiàn)側(cè)滑菜單效果

    Android自定義控件簡(jiǎn)單實(shí)現(xiàn)側(cè)滑菜單效果

    這篇文章主要為大家詳細(xì)介紹了Android自定義控件打造史上最簡(jiǎn)單的側(cè)滑菜單的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-06-06
  • Android中利用Xposed框架實(shí)現(xiàn)攔截系統(tǒng)方法

    Android中利用Xposed框架實(shí)現(xiàn)攔截系統(tǒng)方法

    這篇文章主要介紹了Android中利用Xposed框架實(shí)現(xiàn)攔截系統(tǒng)方法的相關(guān)資料,需要的朋友可以參考下
    2016-11-11
  • Android學(xué)習(xí)之AppWidget筆記分享

    Android學(xué)習(xí)之AppWidget筆記分享

    這篇文章主要為大家詳細(xì)介紹了Android學(xué)習(xí)筆記之AppWidget的相關(guān)資料,感興趣的小伙伴們可以參考一下
    2016-08-08
  • 深入理解Android中View繪制的三大流程

    深入理解Android中View繪制的三大流程

    這篇文章主要給大家介紹了關(guān)于Android中View繪制的三大流程,View的工作流程主要是指measure、layout、draw這三大流程,即測(cè)量、布局和繪制,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。
    2017-07-07

最新評(píng)論

台江县| 读书| 麻城市| 望江县| 黔南| 广东省| 常熟市| 蒲江县| 昔阳县| 冕宁县| 松阳县| 济阳县| 祁连县| 龙海市| 沿河| 济源市| 巴中市| 宁河县| 梁山县| 油尖旺区| 修武县| 苍梧县| 广水市| 合川市| 元朗区| 林甸县| 东丰县| 丹阳市| 澳门| 郴州市| 台江县| 漳州市| 富民县| 庆城县| 育儿| 迭部县| 扬州市| 南宁市| 信丰县| 彰武县| 隆德县|