【问题标题】:How to get a ProgressBar (or a button...) into class in android through koltin?如何通过kotlin将进度条(或按钮......)放入android中的类?
【发布时间】:2019-02-25 19:59:34
【问题描述】:

我需要知道如何在“onCreate”方法之外将 ProgressBar(或任何其他类型的按钮)调用到一个类中。 我在 Java 中看到我可以调用 findViewById(),但是在 Kotlin 中它已被删除。 例如,我正在尝试这样的事情:

 var myProgressBar = findViewById(R.id.myProgressBar) as ProgressBar

但它给了我查找视图方法的未解决参考。

提前感谢您的帮助

______________更新___________________

这是我的 DownloadManager 自定义类

class DownloadSoundController(context: Context): Activity() {

val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
.....
.....
      Thread(Runnable{
        while (starter) {
            var query = DownloadManager.Query()
            query.setFilterById(refid)
            var c = downloadManager.query(query)

            if (c.moveToFirst()) {
                var totalSizeIndex = c.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)
                var downloadedIndex = c.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)
                val fileSize = c.getLong(c.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES))
                var totalSize = c.getInt(totalSizeIndex)
                var downloaded = c.getInt(downloadedIndex)
                var progress = 0.0
                var raffronto: Long = -1

                if (fileSize != raffronto) {
                    progress = downloaded * 100.0 / totalSize
                    //println("myTag - downloaded % :$progress, downloaded var: $downloaded")
                    myProgressBar.progress = progress.toInt()
                    if (progress == 100.0) {
                        starter = false
                    }
                } else {
                    //println("myTag - downloaded = 100 progress: $progress, $downloaded")
                    myProgressBar.progress = progress.toInt()
                    if (progress == 100.0) {
                        starter = false
                    }
                }
            }
        }
    }).start()

这是我的清单:

<application
        android:hardwareAccelerated="true"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

    <activity
            android:name="com.journeyapps.barcodescanner.CaptureActivity"
            android:screenOrientation="fullSensor"
            tools:replace="screenOrientation" />

    <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>

            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
//ATTENTION
   <activity android:name="com.example.myapplication.DownloadSoundController"/> 
// here it returns ERROR, on default constructor

    <receiver android:name=".DownloadBroadcastManager">
        <intent-filter>
            <action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
        </intent-filter>
    </receiver>

</application>

_________UPDATE_2__________

我完善了代码,发现了几个对我来说听起来很“奇怪”的问题:

1) 要停止关于 myProgressBar.progress = value 的空点异常,我发现我必须初始化 myProgressBar.progress = 0

2) 使用 println() 我的线程将我的文件的下载量逐步准确地标记到日志中,但是如果我添加 myProgressBar.progress = progress.toInt() (进度变量与我标记的相同)进入线程中的 println()!)... 它开始异步,甚至在下载开始之前就开始了.. 导致几个错误和 多次 下载“

我真的不知道发生了什么

【问题讨论】:

  • 我不认为 Kotlin 无权访问 findViewById。也许你做错了什么。
  • 我又更新了……真的很“奇怪”

标签: java android kotlin android-button android-progressbar


【解决方案1】:

findViewById 现在返回一个泛型类型,它扩展了View (docs)

final <T extends View> T findViewById(...)

你可以使用

val progressBar = findViewById<ProgressBar>(R.id.myProgressBar)

【讨论】:

  • 它似乎一直给我一个标记为“未解决”。我试过了,我可以在主要活动的每个函数中调用 progressBar,但是我需要在另一个 class.kt 文件中使用它
  • @MicheleRava 你确定你使用的是正确的 SDK 版本吗?
  • 我添加了 :Activity() 构造函数。现在它可以看到 myProgressBar,就像在 MainActivity.kt 中发生的那样......但是它现在会导致崩溃并出现此错误: Process: com.example.myapplication, PID: 20468 java.lang.NullPointerException: Attempt to invoke virtual method ' android.view.View android.view.Window.findViewById(int)' 在空对象引用上
  • @MicheleRava 只有在 onCreate 中调用 setContentView 后才能完全构造 Activity。在此之前您不能使用 findViewById
  • 我的 DownloadManager 自定义类稍后执行......理论上。看来,相反,当我激活下载时,Activity 尚未完全构建......我该怎么做才能让它正确?
【解决方案2】:

首先,它在 Kotlin 中的工作方式相同。

但在 Kotlin 中有更好的方法:

将以下行添加到您的应用程序 build.gradle: apply plugin: 'kotlin-android-extensions'

现在,您可以通过 id 访问视图:

例如myProgressBar.progress = 30

更多:https://kotlinlang.org/docs/tutorials/android-plugin.html

【讨论】:

    【解决方案3】:

    将以下行添加到 build.gradle:apply plugin: 'kotlin-android-extensions

    import kotlinx.android.synthetic.main.activity_main.*
    
    class MyActivity : Activity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            // Instead of findViewById<TextView>(R.id.textView)
            textView.setText("Hello, world!")
        }
    }
    

    这也可以在 onCreate 之外完成。

    【讨论】:

    • 是的,它适用于我的 MainActivity.kt 中的所有函数...但是它不适用于我的“CustomClass.kt”文件
    • CustomClass 是否扩展了 Activity?它是说 class CustomClass : Activity() 吗?它必须扩展 Activity 才能工作。
    • 其实没有。我创建了一个自定义类来处理 DownloadManager。在其中我创建了一个线程来跟踪下载百分比,现在我的目标是将这些值发送到我的进度条
    • 我刚刚添加了一个带有 :Activity() 的构造函数(正如你所建议的那样),现在它可以工作了
    • 好的,我的应用程序现在似乎崩溃了......我认为内部可能存在不同的问题非常感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-16
    • 2011-06-14
    • 2011-04-28
    • 1970-01-01
    • 2021-10-20
    • 2021-05-29
    • 1970-01-01
    相关资源
    最近更新 更多