kotlin - 2个Activity实现平行视图,使用SplitPairFilter

一、创建API33的平板模拟器才支持
二、这是代码实现,也可以使用xml实现,参考官网(连接VPN):
    1、(底部使用 activity 嵌入和 Material Design 构建列表-详情布局)https://developer.android.com/develop/ui/views/layout/activity-embedding?hl=zh-cn
    2、(demo)https://developer.android.com/codelabs/large-screens/activity-embedding?hl=zh-cn#4

导入:
    implementation 'androidx.window:window:1.2.0'
    implementation 'androidx.startup:startup-runtime:1.2.0'    
    
AndroidManifest.xml添加:
                <property
       android:name="android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED"
            android:value="true" />

        <provider android:name="androidx.startup.InitializationProvider"
            android:authorities="${applicationId}.androidx-startup"
            android:exported="false">
            <!-- SplitInitializer的文件下的包名和applicationId配置不一样了. -->
            <meta-data android:name="com.example.androidkotlindemo2.pad.parallet2.SplitInitializer"
                android:value="androidx.startup" />
        </provider>

使用打开:

startActivity(Intent(this, ParalletListActivity::class.java))

package com.example.androidkotlindemo2.pad.parallet
import android.content.Intent
import android.os.Bundle
import android.widget.ArrayAdapter
import android.widget.ListView
import androidx.appcompat.app.AppCompatActivity
import com.example.androidkotlindemo2.R

/**
 * Author : wn
 * Email : maoning20080809@163.com
 * Date : 2025/8/31 14:21
 * Description :
 */
class ParalletListActivity : AppCompatActivity() {
    private lateinit var listView: ListView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.parallet_activity_list)

        // 初始化分屏管理器
        ParalletSplitManager.create(this)

        listView = findViewById(R.id.listView)

        val items = mutableListOf<String>()
        for(i in 0..20){
            items.add("Item ${i}")
        }
        val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, items)
        listView.adapter = adapter

        listView.setOnItemClickListener { _, _, position, _ ->
            val intent = Intent(this, ParalletDetailActivity::class.java).apply {
                putExtra("ITEM_ID", position)
            }
            startActivity(intent)
        }
    }
}

package com.example.androidkotlindemo2.pad.parallet

import android.content.ComponentName
import android.content.Context
import android.content.Intent
import androidx.window.embedding.*

/**
 * Author : wn
 * Email : maoning20080809@163.com
 * Date : 2025/8/31 14:10
 * Description :
 */
//在Application#onCreate方法中调用
class ParalletSplitManager {
    companion object {
        fun create(context: Context) {
            //创建一个分屏对过滤器,将 ListActivity 和 DetailActivity 标识为共享分屏的 activity
            val splitPairFilter = SplitPairFilter(
                ComponentName(context, ParalletListActivity::class.java),
                ComponentName(context, ParalletDetailActivity::class.java),
                null
            )
            //将过滤条件添加到过滤条件集
            val filterSet = setOf(splitPairFilter)
            //为分屏创建布局属性
            val splitAttributes = SplitAttributes.Builder().apply {
                setSplitType(SplitAttributes.SplitType.ratio(0.20f))
                setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT)
            }.build()
            //构建分屏对规则
            val splitPairRule = SplitPairRule.Builder(filterSet).apply {
                setDefaultSplitAttributes(splitAttributes)
                setMaxAspectRatioInPortrait(EmbeddingAspectRatio.ratio(1.5f))
                setMinWidthDp(540)
                setMinSmallestWidthDp(460)
                // 主Activity随副Activity一起finish
                setFinishPrimaryWithSecondary(SplitRule.FinishBehavior.ALWAYS)
                // 副Activity随主Activity一起finish
                setFinishSecondaryWithPrimary(SplitRule.FinishBehavior.ALWAYS)
                setClearTop(true)
            }.build()
            //获取 WindowManager RuleController 的单例实例并添加规则
            val ruleController = RuleController.getInstance(context)
            ruleController.addRule(splitPairRule)

            //创建占位规则
            val placeholderActivityFilter = ActivityFilter(
                ComponentName(context, ParalletListActivity::class.java),
                null
            )
            val placeholderActivityFilterSet = setOf(placeholderActivityFilter)
            val splitPlaceholderRule = SplitPlaceholderRule.Builder(
                placeholderActivityFilterSet,
                Intent(context, ParalletPlaceholderActivity::class.java)
            ).apply {
                setDefaultSplitAttributes(splitAttributes)
                setMaxAspectRatioInPortrait(EmbeddingAspectRatio.ratio(1.5f))
                setMinWidthDp(540)
                setMinSmallestWidthDp(460)
                setFinishPrimaryWithPlaceholder(SplitRule.FinishBehavior.ALWAYS)
            }.build()
            ruleController.addRule(splitPlaceholderRule)

            //创建拒绝分屏activity规则
            val summaryActivityFilter = ActivityFilter(
                ComponentName(context, ParalletSummaryActivity::class.java),
                null
            )
            val summaryActivityFilterSet = setOf(summaryActivityFilter)
            val activityRule =
                ActivityRule.Builder(summaryActivityFilterSet).setAlwaysExpand(true).build()
            ruleController.addRule(activityRule)
        }
    }
}

package com.example.androidkotlindemo2.pad.parallet

import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.example.androidkotlindemo2.R

/**
 * Author : wn
 * Email : maoning20080809@163.com
 * Date : 2025/8/31 14:22
 * Description :
 */
class ParalletDetailActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.parallet_activity_detail)

        val itemId = intent.getIntExtra("ITEM_ID", 0)
        val textView = findViewById<TextView>(R.id.textView)
        textView.text = "Details for Item $itemId"
    }
}

package com.example.androidkotlindemo2.pad.parallet

import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.example.androidkotlindemo2.R

/**
 * Author : wn
 * Email : maoning20080809@163.com
 * Date : 2025/8/31 14:22
 * Description :
 */
class ParalletPlaceholderActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.parallet_activity_placeholder)

        val textView = findViewById<TextView>(R.id.textView)
        textView.text = "Placeholder Activity"
    }
}

package com.example.androidkotlindemo2.pad.parallet

import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.example.androidkotlindemo2.R

/**
 * Author : wn
 * Email : maoning20080809@163.com
 * Date : 2025/8/31 14:23
 * Description :
 */
class ParalletSummaryActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.parallet_activity_summary)

        val textView = findViewById<TextView>(R.id.textView)
        textView.text = "Summary Activity - Always Expanded"
    }
}

parallet_activity_list.xml布局:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="horizontal">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/parallet_list_divide"/>

    <TextView
        android:id="@+id/parallet_list_divide"
        android:layout_width="6dp"
        android:layout_height="match_parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:background="@color/blue"/>
</androidx.constraintlayout.widget.ConstraintLayout>

parallet_activity_detail.xml布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/red"
        android:textSize="30sp" />

</LinearLayout>
parallet_activity_placeholder.xml布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:background="#E0E0E0">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="24sp" />

</LinearLayout>

parallet_activity_summary.xml布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:background="#FFF9C4">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="24sp" />

</LinearLayout>

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐