【问题标题】:How to change activity title when switching between tabs in Kotlin?在 Kotlin 中的选项卡之间切换时如何更改活动标题?
【发布时间】:2018-10-31 21:22:28
【问题描述】:

Java 语言中有很多关于这个问题的答案,但我不能应用它 使用 Kotlin。

我使用 ViewPager 在选项卡之间切换,我希望每次滑动时都更改 MainActivity 标题。

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        setSupportActionBar(toolbar)

        container.adapter = TabPagerAdapter(supportFragmentManager)    
        container.addOnPageChangeListener(TabLayout.TabLayoutOnPageChangeListener(tabs))
    tabs.addOnTabSelectedListener(TabLayout.ViewPagerOnTabSelectedListener(container))
    }

    override fun setTitle(title: CharSequence?) {
        supportActionBar?.title = title
    }
}

我使用“kotlin-android-extensions”,所以容器是 ViewPager 的 id,标签是 TabLayout 的 id。我还创建了扩展 FragmentPagerAdapter 的类 TabPagerAdapter。它使用 getItem 方法返回正确的选项卡,即 Fragment 衍生物。我试图通过覆盖 getPageTitle 方法来实现我的目标,但它不起作用。

class TabPagerAdapter(fragmentManager: FragmentManager) : 
FragmentPagerAdapter(fragmentManager) {

    override fun getItem(p0: Int): Fragment {
        return when (p0) {
            else -> TestTab.newInstance()
            }
    }

    override fun getPageTitle(position: Int): CharSequence? {
        return "test title"
    }

    override fun getCount(): Int {
        return 1
    }
}

我的标签示例:

class NotificationsTab : Fragment() {
    private val _title = "Notifications"

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_notifications, container, false)
    }

    companion object {
        fun newInstance(): NotificationsTab {
            return NotificationsTab()
        }
    }
}

我希望变量 _title 成为 MainActivity 标题。
我使用的 XML:
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/main_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:context="com.androidtest.activities.MainActivity"
        android:orientation="vertical">

    <android.support.design.widget.AppBarLayout
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="63"
            app:elevation="0dp">

        <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="50"
                android:background="#ffffff"
                app:layout_scrollFlags="scroll|enterAlways"
                app:title="@string/app_name">

        </android.support.v7.widget.Toolbar>

        <android.support.design.widget.TabLayout
                android:id="@+id/tabs"
                android:background="#ffffff"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="50"
                app:tabIndicatorColor="@color/tabIndicatorColor"
                app:tabIndicatorHeight="3dp">

            <android.support.design.widget.TabItem
                    android:id="@+id/tab_profile"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="1"/>

            <android.support.design.widget.TabItem
                    android:id="@+id/tab_notifications"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="2"/>

        </android.support.design.widget.TabLayout>
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
            android:id="@+id/container"
            android:layout_weight="390"
            android:background="#ffffff"
            android:layout_width="match_parent"
            android:layout_height="0dp"/>

</LinearLayout>

fragment_notifications.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <TextView
            android:layout_width="wrap_content"
            android:text="notifications"
            android:layout_gravity="center"
            android:textAlignment="center"
            android:textSize="56sp"
            android:layout_height="wrap_content"/>
</LinearLayout>

【问题讨论】:

    标签: android kotlin


    【解决方案1】:

    据我了解,当用户在选项卡之间滑动时,您会将选项卡的文本设置为活动的标题。这是一个解决方案

    首先从activity_main.xml 布局文件中删除所有TabItem 标记,因为您将TabLayout 与ViewPager 一起使用。 ViewPager 将处理如何设置选项卡(选项卡数量、每个选项卡的片段、每个选项卡的标题等)。

    <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:background="#ffffff"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="50"
            app:tabIndicatorHeight="3dp">
    
        <!--<android.support.design.widget.TabItem-->
                <!--android:id="@+id/tab_profile"-->
                <!--android:layout_width="wrap_content"-->
                <!--android:layout_height="wrap_content"-->
                <!--android:text="1"/>-->
    
        <!--<android.support.design.widget.TabItem-->
                <!--android:id="@+id/tab_notifications"-->
                <!--android:layout_width="wrap_content"-->
                <!--android:layout_height="wrap_content"-->
                <!--android:text="2"/>-->
    
    </android.support.design.widget.TabLayout>
    

    然后在MainActivity修改你的代码

    container.adapter = TabPagerAdapter(supportFragmentManager)
    // Comment-out or remove these lines
    // container.addOnPageChangeListener(TabLayout.TabLayoutOnPageChangeListener(tabs))
    // tabs.addOnTabSelectedListener(TabLayout.ViewPagerOnTabSelectedListener(container))
    
    // Pass viewpager to tablayout to setup tabs.
    tabs.setupWithViewPager(container)
    
    // Handle event when users swipe to a tab, here we set tab's text as title of the activity.
    tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
        override fun onTabSelected(tab: TabLayout.Tab) {
            title = tab.text // the value of tab's text is the returned value from `getPageTitle` method in TabPagerAdapter class.
        }
    
        override fun onTabUnselected(tab: TabLayout.Tab?) {
        }
    
        override fun onTabReselected(tab: TabLayout.Tab?) {
        }
    })
    
    // For the first time open the app, we set first tab's title as title of this activity
    title = container.adapter!!.getPageTitle(0)
    

    【讨论】:

    • 如果我的解释不清楚,我很抱歉,我尽力做到最好。我添加了我的选项卡类的示例。我希望我的问题现在可以理解了。
    • 您的解决方案不起作用。我按照你的建议做了一切。这可能是什么原因?你不觉得在getPageTitle中when之前应该有return吗?
    • 是的,我想念return 关键字。因为您的代码不完整,所以我无法重现该问题。我只是告诉你如何做到这一点。
    • 我复制了除 xml 之外的所有内容。我注意到 TabPagerAdapter 中的 getPageTitle 方法对我根本不起作用。省略片段,即使我让这个方法总是返回一个字符串,它也不会改变 MainActivity 的标题。
    • 好的,你能取悦你的 xml 布局文件吗?我会重现并找出根本原因。
    【解决方案2】:
    viewPagerAtmosphericInfo.addOnPageChangeListener(object: ViewPager.OnPageChangeListener{
    override fun onPageScrollStateChanged(state: Int) {
    
    }
    
    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
    
    }
    
    override fun onPageSelected(position: Int) {
       // code here
    })
    

    【讨论】:

    • viewPagerAtmosphericInfo 这是什么
    • @TimCastelijns 这是 Viewpager
    • 我不明白这对我有什么帮助。
    【解决方案3】:

    如果你想用标签设置活动的标题,你必须设置活动的标题,你可以使用活动实例从片段中设置。

    例子:

    //initialize activity instance
    lateinit var mActivity: AppCompatActivity
    
    //get activity inside your onViewCreated of fragment
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    
        mActivity = activity as MainActivity
    
    }
    
    // inside your fragment
    override fun setUserVisibleHint(isVisibleToUser: Boolean) {
        super.setUserVisibleHint(isVisibleToUser)
        if(isVisibleToUser){
            //change your title from here, make sure that activity is not null
            mActivity.supportActionBar?.title = "Your Title"
        }
    }
    

    如果您有任何疑问,请立即联系我! :)

    【讨论】:

    • 您的解决方案对我不起作用,当我在选项卡之间切换时,活动标题的变化不一致。有时会出现属于下一个标签的标题。
    • 你必须在片段的可见性上设置标题
    • 这是什么意思?你能解释一下吗?
    • 在片段中,您可以获得片段的可见性,因此检查片段是否可见然后只设置标题
    • 我在 onViewCreated 方法中创建了if 语句,用于检查片段是否可见,现在它始终显示下一个选项卡的标题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多