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
[  ](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.

## 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|||
|flexWrap|| (except `wrap_reverse`)|
|justifyContent|||
|alignItems|||
|alignContent|| - |
|layout_order|| - |
|layout_flexGrow|||
|layout_flexShrink|||
|layout_alignSelf|||
|layout_flexBasisPercent|||
|layout_(min/max)Width|||
|layout_(min/max)Height|||
|layout_wrapBefore|||
|Divider|||
|View recycling| - ||
|Scrolling| *1 ||
*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

* __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)

* __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

* __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)

* __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

* __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" />
```

## 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.

* __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.

* __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.

* __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

* __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.

* __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.

* __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.

* __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.

# 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
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
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[ ;\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.