add flutter
55
OnTime_Merchant_live/lib/flexbox-layout/demo-playground/build.gradle
Executable file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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}"
|
||||
}
|
||||
33
OnTime_Merchant_live/lib/flexbox-layout/demo-playground/proguard-rules.pro
vendored
Executable file
@@ -0,0 +1,33 @@
|
||||
#
|
||||
# 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 *;
|
||||
#}
|
||||
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
* 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))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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)
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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)
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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:
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,369 @@
|
||||
/*
|
||||
* 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,340 @@
|
||||
/*
|
||||
* 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"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 127 B |
|
After Width: | Height: | Size: 104 B |
|
After Width: | Height: | Size: 88 B |
|
After Width: | Height: | Size: 82 B |
|
After Width: | Height: | Size: 97 B |
|
After Width: | Height: | Size: 90 B |
|
After Width: | Height: | Size: 97 B |
|
After Width: | Height: | Size: 94 B |
|
After Width: | Height: | Size: 102 B |
|
After Width: | Height: | Size: 97 B |
@@ -0,0 +1,20 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,39 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,58 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?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" />
|
||||
|
||||
@@ -0,0 +1,261 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,48 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,19 @@
|
||||
<?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" />
|
||||
@@ -0,0 +1,66 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,21 @@
|
||||
<?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" />
|
||||
@@ -0,0 +1,21 @@
|
||||
<?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" />
|
||||
@@ -0,0 +1,21 @@
|
||||
<?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" />
|
||||
@@ -0,0 +1,21 @@
|
||||
<?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" />
|
||||
@@ -0,0 +1,27 @@
|
||||
<?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" />
|
||||
@@ -0,0 +1,21 @@
|
||||
<?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" />
|
||||
@@ -0,0 +1,19 @@
|
||||
<?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" />
|
||||
@@ -0,0 +1,40 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?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>
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 9.6 KiB |
@@ -0,0 +1,26 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,21 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,36 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,138 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,44 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,65 @@
|
||||
<?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" />
|
||||
|
||||
<EditTextPreference
|
||||
android:key="@string/new_flex_shrink_key"
|
||||
android:title="@string/hint_flex_shrink"
|
||||
android:inputType="numberDecimal"
|
||||
android:persistent="true"
|
||||
android:defaultValue="1.0" />
|
||||
|
||||
<EditTextPreference
|
||||
android:key="@string/new_flex_basis_percent_key"
|
||||
android:title="@string/flex_basis_percent"
|
||||
android:summary="@string/flex_basis_percent_summary"
|
||||
android:inputType="numberSigned"
|
||||
android:persistent="true"
|
||||
android:defaultValue="-1" />
|
||||
|
||||
<EditTextPreference
|
||||
android:key="@string/new_width_key"
|
||||
android:title="@string/width"
|
||||
android:summary="@string/size_unit_summary"
|
||||
android:inputType="numberSigned"
|
||||
android:persistent="true"
|
||||
android:defaultValue="120" />
|
||||
|
||||
<EditTextPreference
|
||||
android:key="@string/new_height_key"
|
||||
android:title="@string/height"
|
||||
android:summary="@string/size_unit_summary"
|
||||
android:inputType="numberSigned"
|
||||
android:persistent="true"
|
||||
android:defaultValue="80" />
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
||||