简体   繁体   English

getView 中的 Kotlin Android onClickListener 仅适用于边缘

[英]Kotlin Android onClickListener in getView only works on edge

I'm new to Kotlin and Android development in general.我是 Kotlin 和 Android 开发的新手。 I have created a custom adapter that extends BaseAdapter and it works as I want it to, but as soon as I was to add a click listener to the view that gets returned in the getView, it doesn't seem to work as expected.我创建了一个扩展 BaseAdapter 的自定义适配器,它可以按我的意愿工作,但是一旦我向在 getView 中返回的视图添加一个单击侦听器,它似乎并没有按预期工作。

I have looked everywhere for an answer.我到处寻找答案。 I have seen people talking about clickable, duplicateParentState, focusable,... But nothing seems to work我见过人们谈论可点击、重复父状态、可聚焦……但似乎没有任何效果

The click listener does react if I click on the left/right border of my layout RelativeLayout, but I want the entire RelativeLayout to react when I click.如果我单击布局 RelativeLayout 的左/右边框,则单击侦听器确实会做出反应,但是我希望在单击时整个 RelativeLayout 做出反应。

Am I missing something in my XML?我的 XML 中是否缺少某些内容? Or is there some kind of "hack" that works.或者是否有某种有效的“黑客”。 I'm a little confused as to why my click listener is not working as expected我有点困惑为什么我的点击监听器没有按预期工作

My TokenAdapter (extends BaseAdapter)我的 TokenAdapter(扩展 BaseAdapter)

class TokenAdapter(private val ctx: Context) : BaseAdapter() {
    private val tokenPersistence: TokenPersistence = TokenPersistence(ctx)
    private val clipboardManager: ClipboardManager =
        ctx.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
    var seconds: Int
    var percentage: Int = 100
    var shouldGenerateToken: Boolean = true

    init {
        seconds = getSecondsUntilRefresh()
    }

    fun getSecondsUntilRefresh() : Int{
        val secondsElapsedInMinute = LocalDateTime.now().second
        return if(secondsElapsedInMinute < 30) 30 - secondsElapsedInMinute else 60 - secondsElapsedInMinute
    }

    override fun getCount(): Int {
        return tokenPersistence.length()
    }

    override fun getItem(position: Int): Token? {
        return tokenPersistence.get(position)
    }

    override fun getItemId(position: Int): Long {
        return position.toLong()
    }

    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
        val v: View = if (convertView == null) {
            val inflater: LayoutInflater =
                    ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
            inflater.inflate(R.layout.list_item, parent, false)
        } else {
            convertView
        }

        val t: Token = getItem(position)!!

        val title: TextView = v.findViewById(R.id.list_item_title)
        val code: TextView = v.findViewById(R.id.list_item_subtitle)
        title.text = t.getLabel()
        if (shouldGenerateToken) {
            var generatedCode : String = t.generateCode()
            generatedCode = generatedCode.substring(0, 3) + " " + generatedCode.substring(3, generatedCode.length)
            code.text = generatedCode
            shouldGenerateToken = false
        }

        val countdown: ProgressBar = v.findViewById(R.id.progress_circular)
        val countdownText: TextView = v.findViewById(R.id.progress_circular_text)

        countdownText.text = seconds.toString()
        countdown.progress = percentage

        v.setOnClickListener {
            val copyText = code.text.split(' ').joinToString("")
            println("===================")
            println("Copied: $copyText")

            val clip: ClipData = ClipData.newPlainText("2FA Code", copyText)
            clipboardManager.setPrimaryClip(clip)

            Toast.makeText(ctx, "Copied: $copyText to clipboard", Toast.LENGTH_LONG).show()
        }

        return v
    }
}

The list_item XML layout list_item XML 布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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/list_item_container"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/list_item_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="#000000"
        android:textSize="16sp"
        android:textStyle="bold"
        android:paddingHorizontal="8dp"
        android:paddingTop="16dp"
        android:paddingBottom="0dp"
        android:clickable="false"
        />


    <TextView
        android:id="@+id/list_item_subtitle"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_below="@id/list_item_title"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_toStartOf="@id/progress_circular_container"
        android:layout_toLeftOf="@id/progress_circular_container"
        android:paddingHorizontal="8dp"
        android:paddingTop="0dp"
        android:text="123456"
        android:textColor="@color/primary"
        android:textSize="32sp"
        android:textStyle="bold"
        android:clickable="false"/>

    <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/progress_circular_container"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_below="@id/list_item_title"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:clickable="false">
            <ProgressBar
                android:id="@+id/progress_circular"
                android:layout_width="48sp"
                android:layout_height="48sp"
                android:indeterminateOnly="false"
                android:progressDrawable="@drawable/pb_circular_determinative"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                tools:progress="100"/>

            <TextView
                android:id="@+id/progress_circular_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="@android:color/black"
                app:layout_constraintBottom_toBottomOf="@+id/progress_circular"
                app:layout_constraintEnd_toEndOf="@+id/progress_circular"
                app:layout_constraintStart_toStartOf="@+id/progress_circular"
                app:layout_constraintTop_toTopOf="@+id/progress_circular"
                tools:text="30" />
        </androidx.constraintlayout.widget.ConstraintLayout>

</RelativeLayout>

So I managed to fix my problem.所以我设法解决了我的问题。

I did 2 "major" things after which my problem was resolved:我做了两件“主要”的事情,之后我的问题得到了解决:

  1. I rewrote my list_item.xml making use of LinearLayout instead of RelativeLayout (although I doubt this did anything)我使用 LinearLayout 而不是 RelativeLayout 重写了我的 list_item.xml (虽然我怀疑这做了什么)

     <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical"> <TextView android:id="@+id/list_item_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#000000" android:textSize="16sp" android:textStyle="bold" android:paddingHorizontal="8dp" android:paddingTop="16dp" android:paddingBottom="0dp" /> <TextView android:id="@+id/list_item_subtitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingHorizontal="8dp" android:paddingTop="0dp" android:textColor="@color/primary" android:textSize="32sp" android:textStyle="bold" /> </LinearLayout> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"> <ProgressBar android:id="@+id/progress_circular" android:layout_width="48sp" android:layout_height="48sp" android:indeterminateOnly="false" android:progressDrawable="@drawable/pb_circular_determinative" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" tools:progress="100"/> <TextView android:id="@+id/progress_circular_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@android:color/black" app:layout_constraintBottom_toBottomOf="@+id/progress_circular" app:layout_constraintEnd_toEndOf="@+id/progress_circular" app:layout_constraintStart_toStartOf="@+id/progress_circular" app:layout_constraintTop_toTopOf="@+id/progress_circular" tools:text="30" /> </androidx.constraintlayout.widget.ConstraintLayout>
  2. I moved my ClickListener from my Adapter getView() to my MainActivity with an setOnItemClickListener on my ListView我使用 ListView 上的 setOnItemClickListener 将 ClickListener 从我的 Adapter getView() 移到了 MainActivity

     val listview = findViewById<ListView>(R.id.tokenList) listview.setOnItemClickListener { parent: AdapterView<*>, view: View, position: Int, id -> val token = tokenAdapter.getItem(position) if(token != null) { val code = token.generateCode() val clip: ClipData = ClipData.newPlainText("2FA Code", code) clipboardManager.setPrimaryClip(clip) Toast.makeText(this, "Copied: $code", Toast.LENGTH_LONG).show() } }

Using this method on my Listview I also didn't have to use clickable, or any of those kinds of properties on my XML layouts.在我的 Listview 上使用这种方法,我也不必在我的 XML 布局上使用可点击或任何这些类型的属性。 If someone knows what exactly made it work, please tell me.如果有人知道究竟是什么使它起作用,请告诉我。 Personally I think it is the Listener being an 'OnItemClick' and it being moved to the MainActivity, although don't take my word for it as it could just be something else random that I did.就我个人而言,我认为 Listener 是一个“OnItemClick”并且它被移动到 MainActivity,尽管不要相信我的话,因为它可能只是我所做的其他随机事件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM