Как отобразить диалоговое окно фрагмента в button.setOnClickListener из класса адаптера в Kotlin-MVP?

Я разрабатываю одно приложение для Android, используя эту структуру Kotlin-MVP. У меня есть одно действие, и оно содержит TabLayout из 4 фрагментов. Весь фрагмент имеет одну кнопку в RecyclerView. Мне нужно показать один «Диалог фрагмента» на этом прослушивателе нажатия кнопки. Не могли бы вы сообщить мне, как я могу отобразить диалоговое окно фрагмента при прослушивании нажатия кнопки из класса адаптера? Пожалуйста, просмотрите снимок экрана.

введите здесь описание изображения

Я обращаюсь к кнопке в событии прослушивателя кликов из класса адаптера, который находится ниже itemView.btn_accept.setOnClickListener:

class InApprovalAdapter(private val jobListItems: MutableList<JobItem>) : RecyclerView.Adapter<InApprovalAdapter.JobViewHolder>() {

private var _ProfileId: Long? = null;

fun getProfileId(): Long? {
    return _ProfileId
}

fun setProfileId(s: Long) {
    _ProfileId = s
}

private var _UserToken : String? = null;

fun getUserToken(): String? {
    return _UserToken
}

fun setUserToken(s: String) {
    _UserToken = s
}

private var _UserTypeId : Long? = null;
fun getUserTypeId(): Long? {
    return _UserTypeId
}

fun setUserTypeId(s: Long) {
    _UserTypeId = s
}


override fun getItemCount() = this.jobListItems.size

override fun onBindViewHolder(holder: JobViewHolder, position: Int) = holder.let {
    it.clear()
    it.onBind(position)
}

override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int) = JobViewHolder(LayoutInflater.from(parent?.context)
        .inflate(R.layout.item_inapproval_list, parent, false))

internal fun addJobsToList(jobs: List<JobItem>, profileId: Long?, userToken: String?, userTypeId: Long?) {
    this.jobListItems.addAll(jobs)
    setProfileId(profileId!!.toLong())
    setUserToken(userToken!!)
    setUserTypeId(userTypeId!!)
    notifyDataSetChanged()
}

inner class JobViewHolder(view: View) : RecyclerView.ViewHolder(view) {

    fun clear() {
        itemView.tv_job_id.text = "";
        itemView.tv_job_title.text= "";
        //itemView.tv_job_description.text ="";
        itemView.tv_job_category.text ="";
        itemView.tv_date_created.text ="";
    }

    fun onBind(position: Int) {

        val (jobId, name, description, serviceId, serviceName,
                address, engineerIds, engineerNames, startDateTimeUtc,
                startDateTimeLocal, endDateTimeUtc, endDateTimeLocal,
                customerId, customerName, customerMobile, customerAltMobile,
                priorityTypeId, priorityTypeName, statusTypeId, statusTypeName,
                isDeleted, isStatusTypeActive, createdBy, createdByName,
                dateCreatedPretty, modifiedBy, modifiedByName ,hasJobMedia,
                jobMedias, hasJobFeedback, jobDetailsImage, dateCreatedUtc, dateModifiedUtc) = jobListItems[position]

        inflateData(jobId, name,
                description,
                serviceId,
                serviceName,
                address,
                engineerIds,
                engineerNames,
                startDateTimeUtc,
                startDateTimeLocal,
                endDateTimeUtc,
                endDateTimeLocal,
                customerId,
                customerName,
                customerMobile,
                customerAltMobile,
                priorityTypeId,priorityTypeName,
                statusTypeId,
                statusTypeName,
                isDeleted,
                isStatusTypeActive,
                createdBy,
                createdByName,
                dateCreatedPretty,
                modifiedBy,
                modifiedByName ,
                hasJobMedia,
                jobMedias, hasJobFeedback, jobDetailsImage, dateCreatedUtc, dateModifiedUtc)
        setItemClickListener(jobId)
    }

    private fun setItemClickListener(jobId: Long?) {
        itemView.setOnClickListener {
            jobId?.let {
                try {
                    val intent = Intent(itemView.context, ServiceDetailActivity::class.java)
                    intent.putExtra("JobId", jobId)
                    itemView.context.startActivity(intent)
                } catch (e: Exception) {
                    Toast.makeText(itemView.context, e.message, Toast.LENGTH_LONG).show()
                }
            }
        }

        itemView.btn_accept.setOnClickListener {



        }

        itemView.btn_reject.setOnClickListener{

        }
    }
    private fun inflateData(jobId: Long?, name: String?, description: String?, serviceId: Long?, serviceName: String?, address: String?, engineerIds: String?,
                            engineerNames: String?, startDateTimeUtc: String?, startDateTimeLocal: String?, endDateTimeUtc: String?,
                            endDateTimeLocal: String?, customerId: Long?, customerName: String?, customerMobile:String?, customerAltMobile: String?,
                            priorityTypeId: Long?, priorityTypeName: String?, statusTypeId: Long?, statusTypeName: String?, isDeleted: Boolean?, isStatusTypeActive: Boolean?,
                            createdBy: Long?, createdByName: String?, dateCreatedPretty: String?, modifiedBy: Long?, modifiedByName: String?, hasJobMedia: Boolean?,
                            jobMedias: List<JobDetailsImage>?, hasJobFeedback: Boolean?, jobDetailsImage:  List<JobDetailsImage>?, dateCreatedUtc: String?, dateModifiedUtc: String?) {
        name.let {
            itemView.tv_job_title.text = it;
        }
        jobId.let {
            itemView.tv_job_id.text = "Job\n#" + it
        }
        /*description.let {
            itemView.tv_job_description.text = it
        }*/
        serviceName.let {
            itemView.tv_job_category.text = it
        }
        dateCreatedPretty.let {
            itemView.tv_date_created.text = it
        }

        if(getUserTypeId() == AppConstants.UserType.Administrator.type ||
                getUserTypeId() == AppConstants.UserType.Admin.type)
        {
            itemView.btn_reject.text = "Reject";
        }
        else
        {
            itemView.btn_reject.text = "Delete";
            itemView.btn_accept.visibility = View.GONE
        }
    }

    private fun callJobStatusChangeApi(jobId: Long?, statusTypeId: Long?)
    {
        val androidId = Settings.Secure.getString(itemView.context.contentResolver, Settings.Secure.ANDROID_ID)

        Rx2AndroidNetworking.post(ApiEndPoint.ENDPOINT_JOB_CHANGEJOBSTATUS)
                .addHeaders("Authorization", "bearer " + getUserToken())
                .addQueryParameter("profileId",  getProfileId().toString())
                .addQueryParameter("jobId", jobId.toString())
                .addQueryParameter("statusTypeId", statusTypeId.toString())
                .addQueryParameter("DeviceId", androidId.toString())
                .build()
                .getAsObject(BaseResponse::class.java, object : ParsedRequestListener<BaseResponse> {

                    override fun onResponse(baseResponse: BaseResponse) {
                        // do anything with response
                        println("succeeded : " + baseResponse.succeeded)
                        println("message : " + baseResponse.message)

                        if(baseResponse.succeeded)
                        {
                            val inApprovalFragment : InApprovalFragment = InApprovalFragment()
                            inApprovalFragment.showStatusSubmissionSuccessMessage(itemView.context, baseResponse.message);
                            notifyDataSetChanged();
                        }
                    }

                    override fun onError(anError: ANError) {
                        // handle error
                        println(anError.message);
                    }

                })
    }

}

}

person Keval Gangani    schedule 17.05.2018    source источник
comment
Не понятно где проблема. Если у вас есть проблемы с доступом к FragmentManager, вы можете получить к нему доступ из контекста (который будет действием) любого представления, как вы уже делали с itemView. Другим подходом может быть передача лямбда-выражения вашему адаптеру, который вы будете вызывать в OnClickListener кнопки принятия. Поскольку адаптер и эта лямбда будут созданы в классе Fragment, вы можете получить доступ к FragmentManager с помощью getFragmentManager().   -  person user    schedule 18.05.2018
comment
@Luksprog В этом проблема. Я не могу получить доступ к getFragmentManager() в классе адаптера. Я новичок в Android и начал изучать Kotlin со структурой MVP. У вас есть пример лямбда?   -  person Keval Gangani    schedule 18.05.2018
comment
@Luksprog Я попробовал этот код ServiceAssignDialog.newInstance().let { it?.show(supportFragmentManager); }, но он говорит о неразрешенной ссылке supportFragmentManager.   -  person Keval Gangani    schedule 18.05.2018
comment
Я показал вам пример. Код, который вы разместили в комментарии, не будет работать, потому что вы выходите за рамки FragmentManager в адаптере.   -  person user    schedule 18.05.2018


Ответы (2)


Если у вас есть проблемы с доступом к FragmentManager, вы можете просто передать лямбду вашему адаптеру в качестве OnClickListener кнопки принятия:

class InApprovalAdapter(
    private val jobListItems: MutableList<JobItem>
    // If you have data to pass to the handler(like a jobId for example) 
    // modify the lambda like (Int) -> Unit
    private val acceptHandler: () -> Unit
    ) : RecyclerView.Adapter<InApprovalAdapter.JobViewHolder>() {

Затем вы можете использовать эту лямбду:

itemView.btn_accept.setOnClickListener {
     acceptHandler()
}

Затем создайте адаптер:

val adapter = InApprovalAdapter(theListOfItems, val clickListener: (Item) -> Unit) {
    // I'm assuming you're creating this adapter inside the Fragment class
    // so at this point you can access getFragmentManager()
    // ideally you'll let the presenter know that something happened in the view: presenter.userAcceptedJob()
    // and the presenter will call back a method on the view to actually show the DialogFragment.
}
person user    schedule 18.05.2018
comment
Я пробовал это решение, но оно не работает. Я создал partItemClicked лямбду, но она не сработала. Я применил вашу логику в PendingFragment.kt и PendingAdapter.kt к itemView.tv_select_engineer.setOnClickListener. Пожалуйста, просмотрите мой код здесь, gist.github.com/kg-dexterity/d76d285eb6e7a195c9a427bc1f6880ba - person Keval Gangani; 19.05.2018
comment
@Keval Ваш код немного сбивает с толку. Прежде всего, вы дважды устанавливаете OnClickListener в itemView.tv_select_engineer: один раз в методе inflateData() правильно (вызывая clickListener()), а затем снова в методе setItemClickListener() неправильно (это не сработает, потому что у вас нет ссылка на FragmentManager). Кроме того, ссылка на адаптер в PendingFragment вводится (чего вам, вероятно, не следует делать), а затем в displayJobList() она заменяется другим экземпляром PendingAdapter. - person user; 19.05.2018
comment
@Keval Я обновил код, который вы опубликовали, добавив более простое решение, которое позволит вам сохранить часть внедрения зависимостей: >gist.github.com/luksprog/802cab392cd357862fae57455a9d7a22 - person user; 19.05.2018
comment
Оба ваших решения работают нормально. Я действительно ценю. Спасибо @Lusprog - person Keval Gangani; 19.05.2018

Я делаю то же самое, показываю пользовательский диалог из адаптера, который вызывается из фрагмента. Не нужно создавать фрагмент диалога, он будет делать то же самое.

Передать активность из фрагмента при настройке адаптера

в фрагменте списка: -

rvAdapter = Listadapter( listnotes,activity!!)

в классе Listadapter: -

class Listadapter( val DataList: ArrayList<String>?,val parentActivity: Activity) : RecyclerView.Adapter<Listadapter.ViewHolder>() {}

в методе onBindViewHolder: -

view.notes.setOnClickListener {
        DialogNOTES(parentActivity,DataList[position])
    }

make метод для отображения пользовательского ежедневного журнала в классе Listadapter: -

private fun DialogNOTES(parentActivity: Activity,notes:String) {
    val dialog = Dialog(parentActivity)
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
    dialog.setCancelable(true)
    dialog.setContentView(R.layout.notes_dilog)//custom dialog layout 
    dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));

    dialog.show()

    dialog.dilog_notes.setText(notes)


}
person pragati kushwaha    schedule 18.02.2020