Проблема Kotlin: TimePickerDialog.OnTimeSetListener в классе (вывод: 2 значения Long

#class #kotlin

#класс #kotlin

Вопрос:

спустя 3 месяца я все еще не нашел решения, и мне нужна ваша помощь.

Язык: Kotlin (Android Studio 3.3.2 Build #AI-182.5107.16.33.5314842, собран 16 февраля 2019 JRE: 1.8.0_152-release-1248-b01 amd64 JVM: 64-разрядная серверная виртуальная машина OpenJDK от JetBrains s.r.o Windows 10 10.0)

Цель / Goal: TimePickerDialog.OnTimeSetListener в классе (вывод: 2 значения Long amp;String)

Проблема: Я не могу точно описать проблему, у меня есть только это сообщение об ошибке Kotlin. контекст: это —> Несоответствие типов. Требуется: Контекст! Найдено: MyClass

Мой код:

activity_main.xml

 <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

<TextView
        android:text="@string/textview"
        android:layout_width="125dp"
        android:layout_height="58dp"
        android:id="@ id/textView" android:layout_marginTop="60dp"
        app:layout_constraintTop_toTopOf="parent" 
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginStart="40dp"/>
<Button
        android:text="@string/button"
        android:layout_width="113dp"
        android:layout_height="58dp"
        android:id="@ id/button" android:layout_marginTop="60dp"
        app:layout_constraintTop_toTopOf="parent"         
        app:layout_constraintStart_toEndOf="@ id/textView"
        android:layout_marginStart="56dp"/>

</android.support.constraint.ConstraintLayout>
  

MainActivity.kt

 package com.terminal_io.goodapp

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity()
{

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

    var myOutput = MyClass (31415926535, "Test")

    button.setOnClickListener()
    {
        myOutput.myTime()
        textView.text = myOutput.myStringInfo
    }
  }
}
  

Класс Kotlin

 package com.terminal_io.goodapp

import android.app.TimePickerDialog
import java.sql.Time
import java.text.SimpleDateFormat
import java.util.*

class MyClass (LongInfo: Long, StringInfo : String)
{
var myLongInfo = LongInfo
var myStringInfo = StringInfo

fun myTime() : Long
{
    var cal = Calendar.getInstance()

    var timeSetListener = TimePickerDialog.OnTimeSetListener { timePicker, 
  hour, minute ->
        cal.set(Calendar.HOUR_OF_DAY, hour)
        cal.set(Calendar.MINUTE, minute)

        myStringInfo = SimpleDateFormat("HH:mm").format(cal.time)
    }

    var Hour = Calendar.HOUR_OF_DAY.toLong()
    var Minute = Calendar.MINUTE.toLong()

    var h: Long = Hour * 3600000 // Hour in millisecs
    var m: Long = Minute * 60000 // Minute in millisecs
    myLongInfo = h   m

    TimePickerDialog(this, timeSetListener, // ??? --> context: this --> 
    // Type mismatch. Required: Context! Found: MyClass
        cal.get(Calendar.HOUR_OF_DAY),
        cal.get(Calendar.MINUTE),
        true
    ).show()

    return myLongInfo; myStringInfo // ??? -> myStringInfo --> Unreachable 
    // code
    }
}
  

Комментарии:

1. Вы можете попробовать передать в context конструктор TimePickerDialog и использовать в этом «проблемном» месте.

2. @Boken: Спасибо. Не могли бы вы, пожалуйста, немного рассказать мне, как. Я недостаточно опытен, чтобы самостоятельно передавать контекст в TimePickerDialog. Я благодарен за любую дополнительную информацию.

Ответ №1:

Насколько я понимаю, у вас есть некоторое время в миллисекундах, и вы хотели бы преобразовать его во время (где 31415926535 равно 15:38) и установить это время в средстве выбора времени.

Вы можете делать все в своей деятельности (в одном классе):

 package training.com.myapplication

import android.app.TimePickerDialog
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
import java.util.*

class MainActivity : AppCompatActivity() {

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

        val time = 31415926535 // It is:  15:38

        setTimeListener(time)
    }

    private fun setTimeListener(time: Long) {
        // Get instance of calendar
        val calendar = Calendar.getInstance()

        // Set time (from milliseconds)
        calendar.timeInMillis = time

        // Create dialog and set hours, minutes and 24 hours mode
        val dialog = TimePickerDialog(
            this,
            getTimePickerListener(),
            calendar.get(Calendar.HOUR_OF_DAY),
            calendar.get(Calendar.MINUTE),
            true
        )

        // After button click - open dialog
        button.setOnClickListener {
            dialog.show()
        }
    }

    private fun getTimePickerListener() =
        TimePickerDialog.OnTimeSetListener { _, hourOfDay, minute ->
            // After selecting time - set text in TextView
            textView.text = "d:d".format(hourOfDay, minute)
        }

}
  

Вы также можете переместить часть кода в отдельный класс

 package training.com.myapplication

import android.app.TimePickerDialog
import android.content.Context
import java.util.*

class MyOwnClass(
    private val context: Context,
    private val timePickerListener: TimePickerDialog.OnTimeSetListener
) {

    fun showTimeDialog(time: Long) {
        // Get instance of calendar
        val calendar = Calendar.getInstance()

        // Set time (from milliseconds)
        calendar.timeInMillis = time

        // Create dialog and set hours, minutes and 24 hours mode
        TimePickerDialog(
            context,
            timePickerListener,
            calendar.get(Calendar.HOUR_OF_DAY),
            calendar.get(Calendar.MINUTE),
            true
        ).show()
    }
}
  

И вызываете в своем Activity (передавая context , listener и time )

 package training.com.myapplication

import android.app.TimePickerDialog
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

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

        val time = 31415926535 // It is:  15:38

        val dialog = MyOwnClass(this, getTimePickerListener())

        // After button click - open dialog
        button.setOnClickListener {
            dialog.showTimeDialog(time)
        }
    }

    private fun getTimePickerListener() =
        TimePickerDialog.OnTimeSetListener { _, hourOfDay, minute ->
            // After selecting time - set text in TextView
            textView.text = "d:d".format(hourOfDay, minute)
        }
}
  

Комментарии:

1. Большое спасибо, Боке. Это работает. Но я хочу, чтобы это работало в классе.

2. Что вы имеете в виду work in a class ? Это в MainActivity.kt

3. когда я создаю свой собственный класс. Класс MyClass (LongInfo: длинный, StringInfo: строка) {…}

4. добавлен @WaldemarNeifert. Что вы думаете? Вы можете переместить всю логику в новый класс и во время создания передать контекст, прослушиватель и время (в миллисекундах).

5. спасибо, чувак, ты действительно помог мне. Мне было трудно понять все это -> timepickerdialog отдельный класс передача вещей…