Как я могу создавать строки с разными промежутками в VerticalGrid в библиотеке leanback

#android #android-studio #gridview #android-tv #leanback

Вопрос:

У меня есть пользовательский фрагмент для отображения элементов в сетке. Он использует VerticalGridPresenter и VerticalGridPresenter.ViewHolder для создания представлений. Я хочу добиться аналогичной компоновки, показанной на этом рисунке. Для компоновки сетки я использую настраиваемую сетку, показанную в LeanbackShowcase.

 /**
 * A fragment for rendering items in a vertical grids.
 */
open class GridFragment : Fragment(), BrowseSupportFragment.MainFragmentAdapterProvider {
    private var mAdapter: ObjectAdapter? = null
    private var mGridPresenter: VerticalGridPresenter? = null
    private var mGridViewHolder: VerticalGridPresenter.ViewHolder? = null
    private var mOnItemViewSelectedListener: OnItemViewSelectedListener? = null
    private var mOnItemViewClickedListener: OnItemViewClickedListener? = null
    private var mSceneAfterEntranceTransition: Any? = null
    private var mSelectedPosition = -1
    private val mMainFragmentAdapter: BrowseSupportFragment.MainFragmentAdapter<*> =
        object : BrowseSupportFragment.MainFragmentAdapter<Fragment?>(this) {
            override fun setEntranceTransitionState(state: Boolean) {
                this@GridFragment.setEntranceTransitionState(state)
            }
        }
    /**
     * Returns the grid presenter.
     */
    /**
     * Sets the grid presenter.
     */
    var gridPresenter: VerticalGridPresenter?
        get() = mGridPresenter
        set(gridPresenter) {
            requireNotNull(gridPresenter) { "Grid presenter may not be null" }
            mGridPresenter = gridPresenter
            mGridPresenter!!.onItemViewSelectedListener = mViewSelectedListener
            if (mOnItemViewClickedListener != null) {
                mGridPresenter!!.onItemViewClickedListener = mOnItemViewClickedListener
            }
        }
    /**
     * Returns the object adapter.
     */
    /**
     * Sets the object adapter for the fragment.
     */
    var adapter: ObjectAdapter?
        get() = mAdapter
        set(adapter) {
            mAdapter = adapter
            updateAdapter()
        }
    private val mViewSelectedListener =
        OnItemViewSelectedListener { itemViewHolder, item, rowViewHolder, row ->
            val position = mGridViewHolder!!.gridView.selectedPosition
            mGridViewHolder?.gridView?.setItemMargin(0)
            if (DEBUG) Log.v(
                TAG,
                "grid selected position $position"
            )
            gridOnItemSelected(position)
            if (mOnItemViewSelectedListener != null) {
                mOnItemViewSelectedListener!!.onItemSelected(
                    itemViewHolder, item,
                    rowViewHolder, row
                )
            }
        }
    private val mChildLaidOutListener =
        OnChildLaidOutListener { parent, view, position, id ->
            if (position == 0) {
                showOrHideTitle()
            }
        }

    /**
     * Sets an item selection listener.
     */
    fun setOnItemViewSelectedListener(listener: OnItemViewSelectedListener?) {
        mOnItemViewSelectedListener = listener
    }

    private fun gridOnItemSelected(position: Int) {
        if (position != mSelectedPosition) {
            mSelectedPosition = position
            showOrHideTitle()
        }
    }

    private fun showOrHideTitle() {
        if (mGridViewHolder!!.gridView.findViewHolderForAdapterPosition(mSelectedPosition)
            == null
        ) {
            return
        }
        if (!mGridViewHolder!!.gridView.hasPreviousViewInSameRow(mSelectedPosition)) {
            mMainFragmentAdapter.fragmentHost.showTitleView(true)
        } else {
            mMainFragmentAdapter.fragmentHost.showTitleView(false)
        }
    }
    /**
     * Returns the item clicked listener.
     */
    /**
     * Sets an item clicked listener.
     */
    var onItemViewClickedListener: OnItemViewClickedListener?
        get() = mOnItemViewClickedListener
        set(listener) {
            mOnItemViewClickedListener = listener
            if (mGridPresenter != null) {
                mGridPresenter!!.onItemViewClickedListener = mOnItemViewClickedListener
            }
        }

    /**
     * Sets the grid presenter.
     */


    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.grid_fragment, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val gridDock = view.findViewById<ViewGroup>(R.id.browse_grid_dock)
        mGridViewHolder = mGridPresenter!!.onCreateViewHolder(gridDock)
        gridDock.addView(mGridViewHolder!!.view)
        mGridViewHolder!!.gridView.setOnChildLaidOutListener(mChildLaidOutListener)
        mSceneAfterEntranceTransition = TransitionHelper.createScene(
            gridDock
        ) { setEntranceTransitionState(true) }
        mainFragmentAdapter.fragmentHost.notifyViewCreated(mMainFragmentAdapter)
        updateAdapter()
    }

    override fun onDestroyView() {
        super.onDestroyView()
        mGridViewHolder = null
    }

    override fun getMainFragmentAdapter(): BrowseSupportFragment.MainFragmentAdapter<*> {
        return mMainFragmentAdapter
    }

    /**
     * Sets the selected item position.
     */
    fun setSelectedPosition(position: Int) {
        mSelectedPosition = position
        if (mGridViewHolder != null amp;amp; mGridViewHolder!!.gridView.adapter != null) {
            mGridViewHolder!!.gridView.setSelectedPositionSmooth(position)
        }
    }

    private fun updateAdapter() {
        if (mGridViewHolder != null) {
            mGridPresenter!!.onBindViewHolder(mGridViewHolder, mAdapter)
            if (mSelectedPosition != -1) {
                mGridViewHolder!!.gridView.selectedPosition = mSelectedPosition
            }
        }
    }

    fun setEntranceTransitionState(afterTransition: Boolean) {
        mGridPresenter!!.setEntranceTransitionState(mGridViewHolder, afterTransition)
    }

    companion object {
        private const val TAG = "VerticalGridFragment"
        private const val DEBUG = false
    }
}
 

Как я могу указать разные промежутки/количество столбцов для каждой строки в фрагменте сетки?