为片段内的按钮创建一个函数



我制作了一个有4个片段的应用程序,每个片段代表应用程序页面。现在,在其中一个片段中,我有一个ToggleButton。我试图得到OnClickListener,使它改变按钮的背景颜色一旦点击。我在MainActivity中编写这个。kt而不是碎片。但是,如果没有logcat,它会使应用程序崩溃。

package com.example.myassignment
import android.graphics.Color
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.example.myassignment.Fragments.DestinationsFragment
import com.example.myassignment.Fragments.HelpFragment
import com.example.myassignment.Fragments.HomeFragment
import com.example.myassignment.Fragments.SettingsFragment
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.fragment_settings.*

class MainActivity : AppCompatActivity() {
private val helpFragment = HelpFragment()
private val settingsFragment = SettingsFragment()
private val homeFragment = HomeFragment()
private val destinationsFragment = DestinationsFragment()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
replaceFragment(homeFragment)
bottom_navigation.setOnNavigationItemSelectedListener{
when(it.itemId){
R.id.ic_home -> replaceFragment(homeFragment)
R.id.ic_destinations -> replaceFragment((destinationsFragment))
R.id.ic_help -> replaceFragment(helpFragment)
R.id.ic_settings -> replaceFragment(settingsFragment)
}

true
}
// This is the onclick for the button which is inside a fragment (SettingsFragment)
btnReset.setOnClickListener { resetColour() }
}
// Function for the onclick function
private fun resetColour() {
btnReset.setBackgroundColor(Color.parseColor("#3E3E3E"))
}
private fun replaceFragment(fragment: Fragment){
if (fragment !=null){
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.fragment_container, fragment)
transaction.commit()
}
}
}

这里是我的SettingsFragment代码(我没有改变任何)

package com.example.myassignment.Fragments
import android.graphics.Color
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.myassignment.R
import kotlinx.android.synthetic.main.fragment_settings.*
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
/**
* A simple [Fragment] subclass.
* Use the [SettingsFragment.newInstance] factory method to
* create an instance of this fragment.
*/
class SettingsFragment : Fragment() {
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_settings, container, false)
}
companion object {
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment SettingsFragment.
*/
// TODO: Rename and change types and number of parameters
@JvmStatic
fun newInstance(param1: String, param2: String) =
SettingsFragment().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
}

这是片段的XML,我想改变的按钮是btnReset

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".Fragments.SettingsFragment"
android:background="@color/black">

<TextView
android:id="@+id/txtSettings"
android:layout_width="323dp"
android:layout_height="102dp"
android:layout_marginTop="16dp"
android:background="@color/orange"
android:gravity="center"
android:text="Settings"
android:textAlignment="center"
android:textColor="@color/black"
android:textSize="60sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/txtNotifications"
android:layout_width="223dp"
android:layout_height="48dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="12dp"
android:layout_marginRight="12dp"
android:background="@color/grey"
android:gravity="center"
android:text="Notifications"
android:textAlignment="center"
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintEnd_toStartOf="@+id/btnNotifications"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtSettings" />
<TextView
android:id="@+id/txtNightMode"
android:layout_width="223dp"
android:layout_height="48dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="12dp"
android:layout_marginRight="12dp"
android:background="@color/grey"
android:gravity="center"
android:text="Night Mode"
android:textAlignment="center"
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintEnd_toStartOf="@+id/btnNightMode"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtNotifications" />
<TextView
android:id="@+id/txtWIFI"
android:layout_width="223dp"
android:layout_height="48dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="12dp"
android:layout_marginRight="12dp"
android:background="@color/grey"
android:gravity="center"
android:text="WI-FI Only"
android:textAlignment="center"
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintEnd_toStartOf="@+id/btnWIFI"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtNightMode" />
<ToggleButton
android:id="@+id/btnNotifications"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginEnd="44dp"
android:layout_marginRight="44dp"
android:text="ToggleButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtSettings"
android:background="@color/cyan"
/>
<ToggleButton
android:id="@+id/btnNightMode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginEnd="44dp"
android:layout_marginRight="44dp"
android:checked="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnNotifications"
android:background="@color/cyan"
/>
<ToggleButton
android:id="@+id/btnWIFI"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginEnd="44dp"
android:layout_marginRight="44dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnNightMode"
android:background="@color/cyan"/>
<Button
android:id="@+id/btnReset"
android:layout_width="337dp"
android:layout_height="154dp"
android:layout_marginTop="24dp"
android:text="Reset"
android:background="@color/cyan"
android:backgroundTint="@color/orange"
android:textColor="@color/black"
android:textSize="50sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtWIFI" />

</androidx.constraintlayout.widget.ConstraintLayout>

-----编辑-----

新增SettingsFragment代码:

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
btnReset.setOnClickListener { resetColour() }
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_settings, container, false)
}
private fun resetColour() {
btnReset.setBackgroundColor(Color.parseColor("3E3E3E"))
}

这是logcat

2021-02-17 08:20:32.594 11717-11717/com.example.myassignment E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.myassignment, PID: 11717
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at com.example.myassignment.Fragments.SettingsFragment.onCreateView(SettingsFragment.kt:40)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2600)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl$2.run(FragmentManagerImpl.java:150)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

这一行是你的问题。

btnReset.setOnClickListener { resetColour() }

btnReset存在于您的片段中,但您正试图从您的活动中引用它。尝试将该代码移动到扩展btnReset所在视图的片段中。

在你的活动课上看到import kotlinx.android.synthetic.main.fragment_settings.*了吗?这是什么使它看起来像btnReset是一个有效的属性,在您的活动中引用。你应该删掉那一行。

最后,它不太可能"没有logcat就崩溃了"。您可能在logcat上设置了某种过滤器,以防止您看到崩溃。

最新更新