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

Android Kotlin:点击按钮实现Fragment间跳转的问题求助

解决Android Fragment跳转与点击事件的错误问题

我是移动应用开发新手,使用Android Studio Dolphin | 2021.3.1 Patch 1,用Kotlin开发应用。需要实现两个功能:

  • 点击fragment_delivery中ID为button_customer_sign的按钮,打开fragment_sign
  • 用户完成签名后,点击fragment_sign中ID为button_load_sign的按钮,返回fragment_delivery

当前代码存在导入错误、点击事件逻辑错误以及Fragment跳转逻辑错误,需要修正。


我的build.gradle依赖配置

dependencies {
    implementation 'androidx.core:core-ktx:1.9.0'
    implementation 'androidx.appcompat:appcompat:1.5.1'
    implementation 'com.google.android.material:material:1.7.0'
    implementation 'androidx.annotation:annotation:1.5.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.5.1'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
    implementation 'androidx.navigation:navigation-fragment-ktx:2.5.3'
    implementation 'androidx.navigation:navigation-ui-ktx:2.5.3'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    implementation 'com.kyanogen.signatureview:signature-view:1.2'

    implementation 'androidx.fragment:fragment-ktx:1.6.0-alpha03'
    implementation 'androidx.fragment:fragment:1.6.0-alpha03'
    debugImplementation 'androidx.fragment:fragment-testing:1.6.0-alpha03'

    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.4'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0'

    // google support library ---------------------------------------------------------------------
    implementation 'androidx.appcompat:appcompat:1.5.1'
    implementation 'com.google.android.material:material:1.7.0'
    implementation 'androidx.cardview:cardview:1.0.0'
    implementation 'androidx.recyclerview:recyclerview:1.2.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    implementation 'androidx.vectordrawable:vectordrawable:1.1.0'
    implementation 'androidx.browser:browser:1.4.0'
}

当前错误的DeliveryFragment.kt代码

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.example.delivery.R
import com.example.delivery.databinding.FragmentDeliveryBinding
import com.example.delivery.ui.sign.Sign

import android.support.v4.app.Fragment // 错误:旧support库导入,与androidx冲突
import android.support.v4.app.FragmentManager // 错误:同上
import android.support.v4.app.FragmentTransaction // 错误:同上

class DeliveryFragment : Fragment() {

    private var _binding: FragmentDeliveryBinding? = null
    private var customerSign: Button? = null

    // This property is only valid between onCreateView and
    // onDestroyView.
    private val binding get() = _binding!!

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        val deliveryViewModel =
            ViewModelProvider(this).get(DeliveryViewModel::class.java)

        _binding = FragmentDeliveryBinding.inflate(inflater, container, false)
        val root: View = binding.root

        val customer = resources.getStringArray(R.array.customer_list)
        val arrayAdapter = ArrayAdapter(requireContext(), R.layout.dropdown_item, customer)
        binding.autoCompleteTextView.setAdapter(arrayAdapter)
        return root
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContectView(com.example.delivery.R.layout.content_main) // 错误:Fragment没有setContentView方法
        customerSign = findViewById(com.example.delivery.R.id.button_customer_sign) as Button // 错误:onCreate阶段视图未初始化,findViewById会返回null
        customerSign.setOnClickListener(View.OnClickListener { openSignFragment() })
    } 

    fun openSignFragment() {
        val intent = Intent(this, SignFragment::class.java) // 错误:Intent用于Activity跳转,Fragment跳转不能用Intent
        startActivity(intent)
    } 

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}

修正步骤与完整代码

1. 修复导入错误

删除所有android.support.v4.app.*的导入,项目使用AndroidX库,对应的核心导入androidx.fragment.app.Fragment已经存在,无需额外导入FragmentManager和FragmentTransaction。

2. 修复点击事件逻辑

Fragment的视图初始化完成在onCreateView之后,应在onViewCreated方法中设置按钮点击监听,利用ViewBinding直接获取按钮实例,避免空指针。

3. 修复Fragment跳转逻辑

推荐使用已添加依赖的Navigation组件实现跳转(官方推荐方案),也可以用FragmentManager手动跳转,以下是两种方案:

方案一:使用Navigation组件跳转

修正后的DeliveryFragment.kt

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import com.example.delivery.R
import com.example.delivery.databinding.FragmentDeliveryBinding

class DeliveryFragment : Fragment() {

    private var _binding: FragmentDeliveryBinding? = null
    private val binding get() = _binding!!

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        val deliveryViewModel = ViewModelProvider(this).get(DeliveryViewModel::class.java)
        _binding = FragmentDeliveryBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        
        // 设置下拉列表
        val customer = resources.getStringArray(R.array.customer_list)
        val arrayAdapter = ArrayAdapter(requireContext(), R.layout.dropdown_item, customer)
        binding.autoCompleteTextView.setAdapter(arrayAdapter)
        
        // 设置签名按钮点击事件,跳转到SignFragment
        binding.buttonCustomerSign.setOnClickListener {
            // 替换R.id.action_deliveryFragment_to_signFragment为你导航图中对应的action ID
            findNavController().navigate(R.id.action_deliveryFragment_to_signFragment)
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}

SignFragment中返回按钮逻辑

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import com.example.delivery.databinding.FragmentSignBinding

class SignFragment : Fragment() {

    private var _binding: FragmentSignBinding? = null
    private val binding get() = _binding!!

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentSignBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        
        // 设置返回按钮点击事件
        binding.buttonLoadSign.setOnClickListener {
            // 返回上一个Fragment
            findNavController().popBackStack()
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}
方案二:使用FragmentManager手动跳转

修正后的DeliveryFragment.kt

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import androidx.fragment.app.Fragment
import androidx.fragment.app.commit
import androidx.lifecycle.ViewModelProvider
import com.example.delivery.R
import com.example.delivery.databinding.FragmentDeliveryBinding
import com.example.delivery.ui.sign.SignFragment

class DeliveryFragment : Fragment() {

    private var _binding: FragmentDeliveryBinding? = null
    private val binding get() = _binding!!

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        val deliveryViewModel = ViewModelProvider(this).get(DeliveryViewModel::class.java)
        _binding = FragmentDeliveryBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        
        // 设置下拉列表
        val customer = resources.getStringArray(R.array.customer_list)
        val arrayAdapter = ArrayAdapter(requireContext(), R.layout.dropdown_item, customer)
        binding.autoCompleteTextView.setAdapter(arrayAdapter)
        
        // 设置签名按钮点击事件,跳转到SignFragment
        binding.buttonCustomerSign.setOnClickListener {
            parentFragmentManager.commit {
                replace(R.id.fragment_container, SignFragment()) // 替换R.id.fragment_container为你的Fragment容器ID
                addToBackStack(null) // 添加到返回栈,支持返回
            }
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}

SignFragment中返回按钮逻辑

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.example.delivery.databinding.FragmentSignBinding

class SignFragment : Fragment() {

    private var _binding: FragmentSignBinding? = null
    private val binding get() = _binding!!

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentSignBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        
        // 设置返回按钮点击事件
        binding.buttonLoadSign.setOnClickListener {
            parentFragmentManager.popBackStack() // 从返回栈弹出,回到DeliveryFragment
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 19:25:28