【问题标题】:ListView is not clickable (custom Adapter)ListView 不可点击(自定义适配器)
【发布时间】:2019-04-22 23:52:36
【问题描述】:

我正在尝试使用 Rome 创建一个简单的 RSS 阅读器。

我的准系统实现使用ListView 和我的自定义Adapter 来填充feed_stub.xml。单击 ListView 项目将启动另一个活动。

到目前为止,我有两个问题:

  1. 我的 ListView 项目不可点击 - 我的 setOnItemClickListener 未触发。

  2. 如果我多次单击某些项目,我的应用程序会崩溃并出现超出范围的异常。这意味着我的适配器可能有错误。

ListView 来自activity_main.xml

<ListView
            android:layout_width="0dp"
            android:layout_height="0dp" android:layout_marginTop="8dp"
            app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent"
            android:layout_marginStart="8dp"
            android:layout_marginBottom="8dp" app:layout_constraintBottom_toBottomOf="parent"
            android:id="@+id/rssListView" app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="8dp"
            android:clickable="true" app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintVertical_bias="0.0"/>

我的MainActivity

import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import cz.cvut.lenguduy.rss.Downloader
import cz.cvut.lenguduy.view.ViewHolder
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {
    private val TAG = "MainActivity"

    private val downloader by lazy { Downloader(this, rssListView) }

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

        rssListView.setOnItemClickListener { parent, _, position, _ ->
            Log.d(TAG, "rssListView: item @pos $position clicked")
            val intent = Intent(this, SecondActivity::class.java)
            val item = parent.getItemAtPosition(position) as ViewHolder

            Toast.makeText(this, "clicked", Toast.LENGTH_LONG).show()

            intent.putExtra("title", item.tvName.text)
            intent.putExtra("text", item.tvSummary.text)
            this.startActivity(intent)
        }

        downloader.execute("http://ax.itunes.apple.com/WebObjects/MZStoreServices.woa/ws/RSS/topfreeapplications/limit=25/xml")
    }

    override fun onDestroy() {
        super.onDestroy()
        downloader.cancel(true)
    }
}

ViewHolder 很简单:

class ViewHolder(view: View) {
    val tvName: TextView = view.findViewById(R.id.tvName)
    val tvSummary: TextView = view.findViewById(R.id.tvSummary)
}

我的ListView 使用feed_stub.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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">

    <TextView
            android:text="TextView"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:id="@+id/tvName" android:layout_marginTop="8dp"
            app:layout_constraintTop_toTopOf="parent" app:layout_constraintEnd_toEndOf="parent"
            android:layout_marginEnd="16dp" app:layout_constraintStart_toStartOf="parent"
            android:layout_marginStart="16dp" android:textSize="20sp" android:textStyle="bold" android:maxLines="2"
            android:clickable="true"/>
    <TextView
            android:text="TextView"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:id="@+id/tvSummary"
            app:layout_constraintTop_toBottomOf="@+id/tvName" app:layout_constraintEnd_toEndOf="parent"
            android:layout_marginEnd="16dp" app:layout_constraintStart_toStartOf="parent"
            android:layout_marginStart="16dp" android:maxLines="3" android:clickable="true"/>
</android.support.constraint.ConstraintLayout>

最后是我的FeedAdapter

class FeedAdapter(context: Context,
                  private val resource: Int, private val feed: MutableList<Any?>)
    : ArrayAdapter<Article>(context, resource) {

    private val inflater = LayoutInflater.from(context)

    override fun getCount(): Int {
        return feed.size
    }

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        val view: View
        val viewHolder: ViewHolder
        if(convertView == null) {
            view = inflater.inflate(resource, parent, false)
            viewHolder = ViewHolder(view)
            view.tag = viewHolder
        } else {
            view = convertView
            viewHolder = view.tag as ViewHolder
        }

        val currentEntry = feed[position] as SyndEntry

        viewHolder.tvName.text = currentEntry.title
        viewHolder.tvSummary.text = currentEntry.description.value

        return view
    }

    override fun isEnabled(position: Int): Boolean {
        return true
    }
}

大部分操作都是由我的伪控制器执行的:

class Downloader(context: Context, listView: ListView): AsyncTask<String, Void, String>() {
    private val TAG = "Downloader"

    private var propContext: Context by Delegates.notNull()
    private var propListView: ListView by Delegates.notNull()

    init {
        propContext = context
        propListView = listView
    }

    private lateinit var list: MutableList<Any?>

    override fun doInBackground(vararg url: String?): String {
        val input = SyndFeedInput()
        val feed = input.build(XmlReader(URL(url[0])))

        list = feed.entries

        return feed.toString()
    }

    override fun onPostExecute(result: String?) {
        super.onPostExecute(result)

        val feedAdapter = FeedAdapter(propContext, R.layout.feed_stub, list)
        propListView.adapter = feedAdapter
    }
}

那么为什么我的ListView 项目无法点击?

为什么我的应用程序在多次点击java.lang.IndexOutOfBoundsException: Invalid index 10, size is 0 后会崩溃?

编辑:FeedAdapters getView() 我添加了这个onClickListener:

convertView?.setOnClickListener() { v ->
            Log.d(TAG, "getView(): item clicked")

            val intent = Intent(context, SecondActivity::class.java)
            intent.putExtra("title", currentEntry.title)
            intent.putExtra("summary", currentEntry.description.value)

            context.startActivity(intent)
        }

现在我有时可以点击它。我完全不知道为什么会这样,但如果我足够随机地点击,我会得到去另一个活动的预期行为。

【问题讨论】:

  • 您好,能否请您添加code-sn-p,您在哪里创建了FeedAdapter对象并将其分配给'rssListView'?
  • val item = parent.getItemAtPosition(position) as ViewHolder 是错误的。 getItemAtPosition 在你的情况下应该是 Article
  • @Jatin 添加了代码。

标签: android listview kotlin clickable


【解决方案1】:

这是因为您没有为 viewHolder 类实现 onClickListener。您已经为 listview onItemClick Listener 实现了,它根本不适用于自定义适配器。对于自定义适配器,您需要在 getView 方法中实现 onClickListener。

override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        val view: View
        val viewHolder: ViewHolder
        if(convertView == null) {
            view = inflater.inflate(resource, parent, false)
            viewHolder = ViewHolder(view)
            view.tag = viewHolder
        } else {
            view = convertView
            viewHolder = view.tag as ViewHolder
        }

        val currentEntry = feed[position] as SyndEntry

        viewHolder.tvName.text = currentEntry.title
        viewHolder.tvSummary.text = currentEntry.description.value

        // set onClickListener for your ConvertView...
        convertView.setOnClickListener(context);    

        return view
    }

// now implement your on Click 
@Overriden
void onClick(View view){

}

【讨论】:

  • 我不明白,当ViewHolder 不继承任何东西时,我将如何实现onClickLIstener()?而且我也完全不理解您的onClick,因为这不是您创建函数的方式。
  • 它是被覆盖的函数,是的,在这个自定义适配器场景中,convertView 将作为 listview 的 viewHolder 工作。看到我没有为 viewHolder 实现 setOnClickListener,我正在为 convertView 做它。检查代码。
  • 我正在查看代码,因为您将 Java 与 Kotlin 混合使用,所以非常令人困惑。无论如何,我已经使用 lambdas 实现了setOnClickListener(因为我仍然完全不知道你的onClick() 应该做什么或者它应该在哪里)现在我的项目是可点击的,但只是有时我不知道为什么(见上次编辑)。
  • @LeNguyenDuyAnh,看,我的代码是用 java 编写的,但它很容易理解。我只是在 convertView 上设置 onClickListener,因为那是您单击的视图。然后你需要实现 onClick 方法,就像每个 viewOnClick 监听器一样。就是这样,在 onClick 中,当单击 listView 中的项目时,您可以放置​​代码来完成您的工作,
  • 在编辑中,您正在描述“现在我有时可以点击它”。所以你的问题现在可能是别的东西。检查您的 logcat 并将其放入问题中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多