Full Code of google/flexbox-layout for AI

main 366b461fd042 cached
181 files
1.1 MB
253.1k tokens
429 symbols
1 requests
Download .txt
Showing preview only (1,157K chars total). Download the full file or copy to clipboard to get everything.
Repository: google/flexbox-layout
Branch: main
Commit: 366b461fd042
Files: 181
Total size: 1.1 MB

Directory structure:
gitextract_48clvfh9/

├── .circleci/
│   └── config.yml
├── .github/
│   ├── issue_template.md
│   └── workflows/
│       └── gradle-wrapper-validation.yml
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── build.gradle
├── demo-cat-gallery/
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── google/
│           │           └── android/
│           │               └── flexbox/
│           │                   └── apps/
│           │                       └── catgallery/
│           │                           ├── CatAdapter.kt
│           │                           ├── CatViewHolder.kt
│           │                           └── MainActivity.kt
│           └── res/
│               ├── layout/
│               │   ├── activity_main.xml
│               │   ├── content_main.xml
│               │   └── viewholder_cat.xml
│               ├── values/
│               │   ├── colors.xml
│               │   ├── dimens.xml
│               │   ├── strings.xml
│               │   └── styles.xml
│               └── values-v21/
│                   └── styles.xml
├── demo-playground/
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── google/
│       │               └── android/
│       │                   └── apps/
│       │                       └── flexbox/
│       │                           └── test/
│       │                               └── MainActivityTest.kt
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── google/
│           │           └── android/
│           │               └── flexbox/
│           │                   ├── Extensions.kt
│           │                   ├── FlexItemAdapter.kt
│           │                   ├── FlexItemChangedListener.kt
│           │                   ├── FlexItemChangedListenerImpl.kt
│           │                   ├── FlexItemChangedListenerImplRecyclerView.kt
│           │                   ├── FlexItemClickListener.kt
│           │                   ├── FlexItemEditFragment.kt
│           │                   ├── FlexItemViewHolder.kt
│           │                   ├── FlexboxLayoutFragment.kt
│           │                   ├── FragmentHelper.kt
│           │                   ├── MainActivity.kt
│           │                   ├── RecyclerViewFragment.kt
│           │                   ├── SettingsActivity.kt
│           │                   └── validators/
│           │                       ├── DimensionInputValidator.kt
│           │                       ├── FixedDimensionInputValidator.kt
│           │                       ├── FlexBasisPercentInputValidator.kt
│           │                       ├── InputValidator.kt
│           │                       ├── IntegerInputValidator.kt
│           │                       └── NonNegativeDecimalInputValidator.kt
│           └── res/
│               ├── drawable/
│               │   ├── flex_item_background.xml
│               │   └── side_nav_bar.xml
│               ├── layout/
│               │   ├── activity_main.xml
│               │   ├── app_bar_main.xml
│               │   ├── content_main.xml
│               │   ├── fragment_flex_item_edit.xml
│               │   ├── fragment_flexboxlayout.xml
│               │   ├── fragment_recyclerview.xml
│               │   ├── nav_header_main.xml
│               │   ├── spinner_align_content.xml
│               │   ├── spinner_align_items.xml
│               │   ├── spinner_flex_direction.xml
│               │   ├── spinner_flex_wrap.xml
│               │   ├── spinner_item.xml
│               │   ├── spinner_justify_content.xml
│               │   └── viewholder_flex_item.xml
│               ├── menu/
│               │   ├── activity_main_drawer.xml
│               │   └── menu_main.xml
│               ├── values/
│               │   ├── colors.xml
│               │   ├── dimens.xml
│               │   ├── strings.xml
│               │   └── styles.xml
│               ├── values-v14/
│               │   └── styles.xml
│               ├── values-v21/
│               │   └── styles.xml
│               ├── values-w720dp/
│               │   └── dimens.xml
│               └── xml/
│                   └── new_flex_item_preferences.xml
├── flexbox/
│   ├── .gitignore
│   ├── build.gradle
│   ├── constants.gradle
│   ├── maven-puglisher-plugin.gradle
│   ├── proguard-rules.txt
│   └── src/
│       ├── androidTest/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── google/
│       │   │           └── android/
│       │   │               └── flexbox/
│       │   │                   ├── FakeFlexContainer.kt
│       │   │                   ├── FlexboxHelperTest.kt
│       │   │                   └── test/
│       │   │                       ├── ConfigChangeActivity.kt
│       │   │                       ├── FlexboxAndroidTest.kt
│       │   │                       ├── FlexboxLayoutManagerConfigChangeTest.kt
│       │   │                       ├── FlexboxLayoutManagerTest.kt
│       │   │                       ├── FlexboxTestActivity.kt
│       │   │                       ├── IsEqualAllowingError.kt
│       │   │                       ├── NestedInnerAdapter.kt
│       │   │                       ├── NestedOuterAdapter.kt
│       │   │                       ├── TestAdapter.kt
│       │   │                       ├── TestAdapterMultiViewTypes.kt
│       │   │                       ├── TestUtil.kt
│       │   │                       └── TestViewHolder.kt
│       │   └── res/
│       │       ├── drawable/
│       │       │   ├── divider.xml
│       │       │   ├── divider_thick.xml
│       │       │   └── flex_item_background.xml
│       │       ├── layout/
│       │       │   ├── activity_align_content_test.xml
│       │       │   ├── activity_align_content_test_overflowed.xml
│       │       │   ├── activity_align_items_baseline_test.xml
│       │       │   ├── activity_align_items_baseline_wrap_content.xml
│       │       │   ├── activity_align_items_parent_padding_test.xml
│       │       │   ├── activity_align_items_test.xml
│       │       │   ├── activity_align_self_stretch_test.xml
│       │       │   ├── activity_child_needs_remeasure_column.xml
│       │       │   ├── activity_child_needs_remeasure_row.xml
│       │       │   ├── activity_direction_column_align_items_center_margin_oneside.xml
│       │       │   ├── activity_direction_row_align_items_center_margin_oneside.xml
│       │       │   ├── activity_divider_test_direction_column.xml
│       │       │   ├── activity_divider_test_direction_row.xml
│       │       │   ├── activity_empty_children.xml
│       │       │   ├── activity_first_item_large_horizontal_test.xml
│       │       │   ├── activity_first_item_large_vertical_test.xml
│       │       │   ├── activity_first_view_gone_first_line_single_item.xml
│       │       │   ├── activity_first_view_gone_layout_grow_set_for_rest.xml
│       │       │   ├── activity_first_view_gone_layout_shrink_set_for_rest.xml
│       │       │   ├── activity_flex_basis_percent_test.xml
│       │       │   ├── activity_flex_grow_test.xml
│       │       │   ├── activity_flex_item_match_parent.xml
│       │       │   ├── activity_flex_item_match_parent_direction_column.xml
│       │       │   ├── activity_flex_wrap_test.xml
│       │       │   ├── activity_flexbox_wrap_content.xml
│       │       │   ├── activity_flexbox_wrapped_with_horizontalscrollview.xml
│       │       │   ├── activity_flexbox_wrapped_with_scrollview.xml
│       │       │   ├── activity_justify_content_test.xml
│       │       │   ├── activity_justify_content_with_gone.xml
│       │       │   ├── activity_justify_content_with_parent_padding.xml
│       │       │   ├── activity_maxheight_test.xml
│       │       │   ├── activity_maxheight_upper_bound_test.xml
│       │       │   ├── activity_maxwidth_test.xml
│       │       │   ├── activity_maxwidth_upper_bound_test.xml
│       │       │   ├── activity_minheight_lower_bound_test.xml
│       │       │   ├── activity_minheight_test.xml
│       │       │   ├── activity_minwidth_lower_bound_test.xml
│       │       │   ├── activity_minwidth_test.xml
│       │       │   ├── activity_order_test.xml
│       │       │   ├── activity_simple.xml
│       │       │   ├── activity_stretch_test.xml
│       │       │   ├── activity_views_visibility_gone.xml
│       │       │   ├── activity_views_visibility_invisible.xml
│       │       │   ├── activity_visibility_gone_first_item_in_flex_line_column.xml
│       │       │   ├── activity_visibility_gone_first_item_in_flex_line_row.xml
│       │       │   ├── activity_wrap_before_test.xml
│       │       │   ├── activity_wrap_child_margin_horizontal_test.xml
│       │       │   ├── activity_wrap_child_margin_vertical_test.xml
│       │       │   ├── activity_wrap_content_child_bottom_margin_column_grow.xml
│       │       │   ├── activity_wrap_content_child_bottom_margin_column_shrink.xml
│       │       │   ├── activity_wrap_content_child_bottom_margin_row_grow.xml
│       │       │   ├── activity_wrap_content_child_bottom_margin_row_shrink.xml
│       │       │   ├── activity_wrap_parent_padding_horizontal_test.xml
│       │       │   ├── activity_wrap_parent_padding_vertical_test.xml
│       │       │   ├── activity_zero_height_positive_flexgrow.xml
│       │       │   ├── activity_zero_width_positive_flexgrow.xml
│       │       │   ├── recyclerview.xml
│       │       │   ├── recyclerview_reverse.xml
│       │       │   ├── recyclerview_viewholder.xml
│       │       │   ├── viewholder_inner_recyclerview.xml
│       │       │   ├── viewholder_inner_recyclerview_wrap_horizontally.xml
│       │       │   ├── viewholder_textview.xml
│       │       │   ├── wrapped_recyclerview.xml
│       │       │   └── wrapped_recyclerview_scroll_vertical.xml
│       │       └── values/
│       │           └── strings.xml
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── google/
│           │           └── android/
│           │               └── flexbox/
│           │                   ├── AlignContent.java
│           │                   ├── AlignItems.java
│           │                   ├── AlignSelf.java
│           │                   ├── FlexContainer.java
│           │                   ├── FlexDirection.java
│           │                   ├── FlexItem.java
│           │                   ├── FlexLine.java
│           │                   ├── FlexWrap.java
│           │                   ├── FlexboxHelper.java
│           │                   ├── FlexboxItemDecoration.java
│           │                   ├── FlexboxLayout.java
│           │                   ├── FlexboxLayoutManager.java
│           │                   └── JustifyContent.java
│           └── res/
│               └── values/
│                   └── attrs.xml
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── tool/
    └── codeStyleSettings.xml

================================================
FILE CONTENTS
================================================

================================================
FILE: .circleci/config.yml
================================================
version: 2
jobs:
  build:
    working_directory: ~/code
    docker:
      - image: circleci/android:api-29
    environment:
      JVM_OPTS: -Xmx3200m
      MAX_RETRY: 4
    steps:
      - checkout
      - restore_cache:
          key: jars-{{ checksum "build.gradle" }}-{{ checksum  "flexbox/build.gradle" }}
      - run:
          name: Download Dependencies
          command: ./gradlew androidDependencies
      - run:
          name: Set up gcloud service key
          command: |
            if [ -n "$GCLOUD_SERVICE_KEY" ]; then echo ${GCLOUD_SERVICE_KEY} | base64 --decode > ${HOME}/client-secret.json ;
                gcloud config set project ${GCLOUD_PROJECT} ;
                gcloud auth activate-service-account ${GCLOUD_SERVICE_ACCOUNT} --key-file ${HOME}/client-secret.json ;
            fi
      - save_cache:
          paths:
            - ~/.gradle
          key: jars-{{ checksum "build.gradle" }}-{{ checksum  "flexbox/build.gradle" }}
      - run:
          name: Build apks
          command: ./gradlew build assembleAndroidTest
      - run:
          name: Run Firebase Test Lab
          command: |
            if [ -n "$GCLOUD_SERVICE_KEY" ]; then set +e ;
              counter=0 ;
              result=1 ;
              while [ $result != 0 -a $counter -lt $MAX_RETRY ]; do
                gcloud firebase test android run \
                  --type instrumentation \
                  --app demo-playground/build/outputs/apk/debug/demo-playground-debug.apk \
                  --test flexbox/build/outputs/apk/androidTest/debug/flexbox-debug-androidTest.apk \
                  --device-ids hammerhead,sailfish \
                  --os-version-ids 19,21,23,24,25,26 \
                  --locales en --orientations portrait,landscape \
                  --results-bucket android-devrel-ci-flexbox \
                  --timeout 180s ;
                result=$? ;
                let counter=counter+1 ;
              done
              exit $result ;
            fi


================================================
FILE: .github/issue_template.md
================================================
- [ ] I have searched [existing issues](https://github.com/google/flexbox-layout/issues) and confirmed this is not a duplicate

## Issues and steps to reproduce
*Please replace this with steps to reproduce your issue.*

## Expected behavior
*Please describe what you expected would happen.*

## Version of the flexbox library
*e.g. 0.2.6, 0.3.0-alpha3*

## Link to code
*Please link to the code we can use to reproduce this issue.*
*A complete project we can build/run is preferred, if you can't provide one, please show*
*us relevant code*


================================================
FILE: .github/workflows/gradle-wrapper-validation.yml
================================================
name: "Validate Gradle Wrapper"
on: [push, pull_request]

jobs:
  validation:
    name: "Validation"
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: gradle/wrapper-validation-action@v1


================================================
FILE: .gitignore
================================================
*.iml
.gradle
.idea/
/local.properties
/.idea/workspace.xml
/.idea/libraries
!.idea/codeStyleSettings.xml
.DS_Store
/build
/captures
.vscode/

# Taken from Android.gitignore https://github.com/github/gitignore/blob/master/Android.gitignore
#
# Built application files
*.apk
*.ap_

# Files for the Dalvik VM
*.dex

# Java class files
*.class

# Generated files
bin/
gen/
out/

# Gradle files
.gradle/
build/

# Local configuration file (sdk path, etc)
local.properties

# Proguard folder generated by Eclipse
proguard/

# Log Files
*.log

# Android Studio Navigation editor temp files
.navigation/

# Android Studio captures folder
captures/

# Intellij
*.iml


================================================
FILE: CONTRIBUTING.md
================================================
# How to become a contributor and submit your own code

## Contributor License Agreements

We'd love to accept your sample apps and patches! Before we can take them, we
have to jump a couple of legal hurdles.

Please fill out either the individual or corporate Contributor License Agreement (CLA).

  * If you are an individual writing original source code and you're sure you
    own the intellectual property, then you'll need to sign an [individual CLA]
    (https://cla.developers.google.com).
  * If you work for a company that wants to allow you to contribute your work,
    then you'll need to sign a [corporate CLA]
    (https://cla.developers.google.com).

Follow either of the two links above to access the appropriate CLA and
instructions for how to sign and return it. Once we receive it, we'll be able to
accept your pull requests.

## Contributing A Patch

1. Submit an issue describing your proposed change to the repo in question.
1. The repo owner will respond to your issue promptly.
1. If your proposed change is accepted, and you haven't already done so, sign a
   Contributor License Agreement (see details above).
1. Fork the desired repo, develop and test your code changes.
1. Ensure that your code adheres to the existing style in the sample to which
   you are contributing. Refer to the
   [Android Code Style Guide]
   (https://source.android.com/source/code-style.html) for the
   recommended coding standards for this organization.
1. Ensure that your code has an appropriate set of unit tests which all pass.
1. Submit a pull request.

## Code Style

This repository follows the official Android code style.
When you send a patch, please try to follow that.
Here are the example steps to follow:

1. From Android Studio or IntelliJ IDEA, navigate to "Preferences" -> "Editor" -> "Code Style"
1. Select "Import Scheme" by clicking the gear icon next to the Scheme pull down
1. Choose <root directory of flexbox-layout>/tool/codeStyleSettings.xml
1. Create a new scheme by typing a scheme name in the "To" edit box or apply to the current scheme.


================================================
FILE: LICENSE
================================================

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright 2018 Google LLC

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: README.md
================================================
# FlexboxLayout
[ ![Circle CI](https://circleci.com/gh/google/flexbox-layout.svg?style=shield&circle-token=2a42716dfffab73d73c5ce7ed7b3ee620cfa137b) ](https://circleci.com/gh/google/flexbox-layout/tree/main)

FlexboxLayout is a library project which brings the similar capabilities of
[CSS Flexible Box Layout Module](https://www.w3.org/TR/css-flexbox-1) to Android.

# Installation
Add the following dependency to your `build.gradle` file:

```
dependencies {
    implementation 'com.google.android.flexbox:flexbox:3.0.0'
}
```

**Starting from 3.0.0, the groupId is changed to `com.google.android.flexbox` in preparation to uploading the artifacts to google maven.
You can still download the artifacts from jcenter for the past versions with the prior groupId (`com.google.android`), but migrating the library 3.0.0 is recommended.**

Note that the default values for `alignItems` and `alignContent` for `FlexboxLayout` have been changed from `stretch` to `flex_start` starting from 2.0.0, it may break the existing apps.
Please make sure to set `stretch` explicitly if you want to apply the behavior of `stretch`.


Note that starting from 1.1.0, the library is expeced to use with AndroidX. Please migrate to [AndroidX](https://developer.android.com/jetpack/androidx/migrate) if you use 1.1.0 or above.

Please use 1.0.0 if you haven't migrated to AndroidX.


# Usage
There are two ways of using Flexbox in your layout.

## FlexboxLayout
The first one is `FlexboxLayout` that extends the `ViewGroup` like `LinearLayout` and `RelativeLayout`.
You can specify the attributes from a layout XML like:
```xml
<com.google.android.flexbox.FlexboxLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:flexWrap="wrap"
    app:alignItems="stretch"
    app:alignContent="stretch" >

    <TextView
        android:id="@+id/textview1"
        android:layout_width="120dp"
        android:layout_height="80dp"
        app:layout_flexBasisPercent="50%"
        />

    <TextView
        android:id="@+id/textview2"
        android:layout_width="80dp"
        android:layout_height="80dp"
        app:layout_alignSelf="center"
        />

    <TextView
        android:id="@+id/textview3"
        android:layout_width="160dp"
        android:layout_height="80dp"
        app:layout_alignSelf="flex_end"
        />
</com.google.android.flexbox.FlexboxLayout>
```

Or from code like:
```java
FlexboxLayout flexboxLayout = (FlexboxLayout) findViewById(R.id.flexbox_layout);
flexboxLayout.setFlexDirection(FlexDirection.ROW);

View view = flexboxLayout.getChildAt(0);
FlexboxLayout.LayoutParams lp = (FlexboxLayout.LayoutParams) view.getLayoutParams();
lp.setOrder(-1);
lp.setFlexGrow(2);
view.setLayoutParams(lp);
```

## FlexboxLayoutManager (within RecyclerView)
The second one is `FlexboxLayoutManager` that can be used within `RecyclerView`.

```java
RecyclerView recyclerView = (RecyclerView) context.findViewById(R.id.recyclerview);
FlexboxLayoutManager layoutManager = new FlexboxLayoutManager(context);
layoutManager.setFlexDirection(FlexDirection.COLUMN);
layoutManager.setJustifyContent(JustifyContent.FLEX_END);
recyclerView.setLayoutManager(layoutManager);
```

or for the attributes for the children of the `FlexboxLayoutManager` you can do like:

```java
mImageView.setImageDrawable(drawable);
ViewGroup.LayoutParams lp = mImageView.getLayoutParams();
if (lp instanceof FlexboxLayoutManager.LayoutParams) {
    FlexboxLayoutManager.LayoutParams flexboxLp = (FlexboxLayoutManager.LayoutParams) lp;
    flexboxLp.setFlexGrow(1.0f);
    flexboxLp.setAlignSelf(AlignSelf.FLEX_END);
}
```

The advantage of using `FlexboxLayoutManager` is that it recycles the views that go off the screen
for reuse for the views that are appearing as the user scrolls instead of inflating every individual view,
which consumes much less memory especially when the number of items contained in the Flexbox container is large.

![FlexboxLayoutManager in action](/assets/flexbox-layoutmanager.gif)


## Supported attributes/features comparison
Due to some characteristics of `RecyclerView`, some Flexbox attributes are not available/not implemented
to the `FlexboxLayoutManager`.
Here is a quick overview of the attributes/features comparison between the two implementations.

|Attribute / Feature|FlexboxLayout| FlexboxLayoutManager (RecyclerView)|
| ------- |:-----------:|:----------------------------------:|
|flexDirection|![Check](/assets/pngs/check_green_small.png)|![Check](/assets/pngs/check_green_small.png)|
|flexWrap|![Check](/assets/pngs/check_green_small.png)|![Check](/assets/pngs/check_green_small.png) (except `wrap_reverse`)|
|justifyContent|![Check](/assets/pngs/check_green_small.png)|![Check](/assets/pngs/check_green_small.png)|
|alignItems|![Check](/assets/pngs/check_green_small.png)|![Check](/assets/pngs/check_green_small.png)|
|alignContent|![Check](/assets/pngs/check_green_small.png)| - |
|layout_order|![Check](/assets/pngs/check_green_small.png)| - |
|layout_flexGrow|![Check](/assets/pngs/check_green_small.png)|![Check](/assets/pngs/check_green_small.png)|
|layout_flexShrink|![Check](/assets/pngs/check_green_small.png)|![Check](/assets/pngs/check_green_small.png)|
|layout_alignSelf|![Check](/assets/pngs/check_green_small.png)|![Check](/assets/pngs/check_green_small.png)|
|layout_flexBasisPercent|![Check](/assets/pngs/check_green_small.png)|![Check](/assets/pngs/check_green_small.png)|
|layout_(min/max)Width|![Check](/assets/pngs/check_green_small.png)|![Check](/assets/pngs/check_green_small.png)|
|layout_(min/max)Height|![Check](/assets/pngs/check_green_small.png)|![Check](/assets/pngs/check_green_small.png)|
|layout_wrapBefore|![Check](/assets/pngs/check_green_small.png)|![Check](/assets/pngs/check_green_small.png)|
|Divider|![Check](/assets/pngs/check_green_small.png)|![Check](/assets/pngs/check_green_small.png)|
|View recycling| - |![Check](/assets/pngs/check_green_small.png)|
|Scrolling| *1 |![Check](/assets/pngs/check_green_small.png)|

*1 Partially possible by wrapping it with `ScrollView`. But it isn't likely to work with a large set
   of views inside the layout. Because it doesn't consider view recycling.

# Supported attributes

## Attributes for the FlexboxLayout:

* __flexDirection__
  * This attribute determines the direction of the main axis (and the cross axis, perpendicular to the main axis). The direction children items are placed inside the Flexbox layout.
  Possible values are:
    * row (default)
    * row_reverse
    * column
    * column_reverse

    ![Flex Direction explanation](/assets/flex-direction.gif)

* __flexWrap__
  * This attribute controls whether the flex container is single-line or multi-line, and the
  direction of the cross axis. Possible values are:
    * nowrap (default for FlexboxLayout)
    * wrap (default for FlexboxLayoutManager)
    * wrap_reverse (not supported by FlexboxLayoutManager)

    ![Flex Wrap explanation](/assets/flex-wrap.gif)

* __justifyContent__
  * This attribute controls the alignment along the main axis. Possible values are:
    * flex_start (default)
    * flex_end
    * center
    * space_between
    * space_around
    * space_evenly

    ![Justify Content explanation](/assets/justify-content.gif)

* __alignItems__
  * This attribute controls the alignment along the cross axis. Possible values are:
    * flex_start (default for FlexboxLayout)
    * flex_end
    * center
    * baseline
    * stretch (default for FlexboxLayoutManager)

    ![Align Items explanation](/assets/align-items.gif)

* __alignContent__
  * This attribute controls the alignment of the flex lines in the flex container. Possible values
  are:
    * flex_start (default)
    * flex_end
    * center
    * space_between
    * space_around
    * stretch

    ![Align Content explanation](/assets/align-content.gif)

* __showDividerHorizontal__ (one or more of `none | beginning | middle | end`)
* __dividerDrawableHorizontal__ (reference to a drawable)
  * Puts horizontal dividers between flex lines (or flex items when flexDirection
  is set to `column` or `column_rebase`).
  
* __showDividerVertical__ (one or more of `none | beginning | middle | end`)
* __dividerDrawableVertical__ (reference to a drawable)
  * Puts vertical dividers between flex items (or flex lines when flexDirection
  is set to `column` or `column_rebase`).

* __showDivider__ (one or more of `none | beginning | middle | end`)
* __dividerDrawable__ (reference to a drawable)
  * Shorthand for setting both horizontal and vertical dividers. Note that if used with other attributes
  (such as `justifyContent="space_around"` or `alignContent="space_between"` ... etc) for putting 
  spaces between flex lines or flex items, you may see unexpected spaces. Please avoid using these
  at the same time.
  
  Example of putting both vertical and horizontal dividers.
  
  `res/drawable/divider.xml`
  ```xml
  <shape xmlns:android="http://schemas.android.com/apk/res/android">
    <size
        android:width="8dp"
        android:height="12dp" />
    <solid android:color="#44A444" />
  </shape> 
  ```
  
  `res/layout/content_main.xml`
  ```xml
  <com.google.android.flexbox.FlexboxLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:alignContent="flex_start"
    app:alignItems="flex_start"
    app:flexWrap="wrap"
    app:showDivider="beginning|middle"
    app:dividerDrawable="@drawable/divider" >

    <TextView
        style="@style/FlexItem"
        android:layout_width="220dp"
        android:layout_height="80dp"
        android:text="1" />
    <TextView
        style="@style/FlexItem"
        android:layout_width="120dp"
        android:layout_height="80dp"
        android:text="2" />
    <TextView
        style="@style/FlexItem"
        android:layout_width="160dp"
        android:layout_height="80dp"
        android:text="3" />
    <TextView
        style="@style/FlexItem"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:text="4" />
    <TextView
        style="@style/FlexItem"
        android:layout_width="100dp"
        android:layout_height="80dp"
        android:text="5" />
  ```
  
  ![Dividers beginning and middle](/assets/divider-beginning-middle.png)


## Attributes for the children of a FlexboxLayout

* __layout_order__ (integer)
  * This attribute can change how the ordering of the children views are laid out.
  By default, children are displayed and laid out in the same order as they appear in the
  layout XML. If not specified, `1` is set as a default value.

    ![Order explanation](/assets/layout_order.gif)

* __layout_flexGrow__ (float)
  * This attribute determines how much this child will grow if positive free space is
  distributed relative to the rest of other flex items included in the same flex line.
  If a flex item has a positive `layout_flexGrow` value, the item will take up the remaining
  space in the flex line. If multiple flex items in the same flex line have positive `layout_flexGrow`
  values, the remaining free space is distributed depending on the proportion of their declared
  `layout_flexGrow` value. (Similar to the `layout_weight` attribute in the `LinearLayout`)
  If not specified, `0` is set as a default value.

    ![Flex Grow explanation](/assets/layout_flexGrow.gif)

* __layout_flexShrink__ (float)
  * This attribute determines how much this child will shrink if negative free space is
  distributed relative to the rest of other flex items included in the same flex line.
  If not specified, `1` is set as a default value.

    ![Flex Shrink explanation](/assets/layout_flexShrink.gif)

* __layout_alignSelf__
  * This attribute determines the alignment along the cross axis (perpendicular to the
  main axis). The alignment in the same direction can be determined by the
  `alignItems` in the parent, but if this is set to other than
  `auto`, the cross axis alignment is overridden for this child. Possible values are:
    * auto (default)
    * flex_start
    * flex_end
    * center
    * baseline
    * stretch

    ![Align Self explanation](/assets/layout_alignSelf.gif)

* __layout_flexBasisPercent__ (fraction)
  * The initial flex item length in a fraction format relative to its parent.
  The initial main size of this child view is trying to be expanded as the specified
  fraction against the parent main size.
  If this value is set, the length specified from `layout_width`
  (or `layout_height`) is overridden by the calculated value from this attribute.
  This attribute is only effective when the parent's length is definite (MeasureSpec mode is
  `MeasureSpec.EXACTLY`). The default value is `-1`, which means not set.

    ![Flex basis percent explanation](/assets/layout_flexBasisPercent.gif)

* __layout_minWidth__ / __layout_minHeight__ (dimension)
  * These attributes impose minimum size constraints for the children of FlexboxLayout.
  A child view won't shrink less than the value of these attributes (varies based on the
  `flexDirection` attribute as to which attribute imposes the size constraint along the
  main axis) regardless of the `layout_flexShrink` attribute.

    ![Min width explanation](/assets/layout_minWidth.gif)

* __layout_maxWidth__ / __layout_maxHeight__ (dimension)
  * These attributes impose maximum size constraints for the children of FlexboxLayout.
  A child view won't be expanded more than the value of these attributes (varies based on the
  `flexDirection` attribute as to which attribute imposes the size constraint along the
  main axis) regardless of the `layout_flexGrow` attribute.

    ![Max width explanation](/assets/layout_maxWidth.gif)

* __layout_wrapBefore__ (boolean)
  * This attribute forces a flex line wrapping, the default value is `false`.
  i.e. if this is set to `true` for a
  flex item, the item will become the first item of a flex line. (A wrapping happens
  regardless of the flex items being processed in the previous flex line)
  This attribute is ignored if the `flex_wrap` attribute is set to `nowrap`.
  The equivalent attribute isn't defined in the original CSS Flexible Box Module
  specification, but having this attribute is useful for Android developers. For example, to flatten
  the layouts when building a grid-like layout or for a situation where developers want
  to put a new flex line to make a semantic difference from the previous one, etc.

    ![Wrap before explanation](/assets/layout_wrapBefore.gif)

# Others

## Known differences from the original CSS specification
This library tries to achieve the same capabilities of the original
[Flexible Box specification](https://www.w3.org/TR/css-flexbox-1) as much as possible,
but due to some reasons such as the way specifying attributes can't be the same between
CSS and Android XML, there are some known differences from the original specification.

(1) There is no [flex-flow](https://www.w3.org/TR/css-flexbox-1/#flex-flow-property)
equivalent attribute
  * Because `flex-flow` is a shorthand for setting the `flex-direction` and `flex-wrap` properties,
  specifying two attributes from a single attribute is not practical in Android.

(2) There is no [flex](https://www.w3.org/TR/css-flexbox-1/#flex-property) equivalent attribute
  * Likewise `flex` is a shorthand for setting the `flex-grow`, `flex-shrink` and `flex-basis`,
  specifying those attributes from a single attribute is not practical.

(3) `layout_flexBasisPercent` is introduced instead of
  [flexBasis](https://www.w3.org/TR/css-flexbox-1/#flex-basis-property)
  * Both `layout_flexBasisPercent` in this library and `flex-basis` property in the CSS are used to
  determine the initial length of an individual flex item. The `flex-basis` property accepts width
  values such as `1em`, `10px`, and `content` as strings as well as percentage values such as
  `10%` and `30%`. `layout_flexBasisPercent` only accepts percentage values.
  However, specifying initial fixed width values can be done by specifying width (or height) values in
  layout_width (or layout_height, varies depending on the `flexDirection`). Also, the same
  effect can be done by specifying "wrap_content" in layout_width (or layout_height) if
  developers want to achieve the same effect as 'content'. Thus, `layout_flexBasisPercent` only
  accepts percentage values, which can't be done through layout_width (or layout_height) for
  simplicity.

(4) `layout_wrapBefore` is introduced.
  * The equivalent attribute doesn't exist in the CSS Flexible Box Module specification,
  but as explained above, Android developers will benefit by having this attribute for having
  more control over when a wrapping happens.

(5) Default values for `alignItems` and `alignContent` are set to `flex_start` instead of `stretch`.
  * Setting `stretch` for the `alignItems` is expensive because the children of `FlexboxLayout` are measured more than twice. The difference is more obvious when the layout hierarchy is deeply nested.

## Xamarin Binding
Xamarin binding is now available on [NuGet](https://www.nuget.org/packages/FlexboxLayoutXamarinBindingAndroid/) thanks to [@btripp](https://github.com/btripp)

## Demo apps
### Flexbox Playground demo app
The `demo-playground` module works as a playground demo app for trying various values for the supported attributes.
You can install it by
```
./gradlew demo-playground:installDebug
```

### Cat gallery demo app
The `demo-cat-gallery` module showcases the usage of the FlexboxLayoutManager inside the RecyclerView
that handles various sizes of views aligned nicely regardless of the device width like the
Google Photo app without loading all the images on the memory.
Thus compared to using the {@link FlexboxLayout}, it's much less likely to abuse the memory,
which sometimes leads to the OutOfMemoryError.
```
./gradlew demo-cat-gallery:installDebug
```

## How to make contributions
Please read and follow the steps in [CONTRIBUTING.md](/CONTRIBUTING.md)

## License
Please see [LICENSE](/LICENSE)


================================================
FILE: build.gradle
================================================
/*
 * Copyright 2016 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    ext {
        minSdkVersion = 14
        targetSdkVersion = 30
        compileSdkVersion = 30

        androidGradlePluginVersion = "4.2.0"
        androidxAnnotationVersion = "1.2.0"
        androidxAppCompatVersion = "1.2.0"
        androidxCoreVersion = "1.3.2"
        androidxPreferenceVersion = "1.1.1"
        androidxRecyclerViewVersion = "1.2.0"
        androidxEspressoVersion = "3.3.0"
        androidxTestExtVersion = "1.1.2"
        androidxTestVersion = "1.3.0"
        junitVersion = "4.13.2"
        kotlinVersion = "1.4.32"
        materialVersion = "1.3.0"
    }

    repositories {
        jcenter()
        google()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:$androidGradlePluginVersion"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
        google()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

// This allows to disable pre dexing. If not disabled, it makes each CI build slow
// See https://circleci.com/docs/android/#disable-pre-dexing-to-improve-build-performance
//     http://tools.android.com/tech-docs/new-build-system/tips#TOC-Improving-Build-Server-performance
project.ext.preDexLibs = !project.hasProperty('disablePreDex')

subprojects {
    project.plugins.whenPluginAdded { plugin ->
        if ("com.android.build.gradle.AppPlugin" == plugin.class.name) {
            project.android.dexOptions.preDexLibraries = rootProject.ext.preDexLibs
        } else if ("com.android.build.gradle.LibraryPlugin" == plugin.class.name) {
            project.android.dexOptions.preDexLibraries = rootProject.ext.preDexLibs
        }
    }
}


================================================
FILE: demo-cat-gallery/build.gradle
================================================
/*
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'

android {
    compileSdkVersion rootProject.ext.compileSdkVersion

    defaultConfig {
        applicationId "com.google.android.flexbox.apps.catgallery"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            shrinkResources true
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation project(path: ":flexbox")
    implementation "androidx.appcompat:appcompat:${rootProject.androidxAppCompatVersion}"
    implementation "androidx.recyclerview:recyclerview:${rootProject.androidxRecyclerViewVersion}"
    implementation "com.google.android.material:material:${rootProject.materialVersion}"
    implementation "org.jetbrains.kotlin:kotlin-stdlib:${rootProject.kotlinVersion}"
}


================================================
FILE: demo-cat-gallery/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /usr/local/google/home/thagikura/android-sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}


================================================
FILE: demo-cat-gallery/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.google.android.flexbox.apps.catgallery">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>

================================================
FILE: demo-cat-gallery/src/main/java/com/google/android/flexbox/apps/catgallery/CatAdapter.kt
================================================
/*
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.flexbox.apps.catgallery

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView

/**
 * Adapter class that handles the data set with the {@link RecyclerView.LayoutManager}
 */
internal class CatAdapter : RecyclerView.Adapter<CatViewHolder>() {

    companion object {
        private val CAT_IMAGE_IDS = intArrayOf(
                R.drawable.cat_1,
                R.drawable.cat_2,
                R.drawable.cat_3,
                R.drawable.cat_4,
                R.drawable.cat_5,
                R.drawable.cat_6,
                R.drawable.cat_7,
                R.drawable.cat_8,
                R.drawable.cat_9,
                R.drawable.cat_10,
                R.drawable.cat_11,
                R.drawable.cat_12,
                R.drawable.cat_13,
                R.drawable.cat_14,
                R.drawable.cat_15,
                R.drawable.cat_16,
                R.drawable.cat_17,
                R.drawable.cat_18,
                R.drawable.cat_19
        )
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CatViewHolder {
        val view = LayoutInflater.from(parent.context)
                .inflate(R.layout.viewholder_cat, parent, false)
        return CatViewHolder(view)
    }

    override fun onBindViewHolder(holder: CatViewHolder, position: Int) {
        val pos = position % CAT_IMAGE_IDS.size
        holder.bindTo(CAT_IMAGE_IDS[pos])
    }

    override fun getItemCount() = CAT_IMAGE_IDS.size * 4
}


================================================
FILE: demo-cat-gallery/src/main/java/com/google/android/flexbox/apps/catgallery/CatViewHolder.kt
================================================
/*
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.flexbox.apps.catgallery

import android.view.View
import android.widget.ImageView
import androidx.annotation.DrawableRes
import androidx.recyclerview.widget.RecyclerView
import com.google.android.flexbox.FlexboxLayoutManager

/**
 * ViewHolder that represents a cat image.
 */
internal class CatViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

    private val imageView: ImageView = itemView.findViewById(R.id.imageview)

    internal fun bindTo(@DrawableRes drawableRes: Int) {
        imageView.setImageResource(drawableRes)
        val lp = imageView.layoutParams
        if (lp is FlexboxLayoutManager.LayoutParams) {
            lp.flexGrow = 1f
        }
    }
}


================================================
FILE: demo-cat-gallery/src/main/java/com/google/android/flexbox/apps/catgallery/MainActivity.kt
================================================
/*
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.flexbox.apps.catgallery

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.recyclerview.widget.RecyclerView
import com.google.android.flexbox.AlignItems
import com.google.android.flexbox.FlexDirection
import com.google.android.flexbox.FlexWrap
import com.google.android.flexbox.FlexboxLayoutManager

/**
 * Launcher Activity for the cat gallery demo app that demonstrates the usage of the
 * {@link FlexboxLayoutManager} that handles various sizes of views aligned nicely regardless of
 * the device width like the Google Photo app without loading all the images on the memory.
 * Thus compared to using the {@link FlexboxLayout}, it's much less likely to abuse the memory,
 * which some times leads to the OutOfMemoryError.
 */
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val toolbar: Toolbar = findViewById(R.id.toolbar)
        setSupportActionBar(toolbar)

        val flexboxLayoutManager = FlexboxLayoutManager(this).apply {
            flexWrap = FlexWrap.WRAP
            flexDirection = FlexDirection.ROW
            alignItems = AlignItems.STRETCH
        }

        val recyclerView: RecyclerView = findViewById(R.id.recyclerview)
        recyclerView.apply {
            layoutManager = flexboxLayoutManager
            adapter = CatAdapter()
        }
    }
}


================================================
FILE: demo-cat-gallery/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2017 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<androidx.coordinatorlayout.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/coordinator_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.google.android.flexbox.apps.catgallery.MainActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/app_bar_height"
        android:fitsSystemWindows="true"
        android:theme="@style/AppTheme.AppBarOverlay">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlwaysCollapsed">

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/AppTheme.PopupOverlay"/>

        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>

    <include layout="@layout/content_main"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>


================================================
FILE: demo-cat-gallery/src/main/res/layout/content_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2017 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<androidx.recyclerview.widget.RecyclerView
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    android:id="@+id/recyclerview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>


================================================
FILE: demo-cat-gallery/src/main/res/layout/viewholder_cat.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2017 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<ImageView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/imageview"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:scaleType="centerCrop"
    android:layout_margin="1dp"
    android:contentDescription="@string/content_description_cat_view_holder"/>


================================================
FILE: demo-cat-gallery/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2017 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
</resources>


================================================
FILE: demo-cat-gallery/src/main/res/values/dimens.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2017 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
    <dimen name="app_bar_height">180dp</dimen>
</resources>


================================================
FILE: demo-cat-gallery/src/main/res/values/strings.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2017 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
    <string name="app_name">Cat Gallery</string>
    <string name="content_description_cat_view_holder">Cat image</string>
</resources>


================================================
FILE: demo-cat-gallery/src/main/res/values/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2017 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>
    <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/>
    <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/>

</resources>


================================================
FILE: demo-cat-gallery/src/main/res/values-v21/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2017 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="android:statusBarColor">@android:color/transparent</item>
    </style>
</resources>


================================================
FILE: demo-playground/build.gradle
================================================
/*
 * Copyright 2016 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'

android {
    compileSdkVersion rootProject.ext.compileSdkVersion

    defaultConfig {
        applicationId "com.google.android.apps.flexbox"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            shrinkResources true
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation project(":flexbox")
    implementation "androidx.annotation:annotation:${rootProject.androidxAnnotationVersion}"
    implementation "androidx.appcompat:appcompat:${rootProject.androidxAppCompatVersion}"
    implementation "androidx.preference:preference:${rootProject.androidxPreferenceVersion}"
    implementation "com.google.android.material:material:${rootProject.materialVersion}"
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"

    testImplementation "junit:junit:${rootProject.ext.junitVersion}"

    androidTestImplementation "androidx.annotation:annotation:${rootProject.androidxAnnotationVersion}"
    androidTestImplementation "androidx.test:runner:${rootProject.androidxTestVersion}"
    androidTestImplementation "androidx.test:rules:${rootProject.androidxTestVersion}"
    androidTestImplementation "androidx.test.espresso:espresso-core:${rootProject.androidxEspressoVersion}"
}


================================================
FILE: demo-playground/proguard-rules.pro
================================================
#
# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}


================================================
FILE: demo-playground/src/androidTest/java/com/google/android/apps/flexbox/test/MainActivityTest.kt
================================================
/*
 * Copyright 2016 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.apps.flexbox.test

import android.content.pm.ActivityInfo
import android.view.View
import android.widget.ArrayAdapter
import android.widget.RadioGroup
import android.widget.Spinner
import android.widget.TextView
import androidx.test.InstrumentationRegistry
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.*
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.filters.FlakyTest
import androidx.test.filters.MediumTest
import androidx.test.rule.ActivityTestRule
import androidx.test.runner.AndroidJUnit4
import com.google.android.apps.flexbox.R
import com.google.android.flexbox.*
import com.google.android.material.navigation.NavigationView
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.core.Is.`is`
import org.junit.Assert.*
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

/**
 * Integration tests for [MainActivity].
 */
@RunWith(AndroidJUnit4::class)
@MediumTest
class MainActivityTest {

    @JvmField
    @Rule
    var activityRule = ActivityTestRule(MainActivity::class.java)

    @Test
    @FlakyTest
    fun testAddFlexItem() {
        val activity = activityRule.activity
        val flexboxLayout = activity.findViewById<FlexboxLayout>(R.id.flexbox_layout)
        assertNotNull(flexboxLayout)
        val beforeCount = flexboxLayout.childCount
        onView(withId(R.id.add_fab)).perform(click())

        assertThat(flexboxLayout.childCount, `is`(beforeCount + 1))
    }

    @Test
    @FlakyTest
    fun testRemoveFlexItem() {
        val activity = activityRule.activity
        val flexboxLayout = activity.findViewById<FlexboxLayout>(R.id.flexbox_layout)
        assertNotNull(flexboxLayout)
        val beforeCount = flexboxLayout.childCount
        onView(withId(R.id.remove_fab)).perform(click())

        assertThat(flexboxLayout.childCount, `is`(beforeCount - 1))
    }

    @Test
    @FlakyTest
    fun testConfigurationChange() {
        val activity = activityRule.activity
        val flexboxLayout = activity.findViewById<FlexboxLayout>(R.id.flexbox_layout)
        assertNotNull(flexboxLayout)
        onView(withId(R.id.add_fab)).perform(click())
        onView(withId(R.id.add_fab)).perform(click())
        onView(withId(R.id.add_fab)).perform(click())
        val beforeCount = flexboxLayout.childCount

        activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        // Verify the flex items are restored across the configuration change.
        assertThat(flexboxLayout.childCount, `is`(beforeCount))
    }

    @Test
    @FlakyTest
    fun testFlexDirectionSpinner() {
        val activity = activityRule.activity
        val flexboxLayout = activity.findViewById<FlexboxLayout>(R.id.flexbox_layout)
        assertNotNull(flexboxLayout)
        val navigationView = activity.findViewById<NavigationView>(R.id.nav_view)
        assertNotNull(navigationView)
        val menu = navigationView.menu
        val spinner = menu.findItem(R.id.menu_item_flex_direction).actionView as Spinner
        val spinnerAdapter = spinner.adapter as ArrayAdapter<CharSequence>

        val columnPosition = spinnerAdapter.getPosition(activity.getString(R.string.column))
        activity.runOnUiThread { spinner.setSelection(columnPosition) }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(flexboxLayout.flexDirection, `is`(FlexDirection.COLUMN))

        val rowReversePosition = spinnerAdapter.getPosition(activity.getString(R.string.row_reverse))
        activity.runOnUiThread { spinner.setSelection(rowReversePosition) }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(flexboxLayout.flexDirection, `is`(FlexDirection.ROW_REVERSE))
    }

    @Test
    @FlakyTest
    fun testFlexWrapSpinner() {
        val activity = activityRule.activity
        val flexboxLayout = activity.findViewById<FlexboxLayout>(R.id.flexbox_layout)
        assertNotNull(flexboxLayout)
        val navigationView = activity.findViewById<NavigationView>(R.id.nav_view)
        assertNotNull(navigationView)
        val menu = navigationView.menu
        val spinner = menu.findItem(R.id.menu_item_flex_wrap).actionView as Spinner
        val spinnerAdapter = spinner.adapter as ArrayAdapter<CharSequence>

        val wrapReversePosition = spinnerAdapter.getPosition(activity.getString(R.string.wrap_reverse))
        activity.runOnUiThread { spinner.setSelection(wrapReversePosition) }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(flexboxLayout.flexWrap, `is`(FlexWrap.WRAP_REVERSE))

        val noWrapPosition = spinnerAdapter.getPosition(activity.getString(R.string.nowrap))
        activity.runOnUiThread { spinner.setSelection(noWrapPosition) }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(flexboxLayout.flexWrap, `is`(FlexWrap.NOWRAP))
    }

    @Test
    @FlakyTest
    fun testJustifyContentSpinner() {
        val activity = activityRule.activity
        val flexboxLayout = activity.findViewById<View>(R.id.flexbox_layout) as FlexboxLayout
        assertNotNull(flexboxLayout)
        val navigationView = activity.findViewById<View>(R.id.nav_view) as NavigationView
        assertNotNull(navigationView)
        val menu = navigationView.menu
        val spinner = menu.findItem(R.id.menu_item_justify_content).actionView as Spinner
        val spinnerAdapter = spinner.adapter as ArrayAdapter<CharSequence>

        val spaceBetweenPosition = spinnerAdapter.getPosition(activity.getString(R.string.space_between))
        activity.runOnUiThread { spinner.setSelection(spaceBetweenPosition) }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(flexboxLayout.justifyContent, `is`(JustifyContent.SPACE_BETWEEN))

        val centerPosition = spinnerAdapter.getPosition(activity.getString(R.string.center))
        activity.runOnUiThread { spinner.setSelection(centerPosition) }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(flexboxLayout.justifyContent, `is`(JustifyContent.CENTER))
    }

    @Test
    @FlakyTest
    fun testAlignItemsSpinner() {
        val activity = activityRule.activity
        val flexboxLayout = activity.findViewById<FlexboxLayout>(R.id.flexbox_layout)
        assertNotNull(flexboxLayout)
        val navigationView = activity.findViewById<NavigationView>(R.id.nav_view)
        assertNotNull(navigationView)
        val menu = navigationView.menu
        val spinner = menu.findItem(R.id.menu_item_align_items).actionView as Spinner
        val spinnerAdapter = spinner.adapter as ArrayAdapter<CharSequence>

        val baselinePosition = spinnerAdapter.getPosition(activity.getString(R.string.baseline))
        activity.runOnUiThread { spinner.setSelection(baselinePosition) }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(flexboxLayout.alignItems, `is`(AlignItems.BASELINE))

        val flexEndPosition = spinnerAdapter.getPosition(activity.getString(R.string.flex_end))
        activity.runOnUiThread { spinner.setSelection(flexEndPosition) }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(flexboxLayout.alignItems, `is`(AlignItems.FLEX_END))
    }

    @Test
    @FlakyTest
    fun testAlignContentSpinner() {
        val activity = activityRule.activity
        val flexboxLayout = activity.findViewById<FlexboxLayout>(R.id.flexbox_layout)
        assertNotNull(flexboxLayout)
        val navigationView = activity.findViewById<NavigationView>(R.id.nav_view)
        assertNotNull(navigationView)
        val menu = navigationView.menu
        val spinner = menu.findItem(R.id.menu_item_align_content).actionView as Spinner
        val spinnerAdapter = spinner.adapter as ArrayAdapter<CharSequence>

        val spaceAroundPosition = spinnerAdapter.getPosition(activity.getString(R.string.space_around))
        activity.runOnUiThread { spinner.setSelection(spaceAroundPosition) }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(flexboxLayout.alignContent, `is`(AlignContent.SPACE_AROUND))

        val stretchPosition = spinnerAdapter.getPosition(activity.getString(R.string.stretch))
        activity.runOnUiThread { spinner.setSelection(stretchPosition) }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(flexboxLayout.alignContent, `is`(AlignContent.STRETCH))
    }

    @Test
    @FlakyTest
    fun testEditFragment_changeOrder() {
        val activity = activityRule.activity
        val flexboxLayout = activity.findViewById<View>(R.id.flexbox_layout) as FlexboxLayout
        assertNotNull(flexboxLayout)
        onView(withId(R.id.textview1)).perform(click())
        onView(withId(R.id.edit_text_order)).perform(replaceText("3"), closeSoftKeyboard())
        onView(withId(R.id.button_ok)).perform(click())
        val first = flexboxLayout.getReorderedChildAt(0) as TextView
        val second = flexboxLayout.getReorderedChildAt(1) as TextView
        val third = flexboxLayout.getReorderedChildAt(2) as TextView

        assertThat(first.text.toString(), `is`("2"))
        assertThat(second.text.toString(), `is`("3"))
        assertThat(third.text.toString(), `is`("1"))
    }

    @Test
    @FlakyTest
    fun testEditFragment_changeFlexGrow() {
        val activity = activityRule.activity
        val flexboxLayout = activity.findViewById<View>(R.id.flexbox_layout) as FlexboxLayout
        assertNotNull(flexboxLayout)
        onView(withId(R.id.textview1)).perform(click())
        onView(withId(R.id.edit_text_flex_grow)).perform(replaceText("1"), closeSoftKeyboard())
        onView(withId(R.id.button_ok)).perform(click())
        val first = activity.findViewById<View>(R.id.textview1) as TextView
        val second = activity.findViewById<View>(R.id.textview2) as TextView
        val third = activity.findViewById<View>(R.id.textview3) as TextView
        assertNotNull(first)
        assertNotNull(second)
        assertNotNull(third)

        assertThat(first.width, `is`(flexboxLayout.width - second.width - third.width))
    }

    @Test
    @FlakyTest
    fun testEditFragment_changeFlexGrowFloat() {
        val activity = activityRule.activity
        val flexboxLayout = activity.findViewById<View>(R.id.flexbox_layout) as FlexboxLayout
        assertNotNull(flexboxLayout)
        onView(withId(R.id.textview1)).perform(click())
        onView(withId(R.id.edit_text_flex_grow)).perform(replaceText("1.0"), closeSoftKeyboard())
        onView(withId(R.id.button_ok)).perform(click())
        val first = activity.findViewById<View>(R.id.textview1) as TextView
        val second = activity.findViewById<View>(R.id.textview2) as TextView
        val third = activity.findViewById<View>(R.id.textview3) as TextView
        assertNotNull(first)
        assertNotNull(second)
        assertNotNull(third)

        assertThat(first.width, `is`(flexboxLayout.width - second.width - third.width))
    }

    @Test
    @FlakyTest
    fun testEditFragment_changeFlexBasisPercent() {
        val activity = activityRule.activity
        val flexboxLayout = activity.findViewById<View>(R.id.flexbox_layout) as FlexboxLayout
        assertNotNull(flexboxLayout)
        onView(withId(R.id.textview1)).perform(click())
        onView(withId(R.id.edit_text_flex_basis_percent))
                .perform(replaceText("50"), closeSoftKeyboard())
        onView(withId(R.id.button_ok)).perform(click())
        val first = activity.findViewById<TextView>(R.id.textview1)
        val second = activity.findViewById<TextView>(R.id.textview2)
        val third = activity.findViewById<TextView>(R.id.textview3)
        assertNotNull(first)
        assertNotNull(second)
        assertNotNull(third)

        assertTrue(first.width - 1 <= flexboxLayout.width / 2 || flexboxLayout.width / 2 <= first.width + 1)
    }

    @Test
    @FlakyTest
    fun testSwitchRecyclerViewFragment() {
        val activity = activityRule.activity
        val flexboxLayout = activity.findViewById<FlexboxLayout>(R.id.flexbox_layout)
        assertNotNull(flexboxLayout)
        val navigationView = activity.findViewById<NavigationView>(R.id.nav_view)
        assertNotNull(navigationView)
        assertNull(activity.findViewById(R.id.recyclerview))
        assertNotNull(activity.findViewById(R.id.flexbox_layout))

        val radioGroup = navigationView.getHeaderView(0)
                .findViewById<RadioGroup>(R.id.radiogroup_container_implementation)
        activity.runOnUiThread { radioGroup.check(R.id.radiobutton_recyclerview) }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertNotNull(activity.findViewById(R.id.recyclerview))
        assertNull(activity.findViewById(R.id.flexbox_layout))
    }
}


================================================
FILE: demo-playground/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.google.android.apps.flexbox">

    <uses-sdk tools:overrideLibrary="android.support.v14.preference" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name="com.google.android.flexbox.MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity android:name="com.google.android.flexbox.SettingsActivity" />
    </application>

</manifest>


================================================
FILE: demo-playground/src/main/java/com/google/android/flexbox/Extensions.kt
================================================
/*
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.flexbox

import android.content.Context

/**
 * Convert pixel to dp. Preserve the negative value as it's used for representing
 * MATCH_PARENT(-1) and WRAP_CONTENT(-2).
 * Ignore the round error that might happen in dividing the pixel by the density.
 *
 * @param pixel   the value in pixel
 *
 * @return the converted value in dp
 */
fun Context.pixelToDp(pixel: Int): Int {
    val displayMetrics = this.resources.displayMetrics
    return if (pixel < 0) pixel else Math.round(pixel / displayMetrics.density)
}

/**
 * Convert dp to pixel. Preserve the negative value as it's used for representing
 * MATCH_PARENT(-1) and WRAP_CONTENT(-2).
 *
 * @param dp      the value in dp
 *
 * @return the converted value in pixel
 */
fun Context.dpToPixel(dp: Int): Int {
    val displayMetrics = this.resources.displayMetrics
    return if (dp < 0) dp else Math.round(dp * displayMetrics.density)
}


================================================
FILE: demo-playground/src/main/java/com/google/android/flexbox/FlexItemAdapter.kt
================================================
/*
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.flexbox

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.RecyclerView
import com.google.android.apps.flexbox.R

/**
 * [RecyclerView.Adapter] implementation for [FlexItemViewHolder].
 */
internal class FlexItemAdapter(private val activity: AppCompatActivity,
                               private val flexContainer: FlexContainer)
    : RecyclerView.Adapter<FlexItemViewHolder>() {

    private val layoutParams = mutableListOf<FlexboxLayoutManager.LayoutParams>()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FlexItemViewHolder {
        val view = LayoutInflater.from(parent.context)
                .inflate(R.layout.viewholder_flex_item, parent, false)

        return FlexItemViewHolder(view)
    }

    override fun onBindViewHolder(holder: FlexItemViewHolder, position: Int) {
        val adapterPosition = holder.adapterPosition
        // TODO: More optimized set the click listener inside the view holder
        holder.itemView.setOnClickListener(FlexItemClickListener(activity,
                FlexItemChangedListenerImplRecyclerView(flexContainer, this),
                adapterPosition))
        holder.bindTo(layoutParams[position])
    }

    fun addItem(lp: FlexboxLayoutManager.LayoutParams) {
        layoutParams.add(lp)
        notifyItemInserted(layoutParams.size - 1)
    }

    fun removeItem(position: Int) {
        if (position < 0 || position >= layoutParams.size) {
            return
        }
        layoutParams.removeAt(position)
        notifyItemRemoved(layoutParams.size)
        notifyItemRangeChanged(position, layoutParams.size)
    }

    val items get() = layoutParams

    override fun getItemCount() = layoutParams.size
}


================================================
FILE: demo-playground/src/main/java/com/google/android/flexbox/FlexItemChangedListener.kt
================================================
/*
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.flexbox

/**
 * A listener that listens to the change of a flex item
 */
internal interface FlexItemChangedListener {

    fun onFlexItemChanged(flexItem: FlexItem, viewIndex: Int)
}


================================================
FILE: demo-playground/src/main/java/com/google/android/flexbox/FlexItemChangedListenerImpl.kt
================================================
/*
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.flexbox

import android.view.ViewGroup

/**
 * Default implementation for the [FlexItemChangedListener].
 */
internal class FlexItemChangedListenerImpl(private val flexContainer: FlexContainer) : FlexItemChangedListener {

    override fun onFlexItemChanged(flexItem: FlexItem, viewIndex: Int) {
        val view = flexContainer.getFlexItemAt(viewIndex)
        view.layoutParams = flexItem as ViewGroup.LayoutParams
    }
}


================================================
FILE: demo-playground/src/main/java/com/google/android/flexbox/FlexItemChangedListenerImplRecyclerView.kt
================================================
/*
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.flexbox

import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView

/**
 * Implementation for the [FlexItemChangedListener].
 * It expects RecyclerView as the underlying flex container implementation.
 */
internal class FlexItemChangedListenerImplRecyclerView(private val flexContainer: FlexContainer,
                                              private val adapter: RecyclerView.Adapter<*>) : FlexItemChangedListener {

    override fun onFlexItemChanged(flexItem: FlexItem, viewIndex: Int) {
        val view = flexContainer.getFlexItemAt(viewIndex)
        view.layoutParams = flexItem as ViewGroup.LayoutParams
        adapter.notifyDataSetChanged()
        // TODO: An Exception is thrown if notifyItemChanged(int) is used.
        // Investigate that, but using LinearLayoutManager also produces the same Exception
        // java.lang.IllegalArgumentException: Called attach on a child which is not detached:
    }
}


================================================
FILE: demo-playground/src/main/java/com/google/android/flexbox/FlexItemClickListener.kt
================================================
/*
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.flexbox

import android.view.View
import androidx.appcompat.app.AppCompatActivity

/**
 * Implementation of the [android.view.View.OnClickListener] when a flex item is clicked in
 * the Flexbox Playground demo app.
 */
internal class FlexItemClickListener(private val activity: AppCompatActivity, private val flexItemChangedListener: FlexItemChangedListener,
                                     private val viewIndex: Int) : View.OnClickListener {

    override fun onClick(v: View) =
            FlexItemEditFragment.newInstance(v.layoutParams as FlexItem, viewIndex).apply {
                setFlexItemChangedListener(flexItemChangedListener)
            }.show(activity.supportFragmentManager, EDIT_DIALOG_TAG)

    companion object {

        private const val EDIT_DIALOG_TAG = "edit_dialog_tag"
    }
}


================================================
FILE: demo-playground/src/main/java/com/google/android/flexbox/FlexItemEditFragment.kt
================================================
/*
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.flexbox

import android.content.Context
import android.os.Build
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.*
import androidx.fragment.app.DialogFragment
import com.google.android.apps.flexbox.R
import com.google.android.flexbox.validators.*
import com.google.android.material.textfield.TextInputLayout

/**
 * DialogFragment that changes the properties for a flex item.
 */
internal class FlexItemEditFragment : DialogFragment() {

    private lateinit var alignSelfAuto: String

    private lateinit var alignSelfFlexStart: String

    private lateinit var alignSelfFlexEnd: String

    private lateinit var alignSelfCenter: String

    private lateinit var alignSelfBaseline: String

    private lateinit var alignSelfStretch: String

    private var viewIndex: Int = 0

    private lateinit var flexItem: FlexItem

    /**
     * Instance of a [FlexItem] being edited. At first it's created as another instance from
     * the [flexItem] because otherwise changes before clicking the ok button will be
     * reflected if the [flexItem] is changed directly.
     */
    private lateinit var flexItemInEdit: FlexItem

    private var flexItemChangedListener: FlexItemChangedListener? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            setStyle(STYLE_NORMAL, android.R.style.Theme_Material_Light_Dialog)
        } else {
            setStyle(STYLE_NORMAL, android.R.style.Theme_Dialog)
        }
        arguments?.let {
            flexItem = it.getParcelable(FLEX_ITEM_KEY)!!
            viewIndex = it.getInt(VIEW_INDEX_KEY)
        }
        flexItemInEdit = createNewFlexItem(flexItem)

        activity?.let {
            alignSelfAuto = it.getString(R.string.auto)
            alignSelfFlexStart = it.getString(R.string.flex_start)
            alignSelfFlexEnd = it.getString(R.string.flex_end)
            alignSelfCenter = it.getString(R.string.center)
            alignSelfBaseline = it.getString(R.string.baseline)
            alignSelfStretch = it.getString(R.string.stretch)
        }
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        val view = inflater.inflate(R.layout.fragment_flex_item_edit, container, false)
        dialog?.setTitle((viewIndex + 1).toString())

        val context = activity ?: return view
        val orderTextInput: TextInputLayout = view.findViewById(R.id.input_layout_order)
        val orderEdit: EditText = view.findViewById(R.id.edit_text_order)
        orderEdit.setText(flexItem.order.toString())
        orderEdit.addTextChangedListener(
                FlexEditTextWatcher(context, orderTextInput, IntegerInputValidator(),
                        R.string.must_be_integer))
        if (flexItem is FlexboxLayoutManager.LayoutParams) {
            // Order is not enabled in FlexboxLayoutManager
            orderEdit.isEnabled = false
        }

        val flexGrowInput: TextInputLayout = view .findViewById(R.id.input_layout_flex_grow)
        val flexGrowEdit: EditText = view.findViewById(R.id.edit_text_flex_grow)
        flexGrowEdit.setText(flexItem.flexGrow.toString())
        flexGrowEdit.addTextChangedListener(
                FlexEditTextWatcher(context, flexGrowInput, NonNegativeDecimalInputValidator(),
                        R.string.must_be_non_negative_float))

        val flexShrinkInput: TextInputLayout = view.findViewById(R.id.input_layout_flex_shrink)
        val flexShrinkEdit: EditText = view.findViewById(R.id.edit_text_flex_shrink)
        flexShrinkEdit.setText(flexItem.flexShrink.toString())
        flexShrinkEdit.addTextChangedListener(
                FlexEditTextWatcher(context, flexShrinkInput, NonNegativeDecimalInputValidator(),
                        R.string.must_be_non_negative_float))

        val flexBasisPercentInput: TextInputLayout =
                view.findViewById(R.id.input_layout_flex_basis_percent)
        val flexBasisPercentEdit: EditText = view.findViewById(R.id.edit_text_flex_basis_percent)
        if (flexItem.flexBasisPercent != FlexboxLayout.LayoutParams.FLEX_BASIS_PERCENT_DEFAULT) {
            flexBasisPercentEdit
                    .setText(Math.round(flexItem.flexBasisPercent * 100).toString())
        } else {
            flexBasisPercentEdit.setText(flexItem.flexBasisPercent.toInt().toString())
        }
        flexBasisPercentEdit.addTextChangedListener(
                FlexEditTextWatcher(context, flexBasisPercentInput, FlexBasisPercentInputValidator(),
                        R.string.must_be_minus_one_or_non_negative_integer))

        val widthInput: TextInputLayout = view.findViewById(R.id.input_layout_width)
        val widthEdit: EditText = view.findViewById(R.id.edit_text_width)
        widthEdit.setText(context.pixelToDp(flexItem.width).toString())
        widthEdit.addTextChangedListener(
                FlexEditTextWatcher(context, widthInput, DimensionInputValidator(),
                        R.string.must_be_minus_one_or_minus_two_or_non_negative_integer))

        val heightInput: TextInputLayout = view.findViewById(R.id.input_layout_height)
        val heightEdit: EditText= view.findViewById(R.id.edit_text_height)
        heightEdit.setText(context.pixelToDp(flexItem.height).toString())
        heightEdit.addTextChangedListener(
                FlexEditTextWatcher(context, heightInput, DimensionInputValidator(),
                        R.string.must_be_minus_one_or_minus_two_or_non_negative_integer))

        val minWidthInput: TextInputLayout = view.findViewById(R.id.input_layout_min_width)
        val minWidthEdit: EditText = view.findViewById(R.id.edit_text_min_width)
        minWidthEdit.setText(context.pixelToDp(flexItem.minWidth).toString())
        minWidthEdit.addTextChangedListener(
                FlexEditTextWatcher(context, minWidthInput, FixedDimensionInputValidator(),
                        R.string.must_be_non_negative_integer))

        val minHeightInput: TextInputLayout = view.findViewById(R.id.input_layout_min_height)
        val minHeightEdit: EditText = view.findViewById(R.id.edit_text_min_height)
        minHeightEdit.setText(context.pixelToDp(flexItem.minHeight).toString())
        minHeightEdit.addTextChangedListener(
                FlexEditTextWatcher(context, minHeightInput, FixedDimensionInputValidator(),
                        R.string.must_be_non_negative_integer))

        val maxWidthInput: TextInputLayout = view.findViewById(R.id.input_layout_max_width)
        val maxWidthEdit: EditText = view.findViewById(R.id.edit_text_max_width)
        maxWidthEdit.setText(context.pixelToDp(flexItem.maxWidth).toString())
        maxWidthEdit.addTextChangedListener(
                FlexEditTextWatcher(context, maxWidthInput, FixedDimensionInputValidator(),
                        R.string.must_be_non_negative_integer))

        val maxHeightInput: TextInputLayout = view.findViewById(R.id.input_layout_max_height)
        val maxHeightEdit: EditText = view.findViewById(R.id.edit_text_max_height)
        maxHeightEdit.setText(context.pixelToDp(flexItem.maxHeight).toString())
        maxHeightEdit.addTextChangedListener(
                FlexEditTextWatcher(context, maxHeightInput, FixedDimensionInputValidator(),
                        R.string.must_be_non_negative_integer))

        setNextFocusesOnEnterDown(orderEdit, flexGrowEdit, flexShrinkEdit, flexBasisPercentEdit,
                widthEdit, heightEdit, minWidthEdit, minHeightEdit, maxWidthEdit, maxHeightEdit)

        val alignSelfSpinner: Spinner = view.findViewById(R.id.spinner_align_self)
        val arrayAdapter = ArrayAdapter.createFromResource(requireActivity(),
                R.array.array_align_self, R.layout.spinner_item)
        alignSelfSpinner.adapter = arrayAdapter
        alignSelfSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(parent: AdapterView<*>, ignored: View?, position: Int,
                                        id: Long) {
                flexItemInEdit.alignSelf = when (parent.getItemAtPosition(position).toString()) {
                    alignSelfAuto -> AlignSelf.AUTO
                    alignSelfFlexStart -> AlignItems.FLEX_START
                    alignSelfFlexEnd -> AlignItems.FLEX_END
                    alignSelfCenter -> AlignItems.CENTER
                    alignSelfBaseline -> AlignItems.BASELINE
                    alignSelfStretch -> AlignItems.STRETCH
                    else -> return
                }
            }

            override fun onNothingSelected(parent: AdapterView<*>) {
                // No op
            }
        }

        val wrapBeforeCheckBox: CheckBox = view.findViewById(R.id.checkbox_wrap_before)
        wrapBeforeCheckBox.isChecked = flexItem.isWrapBefore
        wrapBeforeCheckBox.setOnCheckedChangeListener { _, isChecked ->
            flexItemInEdit.isWrapBefore = isChecked }
        val alignSelfPosition = arrayAdapter
                .getPosition(alignSelfAsString(flexItem.alignSelf))
        alignSelfSpinner.setSelection(alignSelfPosition)

        view.findViewById<Button>(R.id.button_cancel).setOnClickListener {
            copyFlexItemValues(flexItem, flexItemInEdit)
            dismiss()
        }
        val okButton: Button = view.findViewById(R.id.button_ok)
        okButton.setOnClickListener(View.OnClickListener {
            if (orderTextInput.isErrorEnabled || flexGrowInput.isErrorEnabled ||
                    flexBasisPercentInput.isErrorEnabled || widthInput.isErrorEnabled ||
                    heightInput.isErrorEnabled || minWidthInput.isErrorEnabled ||
                    minHeightInput.isErrorEnabled || maxWidthInput.isErrorEnabled ||
                    maxHeightInput.isErrorEnabled) {
                Toast.makeText(activity, R.string.invalid_values_exist, Toast.LENGTH_SHORT)
                        .show()
                return@OnClickListener
            }
            if (flexItemChangedListener != null) {
                copyFlexItemValues(flexItemInEdit, flexItem)
                flexItemChangedListener!!.onFlexItemChanged(flexItem, viewIndex)
            }
            dismiss()
        })
        return view
    }

    fun setFlexItemChangedListener(flexItemChangedListener: FlexItemChangedListener) {
        this.flexItemChangedListener = flexItemChangedListener
    }

    private fun setNextFocusesOnEnterDown(vararg textViews: TextView) {
        // This can be done by setting android:nextFocus* as in
        // https://developer.android.com/training/keyboard-input/navigation.html
        // But it requires API level 11 as a minimum sdk version. To support the lower level
        // devices,
        // doing it programmatically.
        for (i in textViews.indices) {
            textViews[i].setOnEditorActionListener { v, actionId, event ->
                if (actionId == EditorInfo.IME_ACTION_NEXT ||
                        actionId == EditorInfo.IME_ACTION_DONE ||
                        actionId == EditorInfo.IME_NULL
                                && event.action == KeyEvent.ACTION_DOWN
                                && event.keyCode == KeyEvent.KEYCODE_ENTER) {
                    if (i + 1 < textViews.size) {
                        textViews[i + 1].requestFocus()
                    } else if (i == textViews.size - 1) {
                        val inputMethodManager = activity?.getSystemService(
                                Context.INPUT_METHOD_SERVICE) as InputMethodManager?
                        inputMethodManager?.hideSoftInputFromWindow(v.windowToken, 0)
                    }
                }
                true
            }

            // Suppress the key focus change by KeyEvent.ACTION_UP of the enter key
            textViews[i].setOnKeyListener { _, keyCode, event -> keyCode == KeyEvent.KEYCODE_ENTER && event.action == KeyEvent.ACTION_UP }
        }

    }

    private fun alignSelfAsString(alignSelf: Int): String {
        return when (alignSelf) {
            AlignSelf.AUTO -> alignSelfAuto
            AlignItems.FLEX_START -> alignSelfFlexStart
            AlignItems.FLEX_END -> alignSelfFlexEnd
            AlignItems.CENTER -> alignSelfCenter
            AlignItems.BASELINE -> alignSelfBaseline
            AlignItems.STRETCH -> alignSelfStretch
            else -> alignSelfAuto
        }
    }

    private inner class FlexEditTextWatcher internal constructor(val context: Context,
                                                                 val textInputLayout: TextInputLayout,
                                                                 val inputValidator: InputValidator,
                                                                 val errorMessageId: Int) : TextWatcher {

        override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
            // No op
        }

        override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
            if (inputValidator.isValidInput(s)) {
                textInputLayout.isErrorEnabled = false
                textInputLayout.error = ""
            } else {
                textInputLayout.isErrorEnabled = true
                textInputLayout.error = activity?.resources?.getString(errorMessageId)
            }
        }

        override fun afterTextChanged(editable: Editable) {
            if (textInputLayout.isErrorEnabled || editable.isEmpty() ||
                    !inputValidator.isValidInput(editable.toString())) {
                return
            }
            val value = editable.toString().toFloatOrNull() ?: return
            when (textInputLayout.id) {
                R.id.input_layout_order -> if (flexItemInEdit !is FlexboxLayoutManager.LayoutParams) {
                    flexItemInEdit.order = value.toInt()
                } else return
                R.id.input_layout_flex_grow -> flexItemInEdit.flexGrow = value
                R.id.input_layout_flex_shrink -> flexItemInEdit.flexShrink = value
                R.id.input_layout_width -> flexItemInEdit.width = context.dpToPixel(value.toInt())
                R.id.input_layout_height -> flexItemInEdit.height = context.dpToPixel(value.toInt())
                R.id.input_layout_flex_basis_percent -> if (value != FlexboxLayout.LayoutParams.FLEX_BASIS_PERCENT_DEFAULT) {
                    flexItemInEdit.flexBasisPercent = value.toInt() / 100.0f
                } else {
                    flexItemInEdit.flexBasisPercent = FlexItem.FLEX_BASIS_PERCENT_DEFAULT
                }
                R.id.input_layout_min_width -> flexItemInEdit.minWidth = context.dpToPixel(value.toInt())
                R.id.input_layout_min_height -> flexItemInEdit.minHeight = context.dpToPixel(value.toInt())
                R.id.input_layout_max_width -> flexItemInEdit.maxWidth = context.dpToPixel(value.toInt())
                R.id.input_layout_max_height -> flexItemInEdit.maxHeight = context.dpToPixel(value.toInt())
                else -> return
            }
        }
    }

    private fun createNewFlexItem(item: FlexItem): FlexItem {
        if (item is FlexboxLayout.LayoutParams) {
            val newItem = FlexboxLayout.LayoutParams(item.getWidth(), item.getHeight())
            copyFlexItemValues(item, newItem)
            return newItem
        } else if (item is FlexboxLayoutManager.LayoutParams) {
            val newItem = FlexboxLayoutManager.LayoutParams(item.getWidth(), item.getHeight())
            copyFlexItemValues(item, newItem)
            return newItem
        }
        throw IllegalArgumentException("Unknown FlexItem: $item")
    }

    private fun copyFlexItemValues(from: FlexItem, to: FlexItem) {
        if (from !is FlexboxLayoutManager.LayoutParams) {
            to.order = from.order
        }
        to.flexGrow = from.flexGrow
        to.flexShrink = from.flexShrink
        to.flexBasisPercent = from.flexBasisPercent
        to.height = from.height
        to.width = from.width
        to.maxHeight = from.maxHeight
        to.minHeight = from.minHeight
        to.maxWidth = from.maxWidth
        to.minWidth = from.minWidth
        to.alignSelf = from.alignSelf
        to.isWrapBefore = from.isWrapBefore
    }

    companion object {

        private const val FLEX_ITEM_KEY = "flex_item"

        private const val VIEW_INDEX_KEY = "view_index"

        fun newInstance(flexItem: FlexItem, viewIndex: Int) = FlexItemEditFragment().apply {
            arguments = Bundle().apply {
                putParcelable(FLEX_ITEM_KEY, flexItem)
                putInt(VIEW_INDEX_KEY, viewIndex)
            }
        }
    }
}


================================================
FILE: demo-playground/src/main/java/com/google/android/flexbox/FlexItemViewHolder.kt
================================================
/*
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.flexbox

import android.view.Gravity
import android.view.View
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.google.android.apps.flexbox.R

/**
 * ViewHolder implementation for a flex item.
 */
class FlexItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

    private val textView: TextView = itemView.findViewById(R.id.textview)

    fun bindTo(params: RecyclerView.LayoutParams) {
        val adapterPosition = adapterPosition
        textView.apply {
            text = (adapterPosition + 1).toString()
            setBackgroundResource(R.drawable.flex_item_background)
            gravity = Gravity.CENTER
            layoutParams = params
        }
    }
}


================================================
FILE: demo-playground/src/main/java/com/google/android/flexbox/FlexboxLayoutFragment.kt
================================================
/*
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.flexbox

import android.content.Context
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import com.google.android.apps.flexbox.R
import com.google.android.material.floatingactionbutton.FloatingActionButton
import java.util.*

/**
 * Fragment that contains the [FlexboxLayout] as the playground.
 */
class FlexboxLayoutFragment : Fragment() {

    private lateinit var flexContainer: FlexboxLayout

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

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val activity = activity as MainActivity
        flexContainer = view.findViewById(R.id.flexbox_layout)

        val fragmentHelper = FragmentHelper(activity, flexContainer)
        fragmentHelper.initializeViews()
        if (savedInstanceState != null) {
            val flexItems = savedInstanceState
                    .getParcelableArrayList<FlexItem>(FLEX_ITEMS_KEY)!!
            flexContainer.removeAllViews()
            for (i in flexItems.indices) {
                val flexItem = flexItems[i]
                val textView = createBaseFlexItemTextView(activity, i)
                textView.layoutParams = flexItem as FlexboxLayout.LayoutParams
                flexContainer.addView(textView)
            }
        }
        for (i in 0 until flexContainer.flexItemCount) {
            flexContainer.getFlexItemAt(i).setOnClickListener(
                    FlexItemClickListener(activity,
                            FlexItemChangedListenerImpl(flexContainer), i))
        }

        val addFab: FloatingActionButton = activity.findViewById(R.id.add_fab)
        addFab.setOnClickListener {
            val viewIndex = flexContainer.flexItemCount
            // index starts from 0. New View's index is N if N views ([0, 1, 2, ... N-1])
            // exist.
            val textView = createBaseFlexItemTextView(activity, viewIndex)
            val lp = FlexboxLayout.LayoutParams(
                    ViewGroup.LayoutParams.WRAP_CONTENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT)
            fragmentHelper.setFlexItemAttributes(lp)
            textView.layoutParams = lp
            textView.setOnClickListener(FlexItemClickListener(activity,
                    FlexItemChangedListenerImpl(flexContainer), viewIndex))
            flexContainer.addView(textView)
        }
        val removeFab: FloatingActionButton = activity.findViewById(R.id.remove_fab)
        removeFab.setOnClickListener(View.OnClickListener {
            if (flexContainer.flexItemCount == 0) {
                return@OnClickListener
            }
            flexContainer.removeViewAt(flexContainer.flexItemCount - 1)
        })
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        val flexItems = (0 until flexContainer.flexItemCount)
                .map { flexContainer.getFlexItemAt(it) }
                .mapTo(ArrayList()) { it.layoutParams as FlexItem }
        outState.putParcelableArrayList(FLEX_ITEMS_KEY, flexItems)
    }

    private fun createBaseFlexItemTextView(context: Context, index: Int): TextView {
        return TextView(context).apply {
            setBackgroundResource(R.drawable.flex_item_background)
            text = (index + 1).toString()
            gravity = Gravity.CENTER
        }
    }

    companion object {

        private const val FLEX_ITEMS_KEY = "flex_items_key"

        fun newInstance(): FlexboxLayoutFragment {
            return FlexboxLayoutFragment()
        }
    }
}


================================================
FILE: demo-playground/src/main/java/com/google/android/flexbox/FragmentHelper.kt
================================================
/*
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.flexbox

import android.content.SharedPreferences
import android.view.Menu
import android.view.View
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.Spinner
import android.widget.Toast
import androidx.preference.PreferenceManager
import com.google.android.apps.flexbox.R
import com.google.android.material.navigation.NavigationView

/**
 * Helper class that has the common logic for initializing the Fragment for the play ground demo
 * such as [FlexboxLayoutFragment] and a Fragment that uses RecyclerView in it.
 */
internal class FragmentHelper(private val activity: MainActivity, private val flexContainer: FlexContainer) {

    private lateinit var ROW: String

    private lateinit var COLUMN: String

    private lateinit var ROW_REVERSE: String

    private lateinit var COLUMN_REVERSE: String

    private lateinit var NOWRAP: String

    private lateinit var WRAP: String

    private lateinit var WRAP_REVERSE: String

    private lateinit var FLEX_START: String

    private lateinit var FLEX_END: String

    private lateinit var CENTER: String

    private lateinit var BASELINE: String

    private lateinit var STRETCH: String

    private lateinit var SPACE_BETWEEN: String

    private lateinit var SPACE_AROUND: String

    private lateinit var SPACE_EVENLY: String

    private lateinit var sharedPreferences: SharedPreferences

    fun initializeViews() {
        sharedPreferences = PreferenceManager.getDefaultSharedPreferences(activity)
        initializeStringResources()
        val navigationView: NavigationView = activity.findViewById(R.id.nav_view)
        navigationView.setNavigationItemSelectedListener(activity)
        val navigationMenu = navigationView.menu
        initializeFlexDirectionSpinner(navigationMenu)
        initializeFlexWrapSpinner(navigationMenu)
        initializeJustifyContentSpinner(navigationMenu)
        initializeAlignItemsSpinner(navigationMenu)
        initializeAlignContentSpinner(navigationMenu)
    }

    private fun initializeStringResources() {
        ROW = activity.getString(R.string.row)
        COLUMN = activity.getString(R.string.column)
        ROW_REVERSE = activity.getString(R.string.row_reverse)
        COLUMN_REVERSE = activity.getString(R.string.column_reverse)
        NOWRAP = activity.getString(R.string.nowrap)
        WRAP = activity.getString(R.string.wrap)
        WRAP_REVERSE = activity.getString(R.string.wrap_reverse)
        FLEX_START = activity.getString(R.string.flex_start)
        FLEX_END = activity.getString(R.string.flex_end)
        CENTER = activity.getString(R.string.center)
        BASELINE = activity.getString(R.string.baseline)
        STRETCH = activity.getString(R.string.stretch)
        SPACE_BETWEEN = activity.getString(R.string.space_between)
        SPACE_AROUND = activity.getString(R.string.space_around)
        SPACE_EVENLY = activity.getString(R.string.space_evenly)
    }

    /**
     * Sets the attributes for a [FlexItem] based on the stored default values in
     * the SharedPreferences.

     * @param flexItem the FlexItem instance
     * *
     * @return a FlexItem instance, which attributes from the SharedPreferences are updated
     */
    fun setFlexItemAttributes(flexItem: FlexItem): FlexItem {
        flexItem.width = activity.dpToPixel(readPreferenceAsInteger(activity.getString(R.string.new_width_key), DEFAULT_WIDTH))
        flexItem.height = activity.dpToPixel(readPreferenceAsInteger(activity.getString(R.string.new_height_key), DEFAULT_HEIGHT))
        // Order is not supported in the FlexboxLayoutManager
        if (flexItem !is FlexboxLayoutManager.LayoutParams) {
            flexItem.order = readPreferenceAsInteger(activity.getString(R.string.new_flex_item_order_key), "1")
        }
        flexItem.flexGrow = readPreferenceAsFloat(activity.getString(R.string.new_flex_grow_key), "0.0")
        flexItem.flexShrink = readPreferenceAsFloat(activity.getString(R.string.new_flex_shrink_key), "1.0")
        val flexBasisPercent = readPreferenceAsInteger(
                activity.getString(R.string.new_flex_basis_percent_key), "-1")
        flexItem.flexBasisPercent = if (flexBasisPercent == -1) -1f else (flexBasisPercent / 100.0).toFloat()
        return flexItem
    }

    private fun readPreferenceAsInteger(key: String, defValue: String): Int {
        return if (sharedPreferences.contains(key)) {
            sharedPreferences.getString(key, defValue)?.toIntOrNull() ?: defValue.toInt()
        } else {
            defValue.toInt()
        }
    }

    private fun readPreferenceAsFloat(key: String, defValue: String): Float {
        return if (sharedPreferences.contains(key)) {
            sharedPreferences.getString(key, defValue)?.toFloatOrNull() ?: defValue.toFloat()
        } else {
            defValue.toFloat()
        }
    }

    private fun initializeSpinner(currentValue: Int, menuItemId: Int, navigationMenu: Menu,
                                  arrayResourceId: Int, listener: AdapterView.OnItemSelectedListener,
                                  converter: ValueToStringConverter) {
        val spinner = navigationMenu.findItem(menuItemId).actionView as Spinner
        val adapter = ArrayAdapter.createFromResource(activity,
                arrayResourceId, R.layout.spinner_item)
        spinner.adapter = adapter
        spinner.onItemSelectedListener = listener
        val selectedAsString = converter.asString(currentValue)
        val position = adapter.getPosition(selectedAsString)
        spinner.setSelection(position)
    }

    private fun initializeFlexDirectionSpinner(navigationMenu: Menu) {
        initializeSpinner(flexContainer.flexDirection, R.id.menu_item_flex_direction,
                navigationMenu, R.array.array_flex_direction,
                object : AdapterView.OnItemSelectedListener {
                    override fun onItemSelected(parent: AdapterView<*>, ignored: View?, position: Int,
                                                id: Long) {
                        flexContainer.flexDirection = when (parent.getItemAtPosition(position).toString()) {
                            ROW -> FlexDirection.ROW
                            ROW_REVERSE -> FlexDirection.ROW_REVERSE
                            COLUMN -> FlexDirection.COLUMN
                            COLUMN_REVERSE -> FlexDirection.COLUMN_REVERSE
                            else -> return
                        }
                    }

                    override fun onNothingSelected(parent: AdapterView<*>) {
                        // No op
                    }
                }, object : ValueToStringConverter {
            override fun asString(value: Int): String {
                return when (value) {
                    FlexDirection.ROW -> ROW
                    FlexDirection.ROW_REVERSE -> ROW_REVERSE
                    FlexDirection.COLUMN -> COLUMN
                    FlexDirection.COLUMN_REVERSE -> COLUMN_REVERSE
                    else -> ROW
                }
            }
        })
    }

    private fun initializeFlexWrapSpinner(navigationMenu: Menu) {
        initializeSpinner(flexContainer.flexWrap, R.id.menu_item_flex_wrap,
                navigationMenu, R.array.array_flex_wrap,
                object : AdapterView.OnItemSelectedListener {
                    override fun onItemSelected(parent: AdapterView<*>, ignored: View?, position: Int,
                                                id: Long) {
                        flexContainer.flexWrap = when (parent.getItemAtPosition(position).toString()) {
                            NOWRAP -> FlexWrap.NOWRAP
                            WRAP -> FlexWrap.WRAP
                            WRAP_REVERSE -> if (flexContainer is FlexboxLayoutManager) {
                                Toast.makeText(activity,
                                        R.string.wrap_reverse_not_supported,
                                        Toast.LENGTH_SHORT).show()
                                return
                            } else {
                                FlexWrap.WRAP_REVERSE
                            }
                            else -> return
                        }
                    }

                    override fun onNothingSelected(parent: AdapterView<*>) {
                        // No op
                    }
                }, object : ValueToStringConverter {
            override fun asString(value: Int): String {
                return when (value) {
                    FlexWrap.NOWRAP -> NOWRAP
                    FlexWrap.WRAP -> WRAP
                    FlexWrap.WRAP_REVERSE -> WRAP_REVERSE
                    else -> NOWRAP
                }
            }
        })
    }

    private fun initializeJustifyContentSpinner(navigationMenu: Menu) {
        initializeSpinner(flexContainer.justifyContent, R.id.menu_item_justify_content,
                navigationMenu, R.array.array_justify_content,
                object : AdapterView.OnItemSelectedListener {
                    override fun onItemSelected(parent: AdapterView<*>, ignored: View?, position: Int,
                                                id: Long) {
                        flexContainer.justifyContent = when (parent.getItemAtPosition(position).toString()) {
                            FLEX_START -> JustifyContent.FLEX_START
                            FLEX_END -> JustifyContent.FLEX_END
                            CENTER -> JustifyContent.CENTER
                            SPACE_BETWEEN -> JustifyContent.SPACE_BETWEEN
                            SPACE_AROUND -> JustifyContent.SPACE_AROUND
                            SPACE_EVENLY -> JustifyContent.SPACE_EVENLY
                            else -> return
                        }
                    }

                    override fun onNothingSelected(parent: AdapterView<*>) {
                        // No op
                    }
                }, object : ValueToStringConverter {
            override fun asString(value: Int): String {
                return when (value) {
                    JustifyContent.FLEX_START -> FLEX_START
                    JustifyContent.FLEX_END -> FLEX_END
                    JustifyContent.CENTER -> CENTER
                    JustifyContent.SPACE_AROUND -> SPACE_AROUND
                    JustifyContent.SPACE_BETWEEN -> SPACE_BETWEEN
                    JustifyContent.SPACE_EVENLY -> SPACE_EVENLY
                    else -> FLEX_START
                }
            }
        })
    }

    private fun initializeAlignItemsSpinner(navigationMenu: Menu) {
        initializeSpinner(flexContainer.alignItems, R.id.menu_item_align_items,
                navigationMenu, R.array.array_align_items,
                object : AdapterView.OnItemSelectedListener {
                    override fun onItemSelected(parent: AdapterView<*>, ignored: View?, position: Int,
                                                id: Long) {
                        flexContainer.alignItems = when (parent.getItemAtPosition(position).toString()) {
                            FLEX_START -> AlignItems.FLEX_START
                            FLEX_END -> AlignItems.FLEX_END
                            CENTER -> AlignItems.CENTER
                            BASELINE -> AlignItems.BASELINE
                            STRETCH -> AlignItems.STRETCH
                            else -> return
                        }
                    }

                    override fun onNothingSelected(parent: AdapterView<*>) {
                        // No op
                    }
                }, object : ValueToStringConverter {
            override fun asString(value: Int): String {
                return when (value) {
                    AlignItems.FLEX_START -> FLEX_START
                    AlignItems.FLEX_END -> FLEX_END
                    AlignItems.CENTER -> CENTER
                    AlignItems.BASELINE -> BASELINE
                    AlignItems.STRETCH -> STRETCH
                    else -> STRETCH
                }
            }
        })
    }

    private fun initializeAlignContentSpinner(navigationMenu: Menu) {
        initializeSpinner(flexContainer.alignContent, R.id.menu_item_align_content,
                navigationMenu, R.array.array_align_content,
                object : AdapterView.OnItemSelectedListener {
                    override fun onItemSelected(parent: AdapterView<*>, ignored: View?, position: Int,
                                                id: Long) {
                        if (flexContainer is FlexboxLayoutManager) {
                            Toast.makeText(activity, R.string.align_content_not_supported,
                                    Toast.LENGTH_SHORT).show()
                            return
                        }
                        flexContainer.alignContent = when (parent.getItemAtPosition(position).toString()) {
                            FLEX_START -> AlignContent.FLEX_START
                            FLEX_END -> AlignContent.FLEX_END
                            CENTER -> AlignContent.CENTER
                            SPACE_BETWEEN -> AlignContent.SPACE_BETWEEN
                            SPACE_AROUND -> AlignContent.SPACE_AROUND
                            STRETCH -> AlignContent.STRETCH
                            else -> return
                        }
                    }

                    override fun onNothingSelected(parent: AdapterView<*>) {
                        // No op
                    }
                }, object : ValueToStringConverter {
            override fun asString(value: Int): String {
                when (value) {
                    AlignContent.FLEX_START -> return FLEX_START
                    AlignContent.FLEX_END -> return FLEX_END
                    AlignContent.CENTER -> return CENTER
                    AlignContent.SPACE_BETWEEN -> return SPACE_BETWEEN
                    AlignContent.SPACE_AROUND -> return SPACE_AROUND
                    AlignContent.STRETCH -> return STRETCH
                    else -> return STRETCH
                }
            }
        })
    }

    /**
     * Converter for converting an int value for Flexbox properties to a String.
     */
    private interface ValueToStringConverter {

        fun asString(value: Int): String
    }

    companion object {

        private const val DEFAULT_WIDTH = "120"

        private const val DEFAULT_HEIGHT = "80"
    }
}


================================================
FILE: demo-playground/src/main/java/com/google/android/flexbox/MainActivity.kt
================================================
/*
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.flexbox

import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.widget.RadioGroup
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.drawerlayout.widget.DrawerLayout
import androidx.fragment.app.FragmentManager
import com.google.android.apps.flexbox.R
import com.google.android.material.navigation.NavigationView

class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val toolbar: Toolbar = findViewById(R.id.toolbar)
        setSupportActionBar(toolbar)
        val drawer: DrawerLayout = findViewById(R.id.drawer_layout)
        val toggle = ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open,
                R.string.navigation_drawer_close)
        drawer.addDrawerListener(toggle)
        toggle.syncState()

        val navigationView: NavigationView = findViewById(R.id.nav_view)
        val radioGroup: RadioGroup = navigationView.getHeaderView(0)
                .findViewById(R.id.radiogroup_container_implementation)
        val fragmentManager = supportFragmentManager

        radioGroup.setOnCheckedChangeListener { _, checkedId ->
            if (checkedId == R.id.radiobutton_viewgroup) {
                replaceToFlexboxLayoutFragment(fragmentManager)
            } else {
                replaceToRecyclerViewFragment(fragmentManager)
            }
        }

        if (savedInstanceState == null) {
            replaceToFlexboxLayoutFragment(fragmentManager)
        }
    }

    private fun replaceToFlexboxLayoutFragment(fragmentManager: FragmentManager) {
        var fragment: FlexboxLayoutFragment? = fragmentManager.findFragmentByTag(FLEXBOXLAYOUT_FRAGMENT) as FlexboxLayoutFragment?
        if (fragment == null) {
            fragment = FlexboxLayoutFragment.newInstance()
        }
        fragmentManager.beginTransaction()
                .replace(R.id.container, fragment, FLEXBOXLAYOUT_FRAGMENT).commit()
    }

    private fun replaceToRecyclerViewFragment(fragmentManager: FragmentManager) {
        var fragment: RecyclerViewFragment? = fragmentManager.findFragmentByTag(RECYCLERVIEW_FRAGMENT) as RecyclerViewFragment?
        if (fragment == null) {
            fragment = RecyclerViewFragment.newInstance()
        }
        fragmentManager.beginTransaction()
                .replace(R.id.container, fragment, RECYCLERVIEW_FRAGMENT).commit()
    }

    override fun onNavigationItemSelected(item: MenuItem): Boolean {
        return false
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        menuInflater.inflate(R.menu.menu_main, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        val id = item.itemId

        if (id == R.id.action_settings) {
            val intent = Intent(this, SettingsActivity::class.java)
            startActivity(intent)
            return true
        }
        return super.onOptionsItemSelected(item)
    }

    companion object {

        private const val FLEXBOXLAYOUT_FRAGMENT = "flexboxlayout_fragment"

        private const val RECYCLERVIEW_FRAGMENT = "recyclerview_fragment"
    }
}


================================================
FILE: demo-playground/src/main/java/com/google/android/flexbox/RecyclerViewFragment.kt
================================================
/*
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.flexbox

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.RecyclerView
import com.google.android.apps.flexbox.R
import com.google.android.material.floatingactionbutton.FloatingActionButton

/**
 * Fragment that contains the [RecyclerView] and the [FlexboxLayoutManager] as its
 * LayoutManager for the flexbox playground.
 */
internal class RecyclerViewFragment : Fragment() {

    private lateinit var adapter: FlexItemAdapter

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

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

        val recyclerView: RecyclerView = view.findViewById(R.id.recyclerview)
        val activity = activity as MainActivity
        val flexboxLayoutManager = FlexboxLayoutManager(activity)
        recyclerView.layoutManager = flexboxLayoutManager
        adapter = FlexItemAdapter(activity, flexboxLayoutManager)
        recyclerView.adapter = adapter
        if (savedInstanceState != null) {
            val layoutParams : List<FlexboxLayoutManager.LayoutParams>? = savedInstanceState
                    .getParcelableArrayList(FLEX_ITEMS_KEY)
            layoutParams?.let {
                for (i in layoutParams.indices) {
                    adapter.addItem(layoutParams[i])
                }
            }
            adapter.notifyDataSetChanged()
        }
        val fragmentHelper = FragmentHelper(activity, flexboxLayoutManager)
        fragmentHelper.initializeViews()

        val addFab: FloatingActionButton = activity.findViewById(R.id.add_fab)
        addFab.setOnClickListener {
            val lp = FlexboxLayoutManager.LayoutParams(
                    ViewGroup.LayoutParams.WRAP_CONTENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT)
            fragmentHelper.setFlexItemAttributes(lp)
            adapter.addItem(lp)
        }
        val removeFab: FloatingActionButton = activity.findViewById(R.id.remove_fab)
        removeFab.setOnClickListener(View.OnClickListener {
            if (adapter.itemCount == 0) {
                return@OnClickListener
            }
            adapter.removeItem(adapter.itemCount - 1)
        })
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putParcelableArrayList(FLEX_ITEMS_KEY, ArrayList(adapter.items))
    }

    companion object {

        private const val FLEX_ITEMS_KEY = "flex_items"

        fun newInstance(): RecyclerViewFragment {
            return RecyclerViewFragment()
        }
    }
}


================================================
FILE: demo-playground/src/main/java/com/google/android/flexbox/SettingsActivity.kt
================================================
/*
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.flexbox

import android.os.Bundle
import android.widget.Toast
import androidx.fragment.app.FragmentActivity
import androidx.preference.EditTextPreference
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import com.google.android.apps.flexbox.R
import com.google.android.flexbox.validators.DimensionInputValidator
import com.google.android.flexbox.validators.FlexBasisPercentInputValidator
import com.google.android.flexbox.validators.IntegerInputValidator
import com.google.android.flexbox.validators.NonNegativeDecimalInputValidator

internal class SettingsActivity : FragmentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Display the fragment as the main content.
        supportFragmentManager.beginTransaction().replace(android.R.id.content,
                SettingsFragment()).commit()
    }

    /**
     * Fragment for settings.
     */
    class SettingsFragment : PreferenceFragmentCompat() {

        override fun onCreatePreferences(savedInstanceState: Bundle?, s: String?) {
            addPreferencesFromResource(R.xml.new_flex_item_preferences)

            val orderPreference = findPreference(
                    getString(R.string.new_flex_item_order_key)) as EditTextPreference?
            orderPreference?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
                val validator = IntegerInputValidator()
                if (!validator.isValidInput(newValue.toString())) {
                    Toast.makeText(activity,
                            R.string.must_be_integer,
                            Toast.LENGTH_LONG).show()
                    return@OnPreferenceChangeListener false
                }
                true
            }

            val flexGrowPreference = findPreference(
                    getString(R.string.new_flex_grow_key)) as EditTextPreference?
            flexGrowPreference?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
                val validator = NonNegativeDecimalInputValidator()
                if (!validator.isValidInput(newValue.toString())) {
                    Toast.makeText(activity,
                            R.string.must_be_non_negative_float,
                            Toast.LENGTH_LONG).show()
                    return@OnPreferenceChangeListener false
                }
                true
            }

            val flexShrinkPreference = findPreference(
                    getString(R.string.new_flex_shrink_key)) as EditTextPreference?
            flexShrinkPreference?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
                val validator = NonNegativeDecimalInputValidator()
                if (!validator.isValidInput(newValue.toString())) {
                    Toast.makeText(activity,
                            R.string.must_be_non_negative_float,
                            Toast.LENGTH_LONG).show()
                    return@OnPreferenceChangeListener false
                }
                true
            }

            val flexBasisPercentPreference = findPreference(
                    getString(R.string.new_flex_basis_percent_key)) as EditTextPreference?
            flexBasisPercentPreference?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
                val validator = FlexBasisPercentInputValidator()
                if (!validator.isValidInput(newValue.toString())) {
                    Toast.makeText(activity,
                            R.string.must_be_minus_one_or_non_negative_integer,
                            Toast.LENGTH_LONG).show()
                    return@OnPreferenceChangeListener false
                }
                true
            }

            val widthPreference = findPreference(
                    getString(R.string.new_width_key)) as EditTextPreference?
            widthPreference?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
                val validator = DimensionInputValidator()
                if (!validator.isValidInput(newValue.toString())) {
                    Toast.makeText(activity,
                            R.string.must_be_minus_one_or_minus_two_or_non_negative_integer,
                            Toast.LENGTH_LONG).show()
                    return@OnPreferenceChangeListener false
                }
                true
            }

            val heightPreference = findPreference(
                    getString(R.string.new_height_key)) as EditTextPreference?
            heightPreference?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
                val validator = DimensionInputValidator()
                if (!validator.isValidInput(newValue.toString())) {
                    Toast.makeText(activity,
                            R.string.must_be_minus_one_or_minus_two_or_non_negative_integer,
                            Toast.LENGTH_LONG).show()
                    return@OnPreferenceChangeListener false
                }
                true
            }
        }

    }
}


================================================
FILE: demo-playground/src/main/java/com/google/android/flexbox/validators/DimensionInputValidator.kt
================================================
/*
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.flexbox.validators

import android.text.TextUtils

/**
 * Validator for dimension values including match_parent and wrap_content.
 */
class DimensionInputValidator : InputValidator {

    override fun isValidInput(charSequence: CharSequence): Boolean {
        // -1 represents match_parent, -2 represents wrap_content
        return !charSequence.isEmpty() && (TextUtils.isDigitsOnly(charSequence) ||
                charSequence.toString() == "-1" ||
                charSequence.toString() == "-2")
    }
}


================================================
FILE: demo-playground/src/main/java/com/google/android/flexbox/validators/FixedDimensionInputValidator.kt
================================================
/*
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.flexbox.validators

import android.text.TextUtils

/**
 * Validator for dimension values.
 */
class FixedDimensionInputValidator : InputValidator {

    override fun isValidInput(charSequence: CharSequence): Boolean {
        return !charSequence.isEmpty() && TextUtils.isDigitsOnly(charSequence)
    }
}


================================================
FILE: demo-playground/src/main/java/com/google/android/flexbox/validators/FlexBasisPercentInputValidator.kt
================================================
/*
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.flexbox.validators

import android.text.TextUtils

/**
 * Validator for the flex basis percent attribute.
 */
class FlexBasisPercentInputValidator : InputValidator {

    override fun isValidInput(charSequence: CharSequence): Boolean {
        // -1 represents not set
        return !charSequence.isEmpty() && (TextUtils.isDigitsOnly(charSequence) || charSequence.toString() == "-1")
    }
}


================================================
FILE: demo-playground/src/main/java/com/google/android/flexbox/validators/InputValidator.kt
================================================
/*
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.flexbox.validators

/**
 * Interface to verify a given input.
 */
interface InputValidator {

    /**
     * Verifies if the given input is valid.

     * @param charSequence the input to be verified
     * *
     * @return `true` if charSequence is valid, `false` otherwise
     */
    fun isValidInput(charSequence: CharSequence): Boolean
}


================================================
FILE: demo-playground/src/main/java/com/google/android/flexbox/validators/IntegerInputValidator.kt
================================================
/*
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.flexbox.validators

/**
 * Validator for the integers.
 */
class IntegerInputValidator : InputValidator {

    override fun isValidInput(charSequence: CharSequence): Boolean {
        return charSequence.toString().toIntOrNull() != null
    }
}


================================================
FILE: demo-playground/src/main/java/com/google/android/flexbox/validators/NonNegativeDecimalInputValidator.kt
================================================
/*
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.flexbox.validators

/**
 * Validator for non negative integers.
 */
class NonNegativeDecimalInputValidator : InputValidator {

    override fun isValidInput(charSequence: CharSequence): Boolean {
        return charSequence.toString().toFloatOrNull() ?: -1f >= 0
    }
}


================================================
FILE: demo-playground/src/main/res/drawable/flex_item_background.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
    <solid android:color="@color/lightPink" />
    <stroke android:width="1dp" android:color="#888888"/>
</shape>

================================================
FILE: demo-playground/src/main/res/drawable/side_nav_bar.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    <gradient
        android:startColor="#81C784"
        android:centerColor="#4CAF50"
        android:endColor="#2E7D32"
        android:type="linear"
        android:angle="135"/>
</shape>

================================================
FILE: demo-playground/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <include
        layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

</androidx.drawerlayout.widget.DrawerLayout>


================================================
FILE: demo-playground/src/main/res/layout/app_bar_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.google.android.flexbox.MainActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:theme="@style/AppTheme.AppBarOverlay">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </com.google.android.material.appbar.AppBarLayout>

    <include layout="@layout/content_main" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/remove_fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_marginRight="@dimen/fab_margin"
        android:layout_marginEnd="@dimen/fab_margin"
        android:layout_marginBottom="@dimen/second_fab_margin"
        android:src="@drawable/ic_remove_white_24dp" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/add_fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        android:src="@drawable/ic_add_white_24dp" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>


================================================
FILE: demo-playground/src/main/res/layout/content_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/container"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />



================================================
FILE: demo-playground/src/main/res/layout/fragment_flex_item_edit.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginEnd="@dimen/activity_horizontal_margin"
    android:layout_marginStart="@dimen/activity_horizontal_margin"
    android:layout_marginTop="@dimen/activity_vertical_margin"
    android:layout_marginBottom="@dimen/activity_vertical_margin">

    <com.google.android.flexbox.FlexboxLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingEnd="@dimen/margin_medium"
        android:paddingStart="@dimen/margin_medium"
        app:flexWrap="wrap">

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/input_layout_order"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            app:layout_flexGrow="1">

            <EditText
                android:id="@+id/edit_text_order"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/hint_order"
                android:inputType="numberSigned"
                android:lines="1"
                android:maxLines="1" />
        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/input_layout_flex_grow"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            app:layout_flexGrow="1">

            <EditText
                android:id="@+id/edit_text_flex_grow"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/hint_flex_grow"
                android:inputType="numberDecimal"
                android:lines="1"
                android:maxLines="1" />
        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/input_layout_flex_shrink"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            app:layout_flexGrow="1">

            <EditText
                android:id="@+id/edit_text_flex_shrink"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/hint_flex_shrink"
                android:inputType="numberDecimal"
                android:lines="1"
                android:maxLines="1" />
        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/input_layout_flex_basis_percent"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            app:layout_flexGrow="1">

            <EditText
                android:id="@+id/edit_text_flex_basis_percent"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/hint_flex_basis_percent"
                android:inputType="numberSigned"
                android:lines="1"
                android:maxLines="1" />
        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/input_layout_width"
            android:layout_width="300dp"
            android:layout_height="wrap_content"
            app:layout_wrapBefore="true"
            app:layout_flexGrow="1">

            <EditText
                android:id="@+id/edit_text_width"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/hint_width"
                android:inputType="numberSigned"
                android:lines="1"
                android:maxLines="1" />
        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/input_layout_height"
            android:layout_width="300dp"
            android:layout_height="wrap_content"
            app:layout_flexGrow="1">

            <EditText
                android:id="@+id/edit_text_height"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/hint_height"
                android:inputType="numberSigned"
                android:lines="1"
                android:maxLines="1" />
        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/input_layout_min_width"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_flexBasisPercent="22%"
            app:layout_minWidth="130dp"
            app:layout_wrapBefore="true"
            app:layout_flexGrow="1">

            <EditText
                android:id="@+id/edit_text_min_width"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:lines="1"
                android:inputType="number"
                android:hint="@string/hint_min_width"
                android:maxLines="1" />
        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/input_layout_min_height"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_flexBasisPercent="22%"
            app:layout_minWidth="130dp"
            app:layout_flexGrow="1">

            <EditText
                android:id="@+id/edit_text_min_height"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:lines="1"
                android:inputType="number"
                android:hint="@string/hint_min_height"
                android:maxLines="1" />
        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/input_layout_max_width"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_flexBasisPercent="22%"
            app:layout_minWidth="130dp"
            app:layout_flexGrow="1">

            <EditText
                android:id="@+id/edit_text_max_width"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:lines="1"
                android:inputType="number"
                android:hint="@string/hint_max_width"
                android:maxLines="1" />
        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/input_layout_max_height"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_flexBasisPercent="22%"
            app:layout_minWidth="130dp"
            app:layout_flexGrow="1">

            <EditText
                android:id="@+id/edit_text_max_height"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:lines="1"
                android:inputType="number"
                android:hint="@string/hint_max_height"
                android:maxLines="1" />
        </com.google.android.material.textfield.TextInputLayout>

        <CheckBox
            android:id="@+id/checkbox_wrap_before"
            android:layout_width="130dp"
            android:layout_height="wrap_content"
            android:text="@string/hint_wrap_before"
            app:layout_wrapBefore="true"
            app:layout_flexGrow="1" />

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_flexGrow="1">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/hint_align_self" />

            <Spinner
                android:id="@+id/spinner_align_self"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="end" />
        </LinearLayout>


        <LinearLayout
            android:id="@+id/button_panel"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="bottom"
            android:orientation="horizontal"
            android:paddingBottom="@dimen/margin_small"
            android:paddingTop="@dimen/margin_small">

            <View
                android:id="@+id/spacer"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:visibility="invisible" />

            <Button
                android:id="@+id/button_cancel"
                style="@style/DialogButton"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/cancel" />

            <Button
                android:id="@+id/button_ok"
                style="@style/DialogButton"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/ok" />
        </LinearLayout>
    </com.google.android.flexbox.FlexboxLayout>
</ScrollView>


================================================
FILE: demo-playground/src/main/res/layout/fragment_flexboxlayout.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<com.google.android.flexbox.FlexboxLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/flexbox_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:alignContent="flex_start"
    app:alignItems="flex_start"
    app:flexWrap="wrap"
    tools:showIn="@layout/activity_main">

    <TextView
        android:id="@+id/textview1"
        style="@style/FlexItem"
        android:layout_width="@dimen/flex_item_length2"
        android:layout_height="@dimen/flex_item_length"
        android:text="@string/one" />

    <TextView
        android:id="@+id/textview2"
        style="@style/FlexItem"
        android:layout_width="@dimen/flex_item_length3"
        android:layout_height="@dimen/flex_item_length"
        android:text="@string/two" />

    <TextView
        android:id="@+id/textview3"
        style="@style/FlexItem"
        android:layout_width="@dimen/flex_item_length"
        android:layout_height="@dimen/flex_item_length"
        android:text="@string/three" />

</com.google.android.flexbox.FlexboxLayout>

================================================
FILE: demo-playground/src/main/res/layout/fragment_recyclerview.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/recyclerview"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />


================================================
FILE: demo-playground/src/main/res/layout/nav_header_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/side_nav_bar"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:theme="@style/ThemeOverlay.AppCompat.Dark"
    android:orientation="vertical"
    android:gravity="bottom">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="@dimen/nav_header_vertical_spacing"
        android:src="@android:drawable/sym_def_app_icon"
        android:id="@+id/imageView" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="@dimen/nav_header_vertical_spacing"
        android:text="@string/app_name"
        android:textAppearance="@style/TextAppearance.AppCompat.Body1" />

    <RadioGroup
        android:id="@+id/radiogroup_container_implementation"
        android:checkedButton="@+id/radiobutton_viewgroup"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/margin_large">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/underlying_implementation" />

        <RadioButton
            android:id="@+id/radiobutton_viewgroup"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/viewgroup" />

        <RadioButton
            android:id="@+id/radiobutton_recyclerview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/recyclerview" />
    </RadioGroup>
</LinearLayout>


================================================
FILE: demo-playground/src/main/res/layout/spinner_align_content.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<Spinner xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/spinner_align_content"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="center_vertical"
    android:gravity="end" />


================================================
FILE: demo-playground/src/main/res/layout/spinner_align_items.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<Spinner xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/spinner_align_items"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="center_vertical"
    android:gravity="end" />


================================================
FILE: demo-playground/src/main/res/layout/spinner_flex_direction.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<Spinner xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/spinner_flex_direction"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="center_vertical"
    android:gravity="end" />


================================================
FILE: demo-playground/src/main/res/layout/spinner_flex_wrap.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<Spinner xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/spinner_flex_wrap"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="center_vertical"
    android:gravity="end" />


================================================
FILE: demo-playground/src/main/res/layout/spinner_item.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="13sp"
    android:gravity="left"
    android:textColor="@android:color/black"
    android:paddingTop="@dimen/margin_small"
    android:paddingBottom="@dimen/margin_small"
    android:paddingStart="@dimen/margin_tiny"
    android:paddingLeft="@dimen/margin_tiny"
    android:paddingEnd="@dimen/margin_tiny"
    android:paddingRight="@dimen/margin_tiny" />


================================================
FILE: demo-playground/src/main/res/layout/spinner_justify_content.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<Spinner xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/spinner_justify_content"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="center_vertical"
    android:gravity="end" />


================================================
FILE: demo-playground/src/main/res/layout/viewholder_flex_item.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/textview"
    android:layout_width="@dimen/flex_item_length2"
    android:layout_height="@dimen/flex_item_length" />


================================================
FILE: demo-playground/src/main/res/menu/activity_main_drawer.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <group android:checkableBehavior="none">
        <item
            android:id="@+id/menu_item_flex_direction"
            android:title="@string/flex_direction"
            app:actionLayout="@layout/spinner_flex_direction" />
        <item
            android:id="@+id/menu_item_flex_wrap"
            android:title="@string/flex_wrap"
            app:actionLayout="@layout/spinner_flex_wrap" />
        <item
            android:id="@+id/menu_item_justify_content"
            android:title="@string/justify_content"
            app:actionLayout="@layout/spinner_justify_content" />
        <item
            android:id="@+id/menu_item_align_items"
            android:title="@string/align_items"
            app:actionLayout="@layout/spinner_align_items" />
        <item
            android:id="@+id/menu_item_align_content"
            android:title="@string/align_content"
            app:actionLayout="@layout/spinner_align_content" />
    </group>
</menu>


================================================
FILE: demo-playground/src/main/res/menu/menu_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context="com.google.android.flexbox.MainActivity">
    <item
        android:id="@+id/action_settings"
        android:title="@string/action_settings"
        android:orderInCategory="100"
        app:showAsAction="never" />
</menu>


================================================
FILE: demo-playground/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
    <color name="lightPink">#FFCEE1</color>
</resources>


================================================
FILE: demo-playground/src/main/res/values/dimens.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="nav_header_vertical_spacing">16dp</dimen>
    <dimen name="nav_header_height">160dp</dimen>

    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
    <dimen name="fab_margin">16dp</dimen>
    <dimen name="second_fab_margin">92dp</dimen>

    <dimen name="margin_tiny">4dp</dimen>
    <dimen name="margin_small">8dp</dimen>
    <dimen name="margin_medium">16dp</dimen>
    <dimen name="margin_large">32dp</dimen>
    <dimen name="margin_huge">64dp</dimen>

    <dimen name="flex_item_length">80dp</dimen>
    <dimen name="flex_item_length2">120dp</dimen>
    <dimen name="flex_item_length3">160dp</dimen>
</resources>


================================================
FILE: demo-playground/src/main/res/values/strings.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
    <string name="app_name">Flexbox Playground</string>
    <string name="ok">OK</string>
    <string name="cancel">Cancel</string>
    <string name="one" translatable="false">1</string>
    <string name="two" translatable="false">2</string>
    <string name="three" translatable="false">3</string>

    <string name="navigation_drawer_open">Open navigation drawer</string>
    <string name="navigation_drawer_close">Close navigation drawer</string>

    <string name="flex_direction" translatable="false">Flex Direction</string>
    <string name="flex_wrap" translatable="false">Flex Wrap</string>
    <string name="justify_content" translatable="false">Justify Content</string>
    <string name="align_items" translatable="false">Align Items</string>
    <string name="align_content" translatable="false">Align Content</string>

    <string name="row" translatable="false">Row</string>
    <string name="row_reverse" translatable="false">Row Reverse</string>
    <string name="column" translatable="false">Column</string>
    <string name="column_reverse" translatable="false">Column Reverse</string>
    <string name="nowrap" translatable="false">Nowrap</string>
    <string name="wrap" translatable="false">Wrap</string>
    <string name="wrap_reverse" translatable="false">Wrap Reverse</string>
    <string name="flex_start" translatable="false">Flex Start</string>
    <string name="flex_end" translatable="false">Flex End</string>
    <string name="center" translatable="false">Center</string>
    <string name="space_between" translatable="false">Space Between</string>
    <string name="space_around" translatable="false">Space Around</string>
    <string name="space_evenly" translatable="false">Space Evenly</string>
    <string name="baseline" translatable="false">Baseline</string>
    <string name="stretch" translatable="false">Stretch</string>
    <string name="auto" translatable="false">Auto</string>

    <string-array translatable="false" name="array_flex_direction">
        <item>@string/row</item>
        <item>@string/row_reverse</item>
        <item>@string/column</item>
        <item>@string/column_reverse</item>
    </string-array>

    <string-array translatable="false" name="array_flex_wrap">
        <item>@string/nowrap</item>
        <item>@string/wrap</item>
        <item>@string/wrap_reverse</item>
    </string-array>

    <string-array translatable="false" name="array_justify_content">
        <item>@string/flex_start</item>
        <item>@string/flex_end</item>
        <item>@string/center</item>
        <item>@string/space_between</item>
        <item>@string/space_around</item>
        <item>@string/space_evenly</item>
    </string-array>

    <string-array translatable="false" name="array_align_items">
        <item>@string/flex_start</item>
        <item>@string/flex_end</item>
        <item>@string/center</item>
        <item>@string/baseline</item>
        <item>@string/stretch</item>
    </string-array>

    <string-array translatable="false" name="array_align_content">
        <item>@string/flex_start</item>
        <item>@string/flex_end</item>
        <item>@string/center</item>
        <item>@string/space_between</item>
        <item>@string/space_around</item>
        <item>@string/stretch</item>
    </string-array>

    <string-array translatable="false" name="array_align_self">
        <item>@string/auto</item>
        <item>@string/flex_start</item>
        <item>@string/flex_end</item>
        <item>@string/center</item>
        <item>@string/baseline</item>
        <item>@string/stretch</item>
    </string-array>

    <string name="hint_order">Order</string>
    <string name="hint_flex_grow">Flex Grow</string>
    <string name="hint_flex_shrink">Flex Shrink</string>
    <string name="hint_flex_basis_percent">Flex Basis Percent (-1: not set)</string>
    <string name="hint_align_self">Align Self</string>
    <string name="hint_width">Width (-1: match_parent, -2: wrap_content)</string>
    <string name="hint_height">Height (-1: match_parent, -2: wrap_content)</string>
    <string name="hint_min_width">Min Width</string>
    <string name="hint_min_height">Min Height</string>
    <string name="hint_max_width">Max Width</string>
    <string name="hint_max_height">Max Height</string>
    <string name="hint_wrap_before">Wrap Before</string>

    <string name="must_be_non_negative_float">Must be a non-negative float value</string>
    <string name="must_be_non_negative_integer">Must be a non-negative integer value</string>
    <string name="must_be_minus_one_or_minus_two_or_non_negative_integer">Must be -1 or -2 or a non-negative integer value</string>
    <string name="must_be_integer">Must be an integer value</string>
    <string name="must_be_minus_one_or_non_negative_integer">Must be -1 or a non-negative integer value</string>
    <string name="invalid_values_exist">Invalid values exist</string>

    <string name="action_settings">Settings</string>
    <string name="new_flex_items_default">Default values for new flex items</string>
    <string name="new_flex_items_default_key" translatable="false">new_flex_items_default_key</string>
    <string name="new_flex_item_order_key" translatable="false">new_flex_item_order_key</string>
    <string name="new_flex_grow_key" translatable="false">new_flex_grow_key</string>
    <string name="new_flex_shrink_key" translatable="false">new_flex_shrink_key</string>
    <string name="new_flex_basis_percent_key" translatable="false">new_flex_basis_percent_key</string>
    <string name="flex_basis_percent" translatable="false">Flex Basis Percent</string>
    <string name="flex_basis_percent_summary">(-1: not set)</string>
    <string name="width">Width</string>
    <string name="height">Height</string>
    <string name="size_unit_summary">(-1: match_parent, -2: wrap_content)</string>
    <string name="new_width_key" translatable="false">new_width_key</string>
    <string name="new_height_key" translatable="false">new_height_key</string>

    <string name="viewgroup">ViewGroup</string>
    <string name="recyclerview">RecyclerView</string>
    <string name="underlying_implementation">Underlying implementation</string>
    <string name="align_content_not_supported">Setting the alignContent in FlexboxLayoutManager is not supported. Ignoring.</string>
    <string name="wrap_reverse_not_supported">wrap_reverse is not supporeted in the FlexboxLayoutManager.</string>
</resources>


================================================
FILE: demo-playground/src/main/res/values/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>

    <!-- Base application theme. -->
    <style name="AppThemeBase" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <style name="AppTheme" parent="AppThemeBase">
        <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
    </style>

    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

    <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />

    <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />

    <style name="FlexItem">
        <item name="android:background">@drawable/flex_item_background</item>
        <item name="android:gravity">center</item>
    </style>

    <style name="DialogButton" />
</resources>


================================================
FILE: demo-playground/src/main/res/values-v14/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>

    <style name="AppTheme" parent="AppThemeBase">
        <!--
            This is needed to make the app work with the preference-v7 library while keeping
            material theme on API level 14+.
            See http://stackoverflow.com/questions/32070670/preferencefragmentcompat-requires-preferencetheme-to-be-set
        -->
        <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
    </style>
</resources>


================================================
FILE: demo-playground/src/main/res/values-v21/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>

    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="android:statusBarColor">@android:color/transparent</item>
    </style>

    <style name="DialogButton" parent="@android:style/Widget.Material.Button.Borderless.Colored" />
</resources>


================================================
FILE: demo-playground/src/main/res/values-w720dp/dimens.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">64dp</dimen>
    <dimen name="activity_vertical_margin">64dp</dimen>
</resources>


================================================
FILE: demo-playground/src/main/res/xml/new_flex_item_preferences.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory
        android:title="@string/new_flex_items_default"
        android:key="@string/new_flex_items_default_key">
        <EditTextPreference
            android:key="@string/new_flex_item_order_key"
            android:title="@string/hint_order"
            android:inputType="numberSigned"
            android:persistent="true"
            android:defaultValue="1" />

        <EditTextPreference
            android:key="@string/new_flex_grow_key"
            android:title="@string/hint_flex_grow"
            android:inputType="numberDecimal"
            android:persistent="true"
            android:defaultValue="0.0" />

        <EditTextPrefer
Download .txt
gitextract_48clvfh9/

├── .circleci/
│   └── config.yml
├── .github/
│   ├── issue_template.md
│   └── workflows/
│       └── gradle-wrapper-validation.yml
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── build.gradle
├── demo-cat-gallery/
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── google/
│           │           └── android/
│           │               └── flexbox/
│           │                   └── apps/
│           │                       └── catgallery/
│           │                           ├── CatAdapter.kt
│           │                           ├── CatViewHolder.kt
│           │                           └── MainActivity.kt
│           └── res/
│               ├── layout/
│               │   ├── activity_main.xml
│               │   ├── content_main.xml
│               │   └── viewholder_cat.xml
│               ├── values/
│               │   ├── colors.xml
│               │   ├── dimens.xml
│               │   ├── strings.xml
│               │   └── styles.xml
│               └── values-v21/
│                   └── styles.xml
├── demo-playground/
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── google/
│       │               └── android/
│       │                   └── apps/
│       │                       └── flexbox/
│       │                           └── test/
│       │                               └── MainActivityTest.kt
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── google/
│           │           └── android/
│           │               └── flexbox/
│           │                   ├── Extensions.kt
│           │                   ├── FlexItemAdapter.kt
│           │                   ├── FlexItemChangedListener.kt
│           │                   ├── FlexItemChangedListenerImpl.kt
│           │                   ├── FlexItemChangedListenerImplRecyclerView.kt
│           │                   ├── FlexItemClickListener.kt
│           │                   ├── FlexItemEditFragment.kt
│           │                   ├── FlexItemViewHolder.kt
│           │                   ├── FlexboxLayoutFragment.kt
│           │                   ├── FragmentHelper.kt
│           │                   ├── MainActivity.kt
│           │                   ├── RecyclerViewFragment.kt
│           │                   ├── SettingsActivity.kt
│           │                   └── validators/
│           │                       ├── DimensionInputValidator.kt
│           │                       ├── FixedDimensionInputValidator.kt
│           │                       ├── FlexBasisPercentInputValidator.kt
│           │                       ├── InputValidator.kt
│           │                       ├── IntegerInputValidator.kt
│           │                       └── NonNegativeDecimalInputValidator.kt
│           └── res/
│               ├── drawable/
│               │   ├── flex_item_background.xml
│               │   └── side_nav_bar.xml
│               ├── layout/
│               │   ├── activity_main.xml
│               │   ├── app_bar_main.xml
│               │   ├── content_main.xml
│               │   ├── fragment_flex_item_edit.xml
│               │   ├── fragment_flexboxlayout.xml
│               │   ├── fragment_recyclerview.xml
│               │   ├── nav_header_main.xml
│               │   ├── spinner_align_content.xml
│               │   ├── spinner_align_items.xml
│               │   ├── spinner_flex_direction.xml
│               │   ├── spinner_flex_wrap.xml
│               │   ├── spinner_item.xml
│               │   ├── spinner_justify_content.xml
│               │   └── viewholder_flex_item.xml
│               ├── menu/
│               │   ├── activity_main_drawer.xml
│               │   └── menu_main.xml
│               ├── values/
│               │   ├── colors.xml
│               │   ├── dimens.xml
│               │   ├── strings.xml
│               │   └── styles.xml
│               ├── values-v14/
│               │   └── styles.xml
│               ├── values-v21/
│               │   └── styles.xml
│               ├── values-w720dp/
│               │   └── dimens.xml
│               └── xml/
│                   └── new_flex_item_preferences.xml
├── flexbox/
│   ├── .gitignore
│   ├── build.gradle
│   ├── constants.gradle
│   ├── maven-puglisher-plugin.gradle
│   ├── proguard-rules.txt
│   └── src/
│       ├── androidTest/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── google/
│       │   │           └── android/
│       │   │               └── flexbox/
│       │   │                   ├── FakeFlexContainer.kt
│       │   │                   ├── FlexboxHelperTest.kt
│       │   │                   └── test/
│       │   │                       ├── ConfigChangeActivity.kt
│       │   │                       ├── FlexboxAndroidTest.kt
│       │   │                       ├── FlexboxLayoutManagerConfigChangeTest.kt
│       │   │                       ├── FlexboxLayoutManagerTest.kt
│       │   │                       ├── FlexboxTestActivity.kt
│       │   │                       ├── IsEqualAllowingError.kt
│       │   │                       ├── NestedInnerAdapter.kt
│       │   │                       ├── NestedOuterAdapter.kt
│       │   │                       ├── TestAdapter.kt
│       │   │                       ├── TestAdapterMultiViewTypes.kt
│       │   │                       ├── TestUtil.kt
│       │   │                       └── TestViewHolder.kt
│       │   └── res/
│       │       ├── drawable/
│       │       │   ├── divider.xml
│       │       │   ├── divider_thick.xml
│       │       │   └── flex_item_background.xml
│       │       ├── layout/
│       │       │   ├── activity_align_content_test.xml
│       │       │   ├── activity_align_content_test_overflowed.xml
│       │       │   ├── activity_align_items_baseline_test.xml
│       │       │   ├── activity_align_items_baseline_wrap_content.xml
│       │       │   ├── activity_align_items_parent_padding_test.xml
│       │       │   ├── activity_align_items_test.xml
│       │       │   ├── activity_align_self_stretch_test.xml
│       │       │   ├── activity_child_needs_remeasure_column.xml
│       │       │   ├── activity_child_needs_remeasure_row.xml
│       │       │   ├── activity_direction_column_align_items_center_margin_oneside.xml
│       │       │   ├── activity_direction_row_align_items_center_margin_oneside.xml
│       │       │   ├── activity_divider_test_direction_column.xml
│       │       │   ├── activity_divider_test_direction_row.xml
│       │       │   ├── activity_empty_children.xml
│       │       │   ├── activity_first_item_large_horizontal_test.xml
│       │       │   ├── activity_first_item_large_vertical_test.xml
│       │       │   ├── activity_first_view_gone_first_line_single_item.xml
│       │       │   ├── activity_first_view_gone_layout_grow_set_for_rest.xml
│       │       │   ├── activity_first_view_gone_layout_shrink_set_for_rest.xml
│       │       │   ├── activity_flex_basis_percent_test.xml
│       │       │   ├── activity_flex_grow_test.xml
│       │       │   ├── activity_flex_item_match_parent.xml
│       │       │   ├── activity_flex_item_match_parent_direction_column.xml
│       │       │   ├── activity_flex_wrap_test.xml
│       │       │   ├── activity_flexbox_wrap_content.xml
│       │       │   ├── activity_flexbox_wrapped_with_horizontalscrollview.xml
│       │       │   ├── activity_flexbox_wrapped_with_scrollview.xml
│       │       │   ├── activity_justify_content_test.xml
│       │       │   ├── activity_justify_content_with_gone.xml
│       │       │   ├── activity_justify_content_with_parent_padding.xml
│       │       │   ├── activity_maxheight_test.xml
│       │       │   ├── activity_maxheight_upper_bound_test.xml
│       │       │   ├── activity_maxwidth_test.xml
│       │       │   ├── activity_maxwidth_upper_bound_test.xml
│       │       │   ├── activity_minheight_lower_bound_test.xml
│       │       │   ├── activity_minheight_test.xml
│       │       │   ├── activity_minwidth_lower_bound_test.xml
│       │       │   ├── activity_minwidth_test.xml
│       │       │   ├── activity_order_test.xml
│       │       │   ├── activity_simple.xml
│       │       │   ├── activity_stretch_test.xml
│       │       │   ├── activity_views_visibility_gone.xml
│       │       │   ├── activity_views_visibility_invisible.xml
│       │       │   ├── activity_visibility_gone_first_item_in_flex_line_column.xml
│       │       │   ├── activity_visibility_gone_first_item_in_flex_line_row.xml
│       │       │   ├── activity_wrap_before_test.xml
│       │       │   ├── activity_wrap_child_margin_horizontal_test.xml
│       │       │   ├── activity_wrap_child_margin_vertical_test.xml
│       │       │   ├── activity_wrap_content_child_bottom_margin_column_grow.xml
│       │       │   ├── activity_wrap_content_child_bottom_margin_column_shrink.xml
│       │       │   ├── activity_wrap_content_child_bottom_margin_row_grow.xml
│       │       │   ├── activity_wrap_content_child_bottom_margin_row_shrink.xml
│       │       │   ├── activity_wrap_parent_padding_horizontal_test.xml
│       │       │   ├── activity_wrap_parent_padding_vertical_test.xml
│       │       │   ├── activity_zero_height_positive_flexgrow.xml
│       │       │   ├── activity_zero_width_positive_flexgrow.xml
│       │       │   ├── recyclerview.xml
│       │       │   ├── recyclerview_reverse.xml
│       │       │   ├── recyclerview_viewholder.xml
│       │       │   ├── viewholder_inner_recyclerview.xml
│       │       │   ├── viewholder_inner_recyclerview_wrap_horizontally.xml
│       │       │   ├── viewholder_textview.xml
│       │       │   ├── wrapped_recyclerview.xml
│       │       │   └── wrapped_recyclerview_scroll_vertical.xml
│       │       └── values/
│       │           └── strings.xml
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── google/
│           │           └── android/
│           │               └── flexbox/
│           │                   ├── AlignContent.java
│           │                   ├── AlignItems.java
│           │                   ├── AlignSelf.java
│           │                   ├── FlexContainer.java
│           │                   ├── FlexDirection.java
│           │                   ├── FlexItem.java
│           │                   ├── FlexLine.java
│           │                   ├── FlexWrap.java
│           │                   ├── FlexboxHelper.java
│           │                   ├── FlexboxItemDecoration.java
│           │                   ├── FlexboxLayout.java
│           │                   ├── FlexboxLayoutManager.java
│           │                   └── JustifyContent.java
│           └── res/
│               └── values/
│                   └── attrs.xml
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── tool/
    └── codeStyleSettings.xml
Download .txt
SYMBOL INDEX (429 symbols across 7 files)

FILE: flexbox/src/main/java/com/google/android/flexbox/FlexContainer.java
  type FlexContainer (line 27) | interface FlexContainer {
    method getFlexItemCount (line 34) | int getFlexItemCount();
    method getFlexItemAt (line 42) | View getFlexItemAt(int index);
    method getReorderedFlexItemAt (line 54) | View getReorderedFlexItemAt(int index);
    method addView (line 61) | void addView(View view);
    method addView (line 69) | void addView(View view, int index);
    method removeAllViews (line 74) | void removeAllViews();
    method removeViewAt (line 81) | void removeViewAt(int index);
    method getFlexDirection (line 87) | @FlexDirection
    method setFlexDirection (line 96) | void setFlexDirection(@FlexDirection int flexDirection);
    method getFlexWrap (line 102) | @FlexWrap
    method setFlexWrap (line 111) | void setFlexWrap(@FlexWrap int flexWrap);
    method getJustifyContent (line 117) | @JustifyContent
    method setJustifyContent (line 126) | void setJustifyContent(@JustifyContent int justifyContent);
    method getAlignContent (line 132) | @AlignContent
    method setAlignContent (line 140) | void setAlignContent(@AlignContent int alignContent);
    method getAlignItems (line 146) | @AlignItems
    method setAlignItems (line 155) | void setAlignItems(@AlignItems int alignItems);
    method getFlexLines (line 163) | List<FlexLine> getFlexLines();
    method isMainAxisDirectionHorizontal (line 170) | boolean isMainAxisDirectionHorizontal();
    method getDecorationLengthMainAxis (line 181) | int getDecorationLengthMainAxis(View view, int index, int indexInFlexL...
    method getDecorationLengthCrossAxis (line 190) | int getDecorationLengthCrossAxis(View view);
    method getPaddingTop (line 195) | int getPaddingTop();
    method getPaddingLeft (line 200) | int getPaddingLeft();
    method getPaddingRight (line 205) | int getPaddingRight();
    method getPaddingBottom (line 210) | int getPaddingBottom();
    method getPaddingStart (line 215) | int getPaddingStart();
    method getPaddingEnd (line 220) | int getPaddingEnd();
    method getChildWidthMeasureSpec (line 229) | int getChildWidthMeasureSpec(int widthSpec, int padding, int childDime...
    method getChildHeightMeasureSpec (line 238) | int getChildHeightMeasureSpec(int heightSpec, int padding, int childDi...
    method getLargestMainSize (line 243) | int getLargestMainSize();
    method getSumOfCrossSize (line 248) | int getSumOfCrossSize();
    method onNewFlexItemAdded (line 258) | void onNewFlexItemAdded(View view, int index, int indexInFlexLine, Fle...
    method onNewFlexLineAdded (line 265) | void onNewFlexLineAdded(FlexLine flexLine);
    method setFlexLines (line 273) | void setFlexLines(List<FlexLine> flexLines);
    method getMaxLine (line 279) | int getMaxLine();
    method setMaxLine (line 285) | void setMaxLine(int maxLine);
    method getFlexLinesInternal (line 292) | List<FlexLine> getFlexLinesInternal();
    method updateViewCache (line 300) | void updateViewCache(int position, View view);

FILE: flexbox/src/main/java/com/google/android/flexbox/FlexItem.java
  type FlexItem (line 27) | interface FlexItem extends Parcelable {
    method getWidth (line 53) | int getWidth();
    method setWidth (line 61) | void setWidth(int width);
    method getHeight (line 69) | int getHeight();
    method setHeight (line 77) | void setHeight(int height);
    method getOrder (line 86) | int getOrder();
    method setOrder (line 93) | void setOrder(int order);
    method getFlexGrow (line 102) | float getFlexGrow();
    method setFlexGrow (line 109) | void setFlexGrow(float flexGrow);
    method getFlexShrink (line 118) | float getFlexShrink();
    method setFlexShrink (line 125) | void setFlexShrink(float flexShrink);
    method getAlignSelf (line 139) | @AlignSelf
    method setAlignSelf (line 147) | void setAlignSelf(@AlignSelf int alignSelf);
    method getMinWidth (line 154) | int getMinWidth();
    method setMinWidth (line 161) | void setMinWidth(int minWidth);
    method getMinHeight (line 168) | int getMinHeight();
    method setMinHeight (line 175) | void setMinHeight(int minHeight);
    method getMaxWidth (line 182) | int getMaxWidth();
    method setMaxWidth (line 189) | void setMaxWidth(int maxWidth);
    method getMaxHeight (line 194) | int getMaxHeight();
    method setMaxHeight (line 201) | void setMaxHeight(int maxHeight);
    method isWrapBefore (line 215) | boolean isWrapBefore();
    method setWrapBefore (line 222) | void setWrapBefore(boolean wrapBefore);
    method getFlexBasisPercent (line 236) | float getFlexBasisPercent();
    method setFlexBasisPercent (line 243) | void setFlexBasisPercent(float flexBasisPercent);
    method getMarginLeft (line 248) | int getMarginLeft();
    method getMarginTop (line 253) | int getMarginTop();
    method getMarginRight (line 258) | int getMarginRight();
    method getMarginBottom (line 263) | int getMarginBottom();
    method getMarginStart (line 268) | int getMarginStart();
    method getMarginEnd (line 273) | int getMarginEnd();

FILE: flexbox/src/main/java/com/google/android/flexbox/FlexLine.java
  class FlexLine (line 29) | public class FlexLine {
    method FlexLine (line 31) | FlexLine() {
    method getMainSize (line 108) | public int getMainSize() {
    method getCrossSize (line 115) | @SuppressWarnings("WeakerAccess")
    method getItemCount (line 123) | @SuppressWarnings("WeakerAccess")
    method getItemCountNotGone (line 131) | @SuppressWarnings("WeakerAccess")
    method getTotalFlexGrow (line 139) | @SuppressWarnings("WeakerAccess")
    method getTotalFlexShrink (line 147) | @SuppressWarnings("WeakerAccess")
    method getFirstIndex (line 155) | public int getFirstIndex() {
    method updatePositionFromView (line 168) | void updatePositionFromView(View view, int leftDecoration, int topDeco...

FILE: flexbox/src/main/java/com/google/android/flexbox/FlexboxHelper.java
  class FlexboxHelper (line 47) | class FlexboxHelper {
    method FlexboxHelper (line 103) | FlexboxHelper(FlexContainer flexContainer) {
    method createReorderedIndices (line 120) | int[] createReorderedIndices(View viewBeforeAdded, int indexForViewBef...
    method createReorderedIndices (line 156) | int[] createReorderedIndices(SparseIntArray orderCache) {
    method createOrders (line 162) | @NonNull
    method isOrderChangedFromLastMeasurement (line 182) | boolean isOrderChangedFromLastMeasurement(SparseIntArray orderCache) {
    method sortOrdersIntoReorderedIndices (line 200) | private int[] sortOrdersIntoReorderedIndices(int childCount, List<Orde...
    method calculateHorizontalFlexLines (line 220) | void calculateHorizontalFlexLines(FlexLinesResult result, int widthMea...
    method calculateHorizontalFlexLines (line 246) | void calculateHorizontalFlexLines(FlexLinesResult result, int widthMea...
    method calculateHorizontalFlexLinesToIndex (line 278) | void calculateHorizontalFlexLinesToIndex(FlexLinesResult result, int w...
    method calculateVerticalFlexLines (line 295) | void calculateVerticalFlexLines(FlexLinesResult result, int widthMeasu...
    method calculateVerticalFlexLines (line 320) | void calculateVerticalFlexLines(FlexLinesResult result, int widthMeasu...
    method calculateVerticalFlexLinesToIndex (line 352) | void calculateVerticalFlexLinesToIndex(FlexLinesResult result, int wid...
    method calculateFlexLines (line 388) | void calculateFlexLines(FlexLinesResult result, int mainMeasureSpec,
    method evaluateMinimumSizeForCompoundButton (line 645) | private void evaluateMinimumSizeForCompoundButton(CompoundButton compo...
    method getPaddingStartMain (line 663) | private int getPaddingStartMain(boolean isMainHorizontal) {
    method getPaddingEndMain (line 677) | private int getPaddingEndMain(boolean isMainHorizontal) {
    method getPaddingStartCross (line 691) | private int getPaddingStartCross(boolean isMainHorizontal) {
    method getPaddingEndCross (line 705) | private int getPaddingEndCross(boolean isMainHorizontal) {
    method getViewMeasuredSizeMain (line 720) | private int getViewMeasuredSizeMain(View view, boolean isMainHorizonta...
    method getViewMeasuredSizeCross (line 735) | private int getViewMeasuredSizeCross(View view, boolean isMainHorizont...
    method getFlexItemSizeMain (line 750) | private int getFlexItemSizeMain(FlexItem flexItem, boolean isMainHoriz...
    method getFlexItemSizeCross (line 765) | private int getFlexItemSizeCross(FlexItem flexItem, boolean isMainHori...
    method getFlexItemMarginStartMain (line 785) | private int getFlexItemMarginStartMain(FlexItem flexItem, boolean isMa...
    method getFlexItemMarginEndMain (line 804) | private int getFlexItemMarginEndMain(FlexItem flexItem, boolean isMain...
    method getFlexItemMarginStartCross (line 823) | private int getFlexItemMarginStartCross(FlexItem flexItem, boolean isM...
    method getFlexItemMarginEndCross (line 842) | private int getFlexItemMarginEndCross(FlexItem flexItem, boolean isMai...
    method isWrapRequired (line 867) | private boolean isWrapRequired(View view, int mode, int maxSize, int c...
    method isLastFlexItem (line 892) | private boolean isLastFlexItem(int childIndex, int childCount,
    method addFlexLine (line 897) | private void addFlexLine(List<FlexLine> flexLines, FlexLine flexLine, ...
    method checkSizeConstraints (line 913) | private void checkSizeConstraints(View view, int index) {
    method determineMainSize (line 947) | void determineMainSize(int widthMeasureSpec, int heightMeasureSpec) {
    method determineMainSize (line 962) | void determineMainSize(int widthMeasureSpec, int heightMeasureSpec, in...
    method ensureChildrenFrozen (line 1017) | private void ensureChildrenFrozen(int size) {
    method expandFlexItems (line 1041) | private void expandFlexItems(int widthMeasureSpec, int heightMeasureSp...
    method shrinkFlexItems (line 1224) | private void shrinkFlexItems(int widthMeasureSpec, int heightMeasureSp...
    method getChildWidthMeasureSpecInternal (line 1391) | private int getChildWidthMeasureSpecInternal(int widthMeasureSpec, Fle...
    method getChildHeightMeasureSpecInternal (line 1408) | private int getChildHeightMeasureSpecInternal(int heightMeasureSpec, F...
    method determineCrossSize (line 1438) | void determineCrossSize(int widthMeasureSpec, int heightMeasureSpec,
    method constructFlexLinesForAlignContentCenter (line 1581) | private List<FlexLine> constructFlexLinesForAlignContentCenter(List<Fl...
    method stretchViews (line 1601) | void stretchViews() {
    method stretchViews (line 1617) | void stretchViews(int fromIndex) {
    method stretchViewVertically (line 1688) | private void stretchViewVertically(View view, int crossSize, int index) {
    method stretchViewHorizontally (line 1723) | private void stretchViewHorizontally(View view, int crossSize, int ind...
    method layoutSingleChildHorizontal (line 1771) | void layoutSingleChildHorizontal(View view, FlexLine flexLine, int lef...
    method layoutSingleChildVertical (line 1855) | void layoutSingleChildVertical(View view, FlexLine flexLine, boolean i...
    method ensureMeasuredSizeCache (line 1909) | void ensureMeasuredSizeCache(int size) {
    method ensureMeasureSpecCache (line 1919) | void ensureMeasureSpecCache(int size) {
    method extractLowerInt (line 1934) | int extractLowerInt(long longValue) {
    method extractHigherInt (line 1943) | int extractHigherInt(long longValue) {
    method makeCombinedLong (line 1958) | @VisibleForTesting
    method updateMeasureCache (line 1964) | private void updateMeasureCache(int index, int widthMeasureSpec, int h...
    method ensureIndexToFlexLine (line 1978) | void ensureIndexToFlexLine(int size) {
    method clearFlexLines (line 1994) | void clearFlexLines(List<FlexLine> flexLines, int fromFlexItem) {
    class Order (line 2028) | private static class Order implements Comparable<Order> {
      method compareTo (line 2036) | @Override
      method toString (line 2044) | @NonNull
    class FlexLinesResult (line 2054) | static class FlexLinesResult {
      method reset (line 2060) | void reset() {

FILE: flexbox/src/main/java/com/google/android/flexbox/FlexboxItemDecoration.java
  class FlexboxItemDecoration (line 45) | public class FlexboxItemDecoration extends RecyclerView.ItemDecoration {
    method FlexboxItemDecoration (line 58) | public FlexboxItemDecoration(Context context) {
    method setDrawable (line 70) | public void setDrawable(Drawable drawable) {
    method setOrientation (line 86) | public void setOrientation(int orientation) {
    method onDraw (line 90) | @Override
    method getItemOffsets (line 99) | @Override
    method setOffsetAlongCrossAxis (line 120) | private void setOffsetAlongCrossAxis(Rect outRect, int position,
    method setOffsetAlongMainAxis (line 153) | private void setOffsetAlongMainAxis(Rect outRect, int position,
    method drawVerticalDecorations (line 189) | private void drawVerticalDecorations(Canvas canvas, RecyclerView paren...
    method drawHorizontalDecorations (line 233) | private void drawHorizontalDecorations(Canvas canvas, RecyclerView par...
    method needsHorizontalDecoration (line 275) | private boolean needsHorizontalDecoration() {
    method needsVerticalDecoration (line 279) | private boolean needsVerticalDecoration() {
    method isFirstItemInLine (line 286) | private boolean isFirstItemInLine(int position, List<FlexLine> flexLines,

FILE: flexbox/src/main/java/com/google/android/flexbox/FlexboxLayout.java
  class FlexboxLayout (line 78) | public class FlexboxLayout extends ViewGroup implements FlexContainer {
    method FlexboxLayout (line 208) | public FlexboxLayout(Context context) {
    method FlexboxLayout (line 212) | public FlexboxLayout(Context context, AttributeSet attrs) {
    method FlexboxLayout (line 216) | public FlexboxLayout(Context context, AttributeSet attrs, int defStyle...
    method onMeasure (line 262) | @Override
    method getFlexItemCount (line 288) | @Override
    method getFlexItemAt (line 293) | @Override
    method getReorderedChildAt (line 307) | public View getReorderedChildAt(int index) {
    method getReorderedFlexItemAt (line 314) | @Override
    method addView (line 319) | @Override
    method measureHorizontal (line 345) | private void measureHorizontal(int widthMeasureSpec, int heightMeasure...
    method measureVertical (line 406) | private void measureVertical(int widthMeasureSpec, int heightMeasureSp...
    method setMeasuredDimensionForFlex (line 434) | private void setMeasuredDimensionForFlex(@FlexDirection int flexDirect...
    method getLargestMainSize (line 521) | @Override
    method getSumOfCrossSize (line 530) | @Override
    method isMainAxisDirectionHorizontal (line 558) | @Override
    method onLayout (line 563) | @Override
    method layoutHorizontal (line 614) | private void layoutHorizontal(boolean isRtl, int left, int top, int ri...
    method layoutVertical (line 768) | private void layoutVertical(boolean isRtl, boolean fromBottomToTop, in...
    method onDraw (line 903) | @Override
    method drawDividersHorizontal (line 959) | private void drawDividersHorizontal(Canvas canvas, boolean isRtl, bool...
    method drawDividersVertical (line 1039) | private void drawDividersVertical(Canvas canvas, boolean isRtl, boolea...
    method drawVerticalDivider (line 1109) | private void drawVerticalDivider(Canvas canvas, int left, int top, int...
    method drawHorizontalDivider (line 1117) | private void drawHorizontalDivider(Canvas canvas, int left, int top, i...
    method checkLayoutParams (line 1126) | @Override
    method generateLayoutParams (line 1131) | @Override
    method generateLayoutParams (line 1136) | @Override
    method getFlexDirection (line 1146) | @FlexDirection
    method setFlexDirection (line 1152) | @Override
    method getFlexWrap (line 1160) | @FlexWrap
    method setFlexWrap (line 1166) | @Override
    method getJustifyContent (line 1174) | @JustifyContent
    method setJustifyContent (line 1180) | @Override
    method getAlignItems (line 1188) | @AlignItems
    method setAlignItems (line 1194) | @Override
    method getAlignContent (line 1202) | @AlignContent
    method setAlignContent (line 1208) | @Override
    method getMaxLine (line 1216) | @Override
    method setMaxLine (line 1221) | @Override
    method getFlexLines (line 1235) | @Override
    method getDecorationLengthMainAxis (line 1247) | @Override
    method getDecorationLengthCrossAxis (line 1268) | @Override
    method onNewFlexLineAdded (line 1275) | @Override
    method getChildWidthMeasureSpec (line 1292) | @Override
    method getChildHeightMeasureSpec (line 1297) | @Override
    method onNewFlexItemAdded (line 1302) | @Override
    method setFlexLines (line 1316) | @Override
    method getFlexLinesInternal (line 1321) | @Override
    method updateViewCache (line 1326) | @Override
    method getDividerDrawableHorizontal (line 1336) | @Nullable
    method getDividerDrawableVertical (line 1347) | @Nullable
    method setDividerDrawable (line 1360) | public void setDividerDrawable(Drawable divider) {
    method setDividerDrawableHorizontal (line 1373) | public void setDividerDrawableHorizontal(@Nullable Drawable divider) {
    method setDividerDrawableVertical (line 1395) | public void setDividerDrawableVertical(@Nullable Drawable divider) {
    method getShowDividerVertical (line 1409) | @FlexboxLayout.DividerMode
    method getShowDividerHorizontal (line 1414) | @FlexboxLayout.DividerMode
    method setShowDivider (line 1429) | public void setShowDivider(@DividerMode int dividerMode) {
    method setShowDividerVertical (line 1442) | public void setShowDividerVertical(@DividerMode int dividerMode) {
    method setShowDividerHorizontal (line 1457) | public void setShowDividerHorizontal(@DividerMode int dividerMode) {
    method setWillNotDrawFlag (line 1464) | private void setWillNotDrawFlag() {
    method hasDividerBeforeChildAtAlongMainAxis (line 1480) | private boolean hasDividerBeforeChildAtAlongMainAxis(int index, int in...
    method allViewsAreGoneBefore (line 1496) | private boolean allViewsAreGoneBefore(int index, int indexInFlexLine) {
    method hasDividerBeforeFlexLine (line 1512) | private boolean hasDividerBeforeFlexLine(int flexLineIndex) {
    method allFlexLinesAreDummyBefore (line 1531) | private boolean allFlexLinesAreDummyBefore(int flexLineIndex) {
    method hasEndDividerAfterFlexLine (line 1546) | private boolean hasEndDividerAfterFlexLine(int flexLineIndex) {
    class LayoutParams (line 1571) | public static class LayoutParams extends ViewGroup.MarginLayoutParams ...
      method LayoutParams (line 1623) | public LayoutParams(Context context, AttributeSet attrs) {
      method LayoutParams (line 1650) | public LayoutParams(LayoutParams source) {
      method LayoutParams (line 1665) | public LayoutParams(ViewGroup.LayoutParams source) {
      method LayoutParams (line 1669) | public LayoutParams(int width, int height) {
      method LayoutParams (line 1673) | public LayoutParams(MarginLayoutParams source) {
      method getWidth (line 1677) | @Override
      method setWidth (line 1682) | @Override
      method getHeight (line 1687) | @Override
      method setHeight (line 1692) | @Override
      method getOrder (line 1697) | @Override
      method setOrder (line 1702) | @Override
      method getFlexGrow (line 1707) | @Override
      method setFlexGrow (line 1712) | @Override
      method getFlexShrink (line 1717) | @Override
      method setFlexShrink (line 1722) | @Override
      method getAlignSelf (line 1727) | @AlignSelf
      method setAlignSelf (line 1733) | @Override
      method getMinWidth (line 1738) | @Override
      method setMinWidth (line 1743) | @Override
      method getMinHeight (line 1748) | @Override
      method setMinHeight (line 1753) | @Override
      method getMaxWidth (line 1758) | @Override
      method setMaxWidth (line 1763) | @Override
      method getMaxHeight (line 1768) | @Override
      method setMaxHeight (line 1773) | @Override
      method isWrapBefore (line 1778) | @Override
      method setWrapBefore (line 1783) | @Override
      method getFlexBasisPercent (line 1788) | @Override
      method setFlexBasisPercent (line 1793) | @Override
      method getMarginLeft (line 1798) | @Override
      method getMarginTop (line 1803) | @Override
      method getMarginRight (line 1808) | @Override
      method getMarginBottom (line 1813) | @Override
      method describeContents (line 1818) | @Override
      method writeToParcel (line 1823) | @Override
      method LayoutParams (line 1843) | protected LayoutParams(Parcel in) {
      method createFromParcel (line 1867) | @Override
      method newArray (line 1872) | @Override

FILE: flexbox/src/main/java/com/google/android/flexbox/FlexboxLayoutManager.java
  class FlexboxLayoutManager (line 48) | public class FlexboxLayoutManager extends RecyclerView.LayoutManager imp...
    method FlexboxLayoutManager (line 202) | public FlexboxLayoutManager(Context context) {
    method FlexboxLayoutManager (line 211) | public FlexboxLayoutManager(Context context, @FlexDirection int flexDi...
    method FlexboxLayoutManager (line 221) | public FlexboxLayoutManager(Context context, @FlexDirection int flexDi...
    method FlexboxLayoutManager (line 243) | public FlexboxLayoutManager(Context context, AttributeSet attrs, int d...
    method isAutoMeasureEnabled (line 267) | @Override
    method getFlexDirection (line 273) | @FlexDirection
    method setFlexDirection (line 279) | @Override
    method getFlexWrap (line 294) | @Override
    method setFlexWrap (line 300) | @Override
    method getJustifyContent (line 318) | @JustifyContent
    method setJustifyContent (line 324) | @Override
    method getAlignItems (line 332) | @AlignItems
    method setAlignItems (line 338) | @Override
    method getAlignContent (line 350) | @AlignContent
    method setAlignContent (line 356) | @Override
    method getMaxLine (line 363) | @Override
    method setMaxLine (line 368) | @Override
    method getFlexLines (line 376) | @Override
    method getDecorationLengthMainAxis (line 390) | @Override
    method getDecorationLengthCrossAxis (line 399) | @Override
    method onNewFlexItemAdded (line 408) | @Override
    method getFlexItemCount (line 436) | @Override
    method getFlexItemAt (line 453) | @Override
    method getReorderedFlexItemAt (line 476) | @Override
    method onNewFlexLineAdded (line 481) | @Override
    method getChildWidthMeasureSpec (line 486) | @Override
    method getChildHeightMeasureSpec (line 492) | @Override
    method getLargestMainSize (line 498) | @Override
    method getSumOfCrossSize (line 511) | @Override
    method setFlexLines (line 522) | @Override
    method getFlexLinesInternal (line 527) | @Override
    method updateViewCache (line 532) | @Override
    method computeScrollVectorForPosition (line 539) | @Override
    method generateDefaultLayoutParams (line 557) | @Override
    method generateLayoutParams (line 562) | @Override
    method checkLayoutParams (line 567) | @Override
    method onAdapterChanged (line 572) | @Override
    method onSaveInstanceState (line 577) | @Override
    method onRestoreInstanceState (line 595) | @Override
    method onItemsAdded (line 610) | @Override
    method onItemsUpdated (line 616) | @Override
    method onItemsUpdated (line 623) | @Override
    method onItemsRemoved (line 629) | @Override
    method onItemsMoved (line 635) | @Override
    method updateDirtyPosition (line 641) | private void updateDirtyPosition(int positionStart) {
    method onLayoutChildren (line 676) | @Override
    method fixLayoutStartGap (line 791) | private int fixLayoutStartGap(int startOffset, RecyclerView.Recycler r...
    method fixLayoutEndGap (line 830) | private int fixLayoutEndGap(int endOffset, RecyclerView.Recycler recyc...
    method updateFlexLines (line 864) | private void updateFlexLines(int childCount) {
    method onLayoutCompleted (line 996) | @Override
    method isLayoutRtl (line 1010) | boolean isLayoutRtl() {
    method resolveLayoutDirection (line 1014) | private void resolveLayoutDirection() {
    method updateAnchorInfoForLayout (line 1045) | private void updateAnchorInfoForLayout(RecyclerView.State state, Ancho...
    method updateAnchorFromPendingState (line 1068) | private boolean updateAnchorFromPendingState(RecyclerView.State state,...
    method updateAnchorFromChildren (line 1149) | private boolean updateAnchorFromChildren(RecyclerView.State state, Anc...
    method findFirstReferenceChild (line 1188) | private View findFirstReferenceChild(int itemCount) {
    method findLastReferenceChild (line 1211) | private View findLastReferenceChild(int itemCount) {
    method findReferenceChild (line 1232) | private View findReferenceChild(int start, int end, int itemCount) {
    method getChildClosestToStart (line 1264) | private View getChildClosestToStart() {
    method fill (line 1283) | private int fill(RecyclerView.Recycler recycler, RecyclerView.State st...
    method recycleByLayoutState (line 1320) | private void recycleByLayoutState(RecyclerView.Recycler recycler, Layo...
    method recycleFlexLinesFromStart (line 1332) | private void recycleFlexLinesFromStart(RecyclerView.Recycler recycler,
    method canViewBeRecycledFromStart (line 1378) | private boolean canViewBeRecycledFromStart(View view, int scrollingOff...
    method recycleFlexLinesFromEnd (line 1387) | private void recycleFlexLinesFromEnd(RecyclerView.Recycler recycler, L...
    method canViewBeRecycledFromEnd (line 1434) | private boolean canViewBeRecycledFromEnd(View view, int scrollingOffse...
    method recycleChildren (line 1449) | private void recycleChildren(RecyclerView.Recycler recycler, int start...
    method layoutFlexLine (line 1455) | private int layoutFlexLine(FlexLine flexLine, LayoutState layoutState) {
    method layoutFlexLineMainAxisHorizontal (line 1463) | private int layoutFlexLineMainAxisHorizontal(FlexLine flexLine, Layout...
    method layoutFlexLineMainAxisVertical (line 1578) | private int layoutFlexLineMainAxisVertical(FlexLine flexLine, LayoutSt...
    method isMainAxisDirectionHorizontal (line 1711) | @Override
    method updateLayoutStateToFillEnd (line 1729) | private void updateLayoutStateToFillEnd(AnchorInfo anchorInfo, boolean...
    method updateLayoutStateToFillStart (line 1771) | private void updateLayoutStateToFillStart(AnchorInfo anchorInfo, boole...
    method resolveInfiniteAmount (line 1800) | private void resolveInfiniteAmount() {
    method ensureOrientationHelper (line 1818) | private void ensureOrientationHelper() {
    method ensureLayoutState (line 1849) | private void ensureLayoutState() {
    method scrollToPosition (line 1855) | @Override
    method smoothScrollToPosition (line 1865) | @Override
    method getRecycleChildrenOnDetach (line 1878) | @SuppressWarnings("UnusedDeclaration")
    method setRecycleChildrenOnDetach (line 1896) | @SuppressWarnings("UnusedDeclaration")
    method onAttachedToWindow (line 1901) | @Override
    method onDetachedFromWindow (line 1907) | @Override
    method canScrollHorizontally (line 1919) | @Override
    method canScrollVertically (line 1928) | @Override
    method scrollHorizontallyBy (line 1937) | @Override
    method scrollVerticallyBy (line 1952) | @Override
    method handleScrollingMainOrientation (line 1977) | private int handleScrollingMainOrientation(int delta, RecyclerView.Rec...
    method handleScrollingSubOrientation (line 2018) | private int handleScrollingSubOrientation(int delta) {
    method updateLayoutState (line 2059) | private void updateLayoutState(int layoutDirection, int absDelta) {
    method findFirstReferenceViewInLine (line 2176) | private View findFirstReferenceViewInLine(View firstView, FlexLine fir...
    method findLastReferenceViewInLine (line 2208) | private View findLastReferenceViewInLine(View lastView, FlexLine lastV...
    method computeHorizontalScrollExtent (line 2234) | @Override
    method computeVerticalScrollExtent (line 2243) | @Override
    method computeScrollExtent (line 2252) | private int computeScrollExtent(RecyclerView.State state) {
    method computeHorizontalScrollOffset (line 2269) | @Override
    method computeVerticalScrollOffset (line 2278) | @Override
    method computeScrollOffset (line 2287) | private int computeScrollOffset(RecyclerView.State state) {
    method computeHorizontalScrollRange (line 2315) | @Override
    method computeVerticalScrollRange (line 2324) | @Override
    method computeScrollRange (line 2340) | private int computeScrollRange(RecyclerView.State state) {
    method shouldMeasureChild (line 2364) | private boolean shouldMeasureChild(View child, int widthSpec, int heig...
    method isMeasurementUpToDate (line 2377) | private static boolean isMeasurementUpToDate(int childSize, int spec, ...
    method clearFlexLines (line 2394) | private void clearFlexLines() {
    method getChildLeft (line 2400) | private int getChildLeft(View view) {
    method getChildRight (line 2406) | private int getChildRight(View view) {
    method getChildTop (line 2412) | private int getChildTop(View view) {
    method getChildBottom (line 2418) | private int getChildBottom(View view) {
    method isViewVisible (line 2433) | private boolean isViewVisible(View view, boolean completelyVisible) {
    method findFirstVisibleItemPosition (line 2480) | @SuppressWarnings("WeakerAccess")
    method findFirstCompletelyVisibleItemPosition (line 2495) | @SuppressWarnings("WeakerAccess")
    method findLastVisibleItemPosition (line 2514) | @SuppressWarnings("WeakerAccess")
    method findLastCompletelyVisibleItemPosition (line 2529) | @SuppressWarnings("WeakerAccess")
    method findOneVisibleChild (line 2547) | private View findOneVisibleChild(int fromIndex, int toIndex, boolean c...
    method getPositionToFlexLineIndex (line 2563) | int getPositionToFlexLineIndex(int position) {
    class LayoutParams (line 2576) | public static class LayoutParams extends RecyclerView.LayoutParams imp...
      method getWidth (line 2623) | @Override
      method setWidth (line 2628) | @Override
      method getHeight (line 2633) | @Override
      method setHeight (line 2638) | @Override
      method getFlexGrow (line 2643) | @Override
      method setFlexGrow (line 2648) | @Override
      method getFlexShrink (line 2653) | @Override
      method setFlexShrink (line 2658) | @Override
      method getAlignSelf (line 2663) | @AlignSelf
      method setAlignSelf (line 2669) | @Override
      method getMinWidth (line 2674) | @Override
      method setMinWidth (line 2679) | @Override
      method getMinHeight (line 2684) | @Override
      method setMinHeight (line 2689) | @Override
      method getMaxWidth (line 2694) | @Override
      method setMaxWidth (line 2699) | @Override
      method getMaxHeight (line 2704) | @Override
      method setMaxHeight (line 2709) | @Override
      method isWrapBefore (line 2714) | @Override
      method setWrapBefore (line 2719) | @Override
      method getFlexBasisPercent (line 2724) | @Override
      method setFlexBasisPercent (line 2729) | @Override
      method getMarginLeft (line 2734) | @Override
      method getMarginTop (line 2739) | @Override
      method getMarginRight (line 2744) | @Override
      method getMarginBottom (line 2749) | @Override
      method LayoutParams (line 2754) | public LayoutParams(Context c, AttributeSet attrs) {
      method LayoutParams (line 2758) | public LayoutParams(int width, int height) {
      method LayoutParams (line 2762) | public LayoutParams(ViewGroup.MarginLayoutParams source) {
      method LayoutParams (line 2766) | public LayoutParams(ViewGroup.LayoutParams source) {
      method LayoutParams (line 2770) | public LayoutParams(RecyclerView.LayoutParams source) {
      method LayoutParams (line 2774) | public LayoutParams(LayoutParams source) {
      method getOrder (line 2788) | @Override
      method setOrder (line 2793) | @Override
      method describeContents (line 2804) | @Override
      method writeToParcel (line 2809) | @Override
      method LayoutParams (line 2828) | protected LayoutParams(Parcel in) {
      method createFromParcel (line 2849) | @Override
      method newArray (line 2854) | @Override
    class AnchorInfo (line 2865) | private class AnchorInfo {
      method reset (line 2884) | private void reset() {
      method assignCoordinateFromPadding (line 2905) | private void assignCoordinateFromPadding() {
      method assignFromView (line 2915) | private void assignFromView(View anchor) {
      method toString (line 2956) | @Override
    class LayoutState (line 2975) | private static class LayoutState {
      method hasMore (line 3024) | private boolean hasMore(RecyclerView.State state, List<FlexLine> fle...
      method toString (line 3029) | @Override
    class SavedState (line 3048) | private static class SavedState implements Parcelable {
      method describeContents (line 3059) | @Override
      method writeToParcel (line 3064) | @Override
      method SavedState (line 3070) | SavedState() {
      method SavedState (line 3073) | private SavedState(Parcel in) {
      method SavedState (line 3078) | private SavedState(SavedState savedState) {
      method invalidateAnchor (line 3083) | private void invalidateAnchor() {
      method hasValidAnchor (line 3087) | private boolean hasValidAnchor(int itemCount) {
      method createFromParcel (line 3092) | @Override
      method newArray (line 3097) | @Override
      method toString (line 3103) | @Override
Condensed preview — 181 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,163K chars).
[
  {
    "path": ".circleci/config.yml",
    "chars": 1993,
    "preview": "version: 2\njobs:\n  build:\n    working_directory: ~/code\n    docker:\n      - image: circleci/android:api-29\n    environme"
  },
  {
    "path": ".github/issue_template.md",
    "chars": 541,
    "preview": "- [ ] I have searched [existing issues](https://github.com/google/flexbox-layout/issues) and confirmed this is not a dup"
  },
  {
    "path": ".github/workflows/gradle-wrapper-validation.yml",
    "chars": 223,
    "preview": "name: \"Validate Gradle Wrapper\"\non: [push, pull_request]\n\njobs:\n  validation:\n    name: \"Validation\"\n    runs-on: ubuntu"
  },
  {
    "path": ".gitignore",
    "chars": 659,
    "preview": "*.iml\n.gradle\n.idea/\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n!.idea/codeStyleSettings.xml\n.DS_Store\n/bui"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 2076,
    "preview": "# How to become a contributor and submit your own code\n\n## Contributor License Agreements\n\nWe'd love to accept your samp"
  },
  {
    "path": "LICENSE",
    "chars": 11341,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "README.md",
    "chars": 18247,
    "preview": "# FlexboxLayout\n[ ![Circle CI](https://circleci.com/gh/google/flexbox-layout.svg?style=shield&circle-token=2a42716dfffab"
  },
  {
    "path": "build.gradle",
    "chars": 2580,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-cat-gallery/build.gradle",
    "chars": 1723,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-cat-gallery/proguard-rules.pro",
    "chars": 675,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /u"
  },
  {
    "path": "demo-cat-gallery/src/main/AndroidManifest.xml",
    "chars": 799,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n          pa"
  },
  {
    "path": "demo-cat-gallery/src/main/java/com/google/android/flexbox/apps/catgallery/CatAdapter.kt",
    "chars": 2171,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-cat-gallery/src/main/java/com/google/android/flexbox/apps/catgallery/CatViewHolder.kt",
    "chars": 1331,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-cat-gallery/src/main/java/com/google/android/flexbox/apps/catgallery/MainActivity.kt",
    "chars": 2154,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-cat-gallery/src/main/res/layout/activity_main.xml",
    "chars": 2274,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2017 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-cat-gallery/src/main/res/layout/content_main.xml",
    "chars": 966,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2017 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-cat-gallery/src/main/res/layout/viewholder_cat.xml",
    "chars": 954,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2017 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-cat-gallery/src/main/res/values/colors.xml",
    "chars": 790,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2017 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-cat-gallery/src/main/res/values/dimens.xml",
    "chars": 693,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2017 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-cat-gallery/src/main/res/values/strings.xml",
    "chars": 769,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2017 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-cat-gallery/src/main/res/values/styles.xml",
    "chars": 1324,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2017 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-cat-gallery/src/main/res/values-v21/styles.xml",
    "chars": 947,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2017 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/build.gradle",
    "chars": 2237,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-playground/proguard-rules.pro",
    "chars": 1243,
    "preview": "#\n# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n"
  },
  {
    "path": "demo-playground/src/androidTest/java/com/google/android/apps/flexbox/test/MainActivityTest.kt",
    "chars": 13683,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-playground/src/main/AndroidManifest.xml",
    "chars": 1598,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/src/main/java/com/google/android/flexbox/Extensions.kt",
    "chars": 1537,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-playground/src/main/java/com/google/android/flexbox/FlexItemAdapter.kt",
    "chars": 2440,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-playground/src/main/java/com/google/android/flexbox/FlexItemChangedListener.kt",
    "chars": 828,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-playground/src/main/java/com/google/android/flexbox/FlexItemChangedListenerImpl.kt",
    "chars": 1070,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-playground/src/main/java/com/google/android/flexbox/FlexItemChangedListenerImplRecyclerView.kt",
    "chars": 1592,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-playground/src/main/java/com/google/android/flexbox/FlexItemClickListener.kt",
    "chars": 1455,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-playground/src/main/java/com/google/android/flexbox/FlexItemEditFragment.kt",
    "chars": 17716,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-playground/src/main/java/com/google/android/flexbox/FlexItemViewHolder.kt",
    "chars": 1369,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-playground/src/main/java/com/google/android/flexbox/FlexboxLayoutFragment.kt",
    "chars": 4515,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-playground/src/main/java/com/google/android/flexbox/FragmentHelper.kt",
    "chars": 15108,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-playground/src/main/java/com/google/android/flexbox/MainActivity.kt",
    "chars": 4098,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-playground/src/main/java/com/google/android/flexbox/RecyclerViewFragment.kt",
    "chars": 3540,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-playground/src/main/java/com/google/android/flexbox/SettingsActivity.kt",
    "chars": 5870,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-playground/src/main/java/com/google/android/flexbox/validators/DimensionInputValidator.kt",
    "chars": 1155,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-playground/src/main/java/com/google/android/flexbox/validators/FixedDimensionInputValidator.kt",
    "chars": 950,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-playground/src/main/java/com/google/android/flexbox/validators/FlexBasisPercentInputValidator.kt",
    "chars": 1038,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-playground/src/main/java/com/google/android/flexbox/validators/InputValidator.kt",
    "chars": 988,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-playground/src/main/java/com/google/android/flexbox/validators/IntegerInputValidator.kt",
    "chars": 890,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-playground/src/main/java/com/google/android/flexbox/validators/NonNegativeDecimalInputValidator.kt",
    "chars": 916,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "demo-playground/src/main/res/drawable/flex_item_background.xml",
    "chars": 829,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache L"
  },
  {
    "path": "demo-playground/src/main/res/drawable/side_nav_bar.xml",
    "chars": 912,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache L"
  },
  {
    "path": "demo-playground/src/main/res/layout/activity_main.xml",
    "chars": 1568,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/src/main/res/layout/app_bar_main.xml",
    "chars": 2494,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/src/main/res/layout/content_main.xml",
    "chars": 931,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/src/main/res/layout/fragment_flex_item_edit.xml",
    "chars": 10605,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/src/main/res/layout/fragment_flexboxlayout.xml",
    "chars": 1823,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/src/main/res/layout/fragment_recyclerview.xml",
    "chars": 842,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/src/main/res/layout/nav_header_main.xml",
    "chars": 2669,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/src/main/res/layout/spinner_align_content.xml",
    "chars": 888,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/src/main/res/layout/spinner_align_items.xml",
    "chars": 886,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/src/main/res/layout/spinner_flex_direction.xml",
    "chars": 889,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/src/main/res/layout/spinner_flex_wrap.xml",
    "chars": 884,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/src/main/res/layout/spinner_item.xml",
    "chars": 1148,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/src/main/res/layout/spinner_justify_content.xml",
    "chars": 890,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/src/main/res/layout/viewholder_flex_item.xml",
    "chars": 828,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/src/main/res/menu/activity_main_drawer.xml",
    "chars": 1710,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/src/main/res/menu/menu_main.xml",
    "chars": 1036,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/src/main/res/values/colors.xml",
    "chars": 834,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/src/main/res/values/dimens.xml",
    "chars": 1472,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/src/main/res/values/strings.xml",
    "chars": 7070,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/src/main/res/values/styles.xml",
    "chars": 1632,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/src/main/res/values-v14/styles.xml",
    "chars": 1080,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/src/main/res/values-v21/styles.xml",
    "chars": 1049,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/src/main/res/values-w720dp/dimens.xml",
    "chars": 832,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "demo-playground/src/main/res/xml/new_flex_item_preferences.xml",
    "chars": 2592,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "flexbox/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "flexbox/build.gradle",
    "chars": 2333,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/constants.gradle",
    "chars": 894,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/maven-puglisher-plugin.gradle",
    "chars": 1906,
    "preview": "/*\n * Copyright 2021 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/proguard-rules.txt",
    "chars": 888,
    "preview": "#\n# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n"
  },
  {
    "path": "flexbox/src/androidTest/AndroidManifest.xml",
    "chars": 1008,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apac"
  },
  {
    "path": "flexbox/src/androidTest/java/com/google/android/flexbox/FakeFlexContainer.kt",
    "chars": 4291,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/androidTest/java/com/google/android/flexbox/FlexboxHelperTest.kt",
    "chars": 28287,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/androidTest/java/com/google/android/flexbox/test/ConfigChangeActivity.kt",
    "chars": 1261,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/androidTest/java/com/google/android/flexbox/test/FlexboxAndroidTest.kt",
    "chars": 208228,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/androidTest/java/com/google/android/flexbox/test/FlexboxLayoutManagerConfigChangeTest.kt",
    "chars": 7339,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/androidTest/java/com/google/android/flexbox/test/FlexboxLayoutManagerTest.kt",
    "chars": 175566,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/androidTest/java/com/google/android/flexbox/test/FlexboxTestActivity.kt",
    "chars": 828,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/androidTest/java/com/google/android/flexbox/test/IsEqualAllowingError.kt",
    "chars": 1713,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/androidTest/java/com/google/android/flexbox/test/NestedInnerAdapter.kt",
    "chars": 1778,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/androidTest/java/com/google/android/flexbox/test/NestedOuterAdapter.kt",
    "chars": 2407,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/androidTest/java/com/google/android/flexbox/test/TestAdapter.kt",
    "chars": 2612,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/androidTest/java/com/google/android/flexbox/test/TestAdapterMultiViewTypes.kt",
    "chars": 2702,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/androidTest/java/com/google/android/flexbox/test/TestUtil.kt",
    "chars": 866,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/androidTest/java/com/google/android/flexbox/test/TestViewHolder.kt",
    "chars": 983,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/androidTest/res/drawable/divider.xml",
    "chars": 806,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "flexbox/src/androidTest/res/drawable/divider_thick.xml",
    "chars": 806,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "flexbox/src/androidTest/res/drawable/flex_item_background.xml",
    "chars": 871,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ Copyright 2016 Google Inc. All rights reserved.\n  ~\n  ~ Licensed under t"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_align_content_test.xml",
    "chars": 1481,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_align_content_test_overflowed.xml",
    "chars": 1940,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2017 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_align_items_baseline_test.xml",
    "chars": 1618,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_align_items_baseline_wrap_content.xml",
    "chars": 1619,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2017 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_align_items_parent_padding_test.xml",
    "chars": 1357,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_align_items_test.xml",
    "chars": 1513,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_align_self_stretch_test.xml",
    "chars": 1552,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_child_needs_remeasure_column.xml",
    "chars": 1606,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2017 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_child_needs_remeasure_row.xml",
    "chars": 1603,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2017 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_direction_column_align_items_center_margin_oneside.xml",
    "chars": 1245,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright 2016 Google Inc. All rights reserved.\n  ~\n  ~ Licensed under th"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_direction_row_align_items_center_margin_oneside.xml",
    "chars": 1243,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright 2016 Google Inc. All rights reserved.\n  ~\n  ~ Licensed under th"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_divider_test_direction_column.xml",
    "chars": 1908,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_divider_test_direction_row.xml",
    "chars": 1901,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_empty_children.xml",
    "chars": 973,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_first_item_large_horizontal_test.xml",
    "chars": 1507,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_first_item_large_vertical_test.xml",
    "chars": 1509,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_first_view_gone_first_line_single_item.xml",
    "chars": 1790,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2017 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_first_view_gone_layout_grow_set_for_rest.xml",
    "chars": 1846,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2017 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_first_view_gone_layout_shrink_set_for_rest.xml",
    "chars": 1850,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2017 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_flex_basis_percent_test.xml",
    "chars": 1538,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_flex_grow_test.xml",
    "chars": 1490,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_flex_item_match_parent.xml",
    "chars": 1549,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_flex_item_match_parent_direction_column.xml",
    "chars": 1552,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_flex_wrap_test.xml",
    "chars": 1618,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_flexbox_wrap_content.xml",
    "chars": 1660,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_flexbox_wrapped_with_horizontalscrollview.xml",
    "chars": 1818,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_flexbox_wrapped_with_scrollview.xml",
    "chars": 1774,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_justify_content_test.xml",
    "chars": 1470,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_justify_content_with_gone.xml",
    "chars": 1534,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright 2016 Google Inc. All rights reserved.\n  ~\n  ~ Licensed under th"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_justify_content_with_parent_padding.xml",
    "chars": 1763,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_maxheight_test.xml",
    "chars": 1360,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_maxheight_upper_bound_test.xml",
    "chars": 1421,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_maxwidth_test.xml",
    "chars": 1328,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_maxwidth_upper_bound_test.xml",
    "chars": 1389,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_minheight_lower_bound_test.xml",
    "chars": 1671,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_minheight_test.xml",
    "chars": 1367,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_minwidth_lower_bound_test.xml",
    "chars": 1639,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_minwidth_test.xml",
    "chars": 1335,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_order_test.xml",
    "chars": 1579,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_simple.xml",
    "chars": 1296,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_stretch_test.xml",
    "chars": 1508,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_views_visibility_gone.xml",
    "chars": 1819,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_views_visibility_invisible.xml",
    "chars": 1529,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_visibility_gone_first_item_in_flex_line_column.xml",
    "chars": 1517,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_visibility_gone_first_item_in_flex_line_row.xml",
    "chars": 1514,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_wrap_before_test.xml",
    "chars": 1528,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_wrap_child_margin_horizontal_test.xml",
    "chars": 1522,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_wrap_child_margin_vertical_test.xml",
    "chars": 1524,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_wrap_content_child_bottom_margin_column_grow.xml",
    "chars": 1424,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright 2016 Google Inc. All rights reserved.\n  ~\n  ~ Licensed under th"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_wrap_content_child_bottom_margin_column_shrink.xml",
    "chars": 1530,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright 2016 Google Inc. All rights reserved.\n  ~\n  ~ Licensed under th"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_wrap_content_child_bottom_margin_row_grow.xml",
    "chars": 1356,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright 2016 Google Inc. All rights reserved.\n  ~\n  ~ Licensed under th"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_wrap_content_child_bottom_margin_row_shrink.xml",
    "chars": 1468,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright 2016 Google Inc. All rights reserved.\n  ~\n  ~ Licensed under th"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_wrap_parent_padding_horizontal_test.xml",
    "chars": 1512,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_wrap_parent_padding_vertical_test.xml",
    "chars": 1514,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2016 Google Inc. All rights reserved.\n\n  Licensed under the Apach"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_zero_height_positive_flexgrow.xml",
    "chars": 1446,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright 2016 Google Inc. All rights reserved.\n  ~\n  ~ Licensed under th"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/activity_zero_width_positive_flexgrow.xml",
    "chars": 1414,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright 2016 Google Inc. All rights reserved.\n  ~\n  ~ Licensed under th"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/recyclerview.xml",
    "chars": 1051,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright 2016 Google Inc. All rights reserved.\n  ~\n  ~ Licensed under th"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/recyclerview_reverse.xml",
    "chars": 1110,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright 2016 Google Inc. All rights reserved.\n  ~\n  ~ Licensed under th"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/recyclerview_viewholder.xml",
    "chars": 842,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright 2016 Google Inc. All rights reserved.\n  ~\n  ~ Licensed under th"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/viewholder_inner_recyclerview.xml",
    "chars": 1007,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright 2017 Google Inc. All rights reserved.\n  ~\n  ~ Licensed under th"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/viewholder_inner_recyclerview_wrap_horizontally.xml",
    "chars": 1007,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright 2017 Google Inc. All rights reserved.\n  ~\n  ~ Licensed under th"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/viewholder_textview.xml",
    "chars": 892,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright 2017 Google Inc. All rights reserved.\n  ~\n  ~ Licensed under th"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/wrapped_recyclerview.xml",
    "chars": 1292,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright 2017 Google Inc. All rights reserved.\n  ~\n  ~ Licensed under th"
  },
  {
    "path": "flexbox/src/androidTest/res/layout/wrapped_recyclerview_scroll_vertical.xml",
    "chars": 1292,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright 2017 Google Inc. All rights reserved.\n  ~\n  ~ Licensed under th"
  },
  {
    "path": "flexbox/src/androidTest/res/values/strings.xml",
    "chars": 703,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2017 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "flexbox/src/main/AndroidManifest.xml",
    "chars": 672,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache L"
  },
  {
    "path": "flexbox/src/main/java/com/google/android/flexbox/AlignContent.java",
    "chars": 1898,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/main/java/com/google/android/flexbox/AlignItems.java",
    "chars": 1472,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/main/java/com/google/android/flexbox/AlignSelf.java",
    "chars": 1978,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/main/java/com/google/android/flexbox/FlexContainer.java",
    "chars": 9173,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/main/java/com/google/android/flexbox/FlexDirection.java",
    "chars": 1931,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/main/java/com/google/android/flexbox/FlexItem.java",
    "chars": 8910,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/main/java/com/google/android/flexbox/FlexLine.java",
    "chars": 5784,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/main/java/com/google/android/flexbox/FlexWrap.java",
    "chars": 1342,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/main/java/com/google/android/flexbox/FlexboxHelper.java",
    "chars": 103502,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/main/java/com/google/android/flexbox/FlexboxItemDecoration.java",
    "chars": 11439,
    "preview": "/*\n * Copyright 2017 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/main/java/com/google/android/flexbox/FlexboxLayout.java",
    "chars": 73115,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/main/java/com/google/android/flexbox/FlexboxLayoutManager.java",
    "chars": 127399,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/main/java/com/google/android/flexbox/JustifyContent.java",
    "chars": 2136,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "flexbox/src/main/res/values/attrs.xml",
    "chars": 6632,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\nCopyright 2016 Google Inc. All rights reserved.\n\nLicensed under the Apache Li"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "chars": 232,
    "preview": "#Mon Sep 09 14:42:19 PDT 2019\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
  },
  {
    "path": "gradle.properties",
    "chars": 1511,
    "preview": "#\n# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n"
  },
  {
    "path": "gradlew",
    "chars": 5296,
    "preview": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up"
  },
  {
    "path": "gradlew.bat",
    "chars": 2260,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@r"
  },
  {
    "path": "settings.gradle",
    "chars": 678,
    "preview": "/*\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "tool/codeStyleSettings.xml",
    "chars": 13889,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectCodeStyleSettingsManager\">\n    <o"
  }
]

// ... and 1 more files (download for full content)

About this extraction

This page contains the full source code of the google/flexbox-layout GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 181 files (1.1 MB), approximately 253.1k tokens, and a symbol index with 429 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!