{"record":{"id":"90ee51bfd2de4391","repo":"DrKLO/Telegram","slug":"gridlayoutmanager-does-not-support-stack-from-end","errorCode":null,"errorMessage":"GridLayoutManager does not support stack from end. Consider using reverse layout","messagePattern":"GridLayoutManager does not support stack from end\\. Consider using reverse layout","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"TMessagesProj/src/main/java/androidx/recyclerview/widget/GridLayoutManager.java","lineNumber":95,"sourceCode":"     * @param spanCount The number of columns or rows in the grid\n     * @param orientation Layout orientation. Should be {@link #HORIZONTAL} or {@link\n     *                      #VERTICAL}.\n     * @param reverseLayout When set to true, layouts from end to start.\n     */\n    public GridLayoutManager(Context context, int spanCount,\n            @RecyclerView.Orientation int orientation, boolean reverseLayout) {\n        super(context, orientation, reverseLayout);\n        setSpanCount(spanCount);\n    }\n\n    /**\n     * stackFromEnd is not supported by GridLayoutManager. Consider using\n     * {@link #setReverseLayout(boolean)}.\n     */\n    @Override\n    public void setStackFromEnd(boolean stackFromEnd) {\n        if (stackFromEnd) {\n            throw new UnsupportedOperationException(\n                    \"GridLayoutManager does not support stack from end.\"\n                            + \" Consider using reverse layout\");\n        }\n        super.setStackFromEnd(false);\n    }\n\n    @Override\n    public int getRowCountForAccessibility(RecyclerView.Recycler recycler,\n            RecyclerView.State state) {\n        if (mOrientation == HORIZONTAL) {\n            return mSpanCount;\n        }\n        if (state.getItemCount() < 1) {\n            return 0;\n        }\n\n        // Row count is one more than the last item's row index.\n        return getSpanGroupIndex(recycler, state, state.getItemCount() - 1) + 1;","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/DrKLO/Telegram/blob/45ab8f4308496e1f01026a97fcdb0d58a5274474/TMessagesProj/src/main/java/androidx/recyclerview/widget/GridLayoutManager.java#L77-L113","documentation":"GridLayoutManager lays out items into a grid of spans. setStackFromEnd (a LinearLayoutManager feature that makes the list start from the bottom/end and pad to the top) has no coherent meaning for a grid because the span grouping logic assumes forward fill from a start anchor. The class explicitly forbids enabling it and points the developer to setReverseLayout, which achieves an end-anchored layout while keeping the grid math valid. Calling setStackFromEnd(true) is therefore a configuration error, not a runtime fault.","triggerScenarios":"Code path that sets setStackFromEnd(true) on a LayoutManager that is later swapped to (or always was) a GridLayoutManager; inflating a layout with app:stackFromEnd='true' on a RecyclerView whose LayoutManager is a GridLayoutManager; sharing a config builder between LinearLayoutManager and GridLayoutManager.","commonSituations":"Porting a chat-style reverse list (which used LinearLayoutManager.setStackFromEnd) into a grid; XML attribute inherited from a template; setting stackFromEnd defensively without checking the LayoutManager type.","solutions":["Use setReverseLayout(true) on the GridLayoutManager to anchor content at the end.","Before calling setStackFromEnd, check the LayoutManager type and only apply it to LinearLayoutManager.","Remove app:stackFromEnd='true' from XML when using GridLayoutManager."],"exampleFix":"// before\nGridLayoutManager glm = new GridLayoutManager(this, 3);\nglm.setStackFromEnd(true); // throws\n\n// after\nGridLayoutManager glm = new GridLayoutManager(this, 3);\nglm.setReverseLayout(true); // end-anchored, grid-safe","handlingStrategy":"type-guard","validationCode":"// Only setStackFromEnd on LinearLayoutManager, never GridLayoutManager\nvoid maybeSetStackFromEnd(RecyclerView.LayoutManager lm, boolean stack) {\n    if (lm instanceof GridLayoutManager) {\n        if (stack) ((GridLayoutManager) lm).setReverseLayout(true);\n    } else if (lm instanceof LinearLayoutManager) {\n        ((LinearLayoutManager) lm).setStackFromEnd(stack);\n    }\n}","typeGuard":"boolean isStackFromEndSafe(RecyclerView.LayoutManager lm) {\n    return !(lm instanceof GridLayoutManager);\n}","tryCatchPattern":null,"preventionTips":["For grids, use setReverseLayout(true) to anchor content at the end.","Check LayoutManager type before calling setStackFromEnd.","Avoid app:stackFromEnd='true' in XML bound to a GridLayoutManager."],"tags":["recyclerview","gridlayoutmanager","configuration","stackfromend"],"backgroundTag":null,"analyzedSha":"45ab8f4308496e1f01026a97fcdb0d58a5274474","analyzedAt":"2026-08-14T05:19:30.815Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}