DialogFragment探索与实现(Kotlin版)

1,912 阅读2分钟

Kotlin版本

Java版本链接

class EverythingDialogFragment : DialogFragment() {

    private var mRootView: View? = null
    private var mDialog: Dialog? = null
    private var mContext: Context? = null
    private var widthPercentSize = 0f
    private var heightPercentSize = 0f
    private var layoutResID = 0
    private var holder: EverythingDialogHolder? = null
    private var viewIds: IntArray? = null
    private var mTheme = 0
    private var cancel = false
    private var touchOutside = false
    private val simpleName : String = "EverythingDialogFragment"
    private var animations : Int =0

    companion object {
        fun newInstance(): EverythingDialogFragment {
            return EverythingDialogFragment()
        }
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        mDialog = dialog
        if (mDialog != null) {
            mDialog?.setOnDismissListener(null)
            mDialog?.setOnCancelListener(null)
        }
    }

    override fun onAttach(context: Context) {
        super.onAttach(context)
        mContext = context
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (mTheme != 0) {
            setStyle(STYLE_NORMAL, mTheme)
        }
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        if (mRootView == null) {
            mRootView = inflater.inflate(layoutResID, container, false)
            setDialogSize(widthPercentSize, heightPercentSize)
        }
        return mRootView
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        mDialog = dialog

        holder = EverythingDialogHolder.create(mRootView, this)

        if (viewConvertListener != null) {
            viewConvertListener!!.convertView(holder, this)
        }
        if (holder != null && viewIds != null && viewIds!!.size > 0) {
            holder!!.addChildClickListener(viewIds!!)
        }
        if (mDialog != null) {
            val window = mDialog?.window
            window?.setWindowAnimations(animations)
            mDialog?.setCanceledOnTouchOutside(touchOutside)
            mDialog?.setOnKeyListener { _: DialogInterface?, _: Int, _: KeyEvent? -> cancel }
        }
    }

    /**
     * 其他区域是否点击消失
     * @param touchOutside
     * @return
     */
    fun setCanceledOnTouchOutside(touchOutside: Boolean): EverythingDialogFragment {
        this.touchOutside = touchOutside
        return this
    }

    /**
     * 屏蔽返回键
     * @param cancel
     * @return
     */
    fun setCanceledOnTouch(cancel: Boolean): EverythingDialogFragment {
        this.cancel = cancel
        return this
    }

    /**
     * 设置Style
     * @param theme
     * @return
     */
    fun setStyle(theme: Int): EverythingDialogFragment {
        this.mTheme = theme
        return this
    }

    /**
     * 设置dialog动画
     */
    fun setWindowAnimations(animations: Int): EverythingDialogFragment {
        this.animations = animations
        return this
    }

    /**
     * 设置布局
     * @param layoutResID
     * @return
     */
    fun setContentView(@LayoutRes layoutResID: Int): EverythingDialogFragment {
        this.layoutResID = layoutResID
        return this
    }

    /**
     * 设置显示的宽
     * @param widthPercentSize
     * @return
     */
    fun setWidthPercentSize(widthPercentSize: Float): EverythingDialogFragment {
        this.widthPercentSize = widthPercentSize
        return this
    }

    /**
     * 显示高
     * @param heightPercentSize
     * @return
     */
    fun setHeightPercentSize(heightPercentSize: Float): EverythingDialogFragment {
        this.heightPercentSize = heightPercentSize
        return this
    }


    private fun setFragmentManager(manager: FragmentManager?) {
        try {
            manager?.beginTransaction()?.remove(this)?.commitAllowingStateLoss()
            super.show(manager, simpleName)
        }catch (e:Exception){

        }
    }

    fun show(obj: Any?): EverythingDialogFragment {
        if (obj != null) {
            when (obj) {
                is FragmentActivity -> {
                    setFragmentManager(obj.supportFragmentManager)
                }
                is Fragment -> {
                    setFragmentManager(obj.fragmentManager)
                }
                else -> {
                    throw IllegalArgumentException("not is FragmentManager")
                }
            }
        }
        return this
    }

    /**
     * 设置显示屏幕大小
     */
    private fun setDialogSize(widthPercent: Float, heightPercent: Float) {
        val dm = DisplayMetrics()
        val activity = activity
        val dialog = dialog
        if (activity != null && dialog != null) {
            activity.windowManager.defaultDisplay.getMetrics(dm)
            val window = dialog.window
            if (window != null) {
                window.decorView.setPadding(0, 0, 0, 0)
                val lp = window.attributes
                lp.width = if (widthPercent == 0f) WindowManager.LayoutParams.WRAP_CONTENT else
                    if (widthPercent == 1f) WindowManager.LayoutParams.MATCH_PARENT else
                            (dm.widthPixels * widthPercent).toInt()
                lp.height = if (heightPercent == 0f) WindowManager.LayoutParams.WRAP_CONTENT else
                    if (heightPercent == 1f) WindowManager.LayoutParams.MATCH_PARENT else
                            (dm.heightPixels * heightPercent).toInt()
                window.attributes = lp
                window.setBackgroundDrawable(ColorDrawable())
            }
        }
    }

    /**
     * 可以暴露所有的view
     */
    interface ConvertViewListener {
        fun convertView(holder: EverythingDialogHolder?, dialog: EverythingDialogFragment?)
    }

    private var viewConvertListener: ConvertViewListener? = null
    fun setConvertViewListener(l: ConvertViewListener?): EverythingDialogFragment {
        viewConvertListener = l
        return this
    }

    var onChildClickListener: OnChildClickListener? = null
        private set

    /**
     * 设置子View Listener
     */
    fun setOnChildClickListener(l: OnChildClickListener?, @IdRes vararg viewIds: Int): BaseDialogFragment {
        onChildClickListener = l
        addIdRes(*viewIds)
        return this
    }

    /**
     * 设置子View Listener
     */
    fun setOnChildClickListener(l: OnChildClickListener?): EverythingDialogFragment {
        onChildClickListener = l
        return this
    }

    /**
     * 子view添加
     * @param viewIds
     * @return
     */
    fun addIdRes(@IdRes vararg viewIds: Int): EverythingDialogFragment {
        this.viewIds = viewIds
        return this
    }

}
class EverythingDialogHolder(private var convertView: View?, dialogFragment: EverythingDialogFragment?) {

    private val views: SparseArray<View?> = SparseArray()
    private val childClickViewIds: LinkedHashSet<Int> = LinkedHashSet()
    private val dialogFragment: EverythingDialogFragment? = dialogFragment

    fun <T : View?> findViewById(@IdRes viewId: Int): T? {
        var view = views[viewId]
        if (view == null) {
            view = convertView?.findViewById(viewId)
            views.put(viewId, view)
        }
        return view as T?
    }

    /**
     * 添加子view Listener
     * @param viewIds
     * @return
     */
    fun addChildClickListener(viewIds: IntArray): EverythingDialogHolder {
        for (viewId in viewIds) {
            childClickViewIds.add(viewId)
            val view = findViewById<View>(viewId)
            if (view != null) {
                if (!view.isClickable) {
                    view.isClickable = true
                }
                view.setOnClickListener(View.OnClickListener { v: View? ->
                    if (dialogFragment?.onChildClickListener != null) {
                        dialogFragment.onChildClickListener!!.onChildViewClick(dialogFragment, v)
                    }
                })
            }
        }
        return this
    }

    companion object {
        fun create(view: View?, dialogFragment: EverythingDialogFragment?): EverythingDialogHolder {
            return EverythingDialogHolder(view, dialogFragment)
        }
    }

}
interface OnChildClickListener {
    fun onChildViewClick(dialog: EverythingDialogFragment?, v: View?)
}

使用方法(一)

  EverythingDialogFragment.
                newInstance().
                setWidthPercentSize(0.8f).
                setHeightPercentSize(0.8f).
                setContentView(R.layout.dialog_test).
                show(this).
                setConvertViewListener((holder, dialog) -> {
                    TextView tv1 = holder.findViewById(R.id.tv1);
                });

使用方法(二)

  EverythingDialogFragment.
                newInstance().
                setWidthPercentSize(0.8f).
                setHeightPercentSize(0.8f).
                setContentView(R.layout.dialog_test).
                addIdRes(R.id.tv1,R.id.tv2).
                show(this).
                setOnChildClickListener((dialog, v) -> {
                    if (R.id.tv1 == v.getId()){
                        //do something
                    }
                });

Java调用Kotlin使用方法(三)

  EverythingDialogFragment.Companion.
                newInstance().
                setWidthPercentSize(0.8f).
                setHeightPercentSize(0.8f).
                setContentView(R.layout.dialog_test).
                addIdRes(R.id.tv1,R.id.tv2).
                show(this).
                setOnChildClickListener((dialog, v) -> {
                    if (R.id.tv1 == v.getId()){
                        //do something
                    }
                });