[英]Unable to add OnClickListener to buttons in a Fragment
我對 Android 開發很陌生,所以請 go 對我輕松一點,但我在試圖弄清楚為什么我不能向片段中的任何按鈕添加事件偵聽器時遇到了死胡同。 我想要做的是我有一個片段,它將作為我的應用程序的一般登錄頁面,其中包含一系列用戶應該能夠單擊的按鈕,這些按鈕會將它們導航到應用程序的其他頁面。 所有的按鈕都在那里,但我無法讓它們做任何事情。 應該打印出當前按鈕的 id 的 println 語句確實有效,因此代碼正在進入 switch 案例,但 setOnClickListener 的行為與我預期的不同。 這是我目前正在處理的片段 class 的代碼(請注意,有一個右括號來結束 class 我只是由於某種原因無法在代碼樣式中得到它):
class HomeFragment : Fragment() {
private val buttonFragments = listOf("recipes", "budget", "inventory", "customers",
"reports")
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_home, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
for(button in buttonFragments) {
var currentHomeButton: View
when(button) {
"recipes" -> {
currentHomeButton = view.findViewById(R.id.button_recipes)
println(currentHomeButton.id)
currentHomeButton.setOnClickListener { println("Hello") }
}
}
}
}
這是我嘗試過的:
我希望這足以 go 關閉,但如果需要我可以分享更多。
更新在進行了更多探索之后,我想我更好地理解了為什么會出現我的問題,但仍然找不到解決方法。 HomeFragment 由我創建的一系列自定義按鈕組成,稱為 HomeButton。 HomeButton 由一個 MaterialButton 組成,並對其進行了一系列特定的樣式設置。 當我將 setOnClick 附加到材質按鈕的 id 時,它可以工作,但是當我嘗試將它附加到我的自定義組件時,它不會。
您正在使用標准 output ( println(...)
函數),它沒有在 Android 應用程序中使用。
意思是,你的點擊監聽器工作,但里面的代碼是無用的,除非你在你的開發機器上手動執行它(使用main
函數)。
了解如何 使用 LogCat 使用寫入日志
假設我們有一個名為 (TestFragment) 的片段
它的布局:fragment_testfragment.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".presintation.TestFragment">
<TextView
android:id="@+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="xxxxxxxxx"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.257" />
<Button
android:id="@+id/b1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="b1"
app:layout_constraintBottom_toTopOf="@+id/b2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/b2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="b2"
app:layout_constraintBottom_toTopOf="@+id/b3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/b3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="b3"
app:layout_constraintBottom_toTopOf="@+id/b4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/b4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="228dp"
android:text="b4"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.501"
app:layout_constraintStart_toStartOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
初始化 4 個按鈕 (b1,b2,b3,b4) 並使用單擊按鈕的名稱更改文本片段 class 中的代碼:
測試片段.kt:
package com.mostafan3ma.android.hilttesting.presintation
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import com.mostafan3ma.android.hilttesting.R
import kotlin.math.log
class TestFragment : Fragment() {
private val TAG = "TestFragment"
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_testfragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.findViewById<Button>(R.id.b1).setOnClickListener {
Log.d(TAG, "onViewCreated: b1 clicked")
Toast.makeText(context, "b1 clicked", Toast.LENGTH_SHORT).show()
view.findViewById<TextView>(R.id.txt).text = "b1"
}
view.findViewById<Button>(R.id.b2).setOnClickListener {
Log.d(TAG, "onViewCreated: b2 clicked")
Toast.makeText(context, "b2 clicked", Toast.LENGTH_SHORT).show()
view.findViewById<TextView>(R.id.txt).text = "b2"
}
view.findViewById<Button>(R.id.b3).setOnClickListener {
Log.d(TAG, "onViewCreated: b3 clicked")
Toast.makeText(context, "b3 clicked", Toast.LENGTH_SHORT).show()
view.findViewById<TextView>(R.id.txt).text = "b3"
}
view.findViewById<Button>(R.id.b4).setOnClickListener {
Log.d(TAG, "onViewCreated: b4 clicked")
Toast.makeText(context, "b4 clicked", Toast.LENGTH_SHORT).show()
view.findViewById<TextView>(R.id.txt).text = "b4"
}
}
}
因此,經過大量研究並嘗試了不同的解決方案,我已經弄清楚了問題所在並解決了問題。 問題是我試圖在我制作的自定義視圖組件上附加一個 setOnClickListener 。 因此,setOnClickListener 沒有附加任何內容(或至少沒有任何有用的內容),因為 function 不知道如何使用自定義視圖組件。 為了解決這個問題,我在 HomeButton.kt 自定義視圖文件中實現了以下代碼:
private var listener: OnClickListener? = null
override fun dispatchTouchEvent(event: MotionEvent): Boolean {
if (event.action == MotionEvent.ACTION_UP) {
if (listener != null) listener!!.onClick(this)
}
return super.dispatchTouchEvent(event)
}
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
if (event.action == KeyEvent.ACTION_UP &&
(event.keyCode == KeyEvent.KEYCODE_DPAD_CENTER ||
event.keyCode == KeyEvent.KEYCODE_ENTER)) {
if (listener != null) listener!!.onClick(this)
}
return super.dispatchKeyEvent(event)
}
override fun setOnClickListener(listener: OnClickListener?) {
this.listener = listener
}
這允許在 HomeButton 自定義視圖組件上使用 setOnClickListener。 然后回到 HomeFragment.kt 片段文件,這是我實現的代碼,它沒有任何問題:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
for(button in buttonFragments) {
var currentHomeButton: HomeButton
when(button) {
"recipes" -> {
currentHomeButton = view.findViewById(R.id.button_recipes)
currentHomeButton.setOnClickListener { utils.replaceFragment(
RecipesListFragment(), currentHomeButton.getText()) }
}
"budget" -> {
currentHomeButton = view.findViewById(R.id.button_budget)
currentHomeButton.setOnClickListener { utils.replaceFragment(
BudgetListFragment(), currentHomeButton.getText()) }
}
...
}
}
希望這可以幫助將來的人
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.