如何在 Android 中使用接口作为监听器和 Dialog?
Posted
技术标签:
【中文标题】如何在 Android 中使用接口作为监听器和 Dialog?【英文标题】:How to use interfaces as listeners from and Dialoge in Android? 【发布时间】:2021-03-03 15:21:47 【问题描述】:我不知道如何将 android 中的接口用作事件侦听器。我用方法onProfilePictureTaken
定义了一个接口ProfilePictureTakenEvent
。在通过单击片段的按钮打开的对话框中,用户可以使用相机拍摄图像。我使用了startActivityForResult
的方法。我在片段中得到的这个动作的结果(图像)(被覆盖的方法onActivityResult
)。
现在我的问题是:当我在片段中获得结果时,如何在对话框中显示这张图片?我以为我可以使用事件监听器,但我不知道怎么做也没有找到任何解释。
这是我的代码:
UserFragment.tk
class UserFragment() : Fragment()
private var userFragment: UserFragment? = null
private var profilePictureTakenEvent: ProfilePictureTakenEvent? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View?
return inflater.inflate(R.layout.fragment_user, container, false)
override fun onViewCreated(
view: View,
savedInstanceState: Bundle?
)
super.onViewCreated(view, savedInstanceState)
this.userFragment = this
val database = UserManagerDatabase(view.context)
val repository = UserRepository(database)
val factory = UserViewModelFactory(repository)
val viewModel = ViewModelProviders.of(this, factory).get(UserViewModel::class.java)
val adapter = UserAdapter(listOf(), viewModel)
rvUsers.layoutManager = LinearLayoutManager(view.context)
rvUsers.adapter = adapter
var emailAddresses: List<String> = emptyList()
viewModel.getAll().observe(viewLifecycleOwner, userList ->
adapter.users = userList
emailAddresses = userList.map user -> user.email
adapter.notifyDataSetChanged()
)
viewModel.getEmailAddresses().observe(viewLifecycleOwner, emailAddresses = it )
fBtnAddUser.setOnClickListener
AddUserDialog(view.context,
object: UserCreateEvent
override fun onAddButtonClicked(user: User)
viewModel.insert(user)
, emailAddresses, userFragment).show()
fun setProfilePictureTakenEvent(profilePictureTakenEvent: ProfilePictureTakenEvent)
this.profilePictureTakenEvent = profilePictureTakenEvent
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?)
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == AddUserDialog.REQUEST_IMAGE_CAPTURE)
this.profilePictureTakenEvent?.onProfilePictureTaken(data)
AddUserDialog.kt:
class AddUserDialog(
context: Context,
private var userCreateEvents: UserCreateEvent,
private var emails: List<String>,
private var parentFragment: UserFragment?
) : AppCompatDialog(context), ProfilePictureTakenEvent
companion object
const val REQUEST_IMAGE_CAPTURE = 1
private var imageData: Bitmap? = null
override fun onProfilePictureTaken(data: Intent?)
this.ivProfilePicture.setImageBitmap(data?.extras?.get("data") as Bitmap)
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.dialog_add_user)
setTitle(context.getString(R.string.title_add_user))
val editTextViews: Map<String, EditText> = mapOf(
"first_name" to dAddUserEdFirstName,
"last_name" to dAddUserEdLastName,
"email" to dAddUserEdEmail,
"password" to dAddUserEdPassword,
"password_confirmation" to dAddUserEdPasswordConfirmation
)
dAddUserBtnSave.setOnClickListener
val firstName = dAddUserEdFirstName.text.toString()
val lastName = dAddUserEdLastName.text.toString()
val username = "$firstName.toLowerCase(Locale.GERMAN)-$lastName.toLowerCase(Locale.GERMAN)"
val email = dAddUserEdEmail.text.toString()
val password = dAddUserEdPassword.text.toString()
val passwordConfirmation = dAddUserEdPasswordConfirmation.text.toString()
var error = false
val emptyFields: StringBuilder = StringBuilder()
// Check if any EditText is empty
editTextViews.forEach (key, editTextView) ->
val textEmpty: Boolean = editTextView.text.toString().isEmpty()
if (textEmpty)
error = true
emptyFields.append("$context.getString(AppHelper.stringTranslation(key)), ")
AppHelper.updateBackground(context, editTextView, if (textEmpty) R.drawable.input_field_error else R.drawable.input_field)
if (error)
//AppHelper.showToastLong(context, context.getString(R.string.error_field_not_filled, AppHelper.commaStringToCorrectGrammatical(context, emptyFields.toString())))
return@setOnClickListener
// Check if E-Mail address is valid
if (AppHelper.invalidEmail(email))
AppHelper.showToastShort(context, R.string.error_invalid_email)
return@setOnClickListener
// Check if supplied E-Mail address is unique
if (emails.contains(email))
AppHelper.showToastShort(context, R.string.error_email_already_taken)
return@setOnClickListener
// Check if password and password confirmation match
if (password != passwordConfirmation)
AppHelper.showToastShort(context, R.string.error_password_confirmation_not_matching)
return@setOnClickListener
//TODO: Password hashing
// Creating the User
val user = User(firstName, lastName, username, email, password)
userCreateEvents.onAddButtonClicked(user)
// Closing the dialog after calling the onClickEvent and data is valid
dismiss()
btnTakeProfilePicture.setOnClickListener
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
try
parentFragment?.startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE)
catch (e: ActivityNotFoundException)
AppHelper.showToastLong(context, "Fehler")
// Close dialog when cancel Button is clicked
dAddUserBtnCancel.setOnClickListener cancel()
ProfilePictureTakenEvent.kt:
interface ProfilePictureTakenEvent
fun onProfilePictureTaken(data: Intent?)
【问题讨论】:
【参考方案1】:据我了解,您的对话框在捕获图像后仍会显示, 就像从那个片段创建对话框一样,一个简单的解决方案可以是:将对象保存在一个全局变量中,可以调用一个函数来显示捕获的图像。 喜欢:
val dialog = AddUserDialog(....)
里面
onActivityResult(..)
...
dialog.updateImage(data)
因此实际上您不需要任何侦听器来在对话框中显示图像。
【讨论】:
这很简单,而且很有效。非常感谢!以上是关于如何在 Android 中使用接口作为监听器和 Dialog?的主要内容,如果未能解决你的问题,请参考以下文章