Skip to content

Commit

Permalink
Merge branch 'release-2.3.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark Ormesher committed Aug 5, 2018
2 parents 96910c6 + a44c42d commit ad96356
Show file tree
Hide file tree
Showing 17 changed files with 80,695 additions and 69 deletions.
52 changes: 35 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ You can try the demo in one of two ways:

### Gradle

compile 'uk.co.markormesher:android-fab:2.0.0'
compile 'uk.co.markormesher:android-fab:2.3.1'

### Maven

<dependency>
<groupId>uk.co.markormesher</groupId>
<artifactId>android-fab</artifactId>
<version>2.0.0</version>
<version>2.3.1</version>
<type>pom</type>
</dependency>

Expand All @@ -43,7 +43,7 @@ See [app/proguard-rules.pro](app/proguard-rules.pro) for an example.

// Java
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);

// Kotlin (without Android extensions)
val fab = findViewById(R.id.fab) as FloatingActionButton

Expand All @@ -63,17 +63,17 @@ The FAB can be positioned in any of the four corners of the activity via XML or

// Java
fab.setButtonPosition(POSITION_BOTTOM | POSITION_END);

// Kotlin
fab.setButtonPosition(POSITION_BOTTOM.or(POSITION_END))

// XML
<uk.co.markormesher.android_fab.FloatingActionButton
xmlns:app="http://schemas.android.com/apk/res-auto"
...
app:buttonPosition="bottom|end"
/>

The FAB is aware of text-direction (right-to-left or left-to-right) and adjusts the meaning of "start" and "end" positions accordingly. This functionality can be overridden using the named constants for left and right.

### FAB Icon
Expand All @@ -82,10 +82,10 @@ The icon displayed in the centre of the FAB can be set via XML using a `Drawable

// Java
fab.setButtonIconResource(R.drawable.ic_add);

// Kotlin
fab.setButtonIconResource(R.drawable.ic_add)

// XML
<uk.co.markormesher.android_fab.FloatingActionButton
xmlns:app="http://schemas.android.com/apk/res-auto"
Expand All @@ -99,10 +99,10 @@ The background colour of the FAB can be set via XML using a colour reference or

// Java
fab.setButtonBackgroundColour(0xffff9900);

// Kotlin
fab.setButtonBackgroundColour(0xffff9900.toInt())

// XML
<uk.co.markormesher.android_fab.FloatingActionButton
xmlns:app="http://schemas.android.com/apk/res-auto"
Expand All @@ -121,15 +121,15 @@ A click listener can be added to the FAB in the same way as any other button. Th
// ...
}
});

// Kotlin
fab.setOnClickListener { v ->
// ...
}

### Speed-Dial Menu

The speed-dial menu is enabled by creating a class that extends `SpeedDialMenuAdapter` and passing it to `fab.setSpeedDialMenuAdapter(...)`. The adapter class methods are [documented in-situ](fab/src/main/java/uk/co/markormesher/android_fab/SpeedDialMenuAdapter.kt).
The speed-dial menu is enabled by creating a class that extends `SpeedDialMenuAdapter` and passing it to `fab.setSpeedDialMenuAdapter(...)`. The adapter class methods are [documented in-situ](fab/src/main/kotlin/uk/co/markormesher/android_fab/SpeedDialMenuAdapter.kt).

### Speed-Dial Menu Content Cover

Expand All @@ -139,7 +139,7 @@ The colour of the content cover can be set programmatically with `fab.setContent

// Java
fab.setContentCoverColour(0xffff9900);

// Kotlin
fab.setContentCoverColour(0xffff9900.toInt())

Expand All @@ -148,7 +148,7 @@ The cover can be enabled/disabled programmatically with `fab.setContentCoverEnab
// Java
fab.setContentCoverEnabled(true);
fab.setContentCoverEnabled(false);

// Kotlin
fab.setContentCoverEnabled(true)
fab.setContentCoverEnabled(false)
Expand All @@ -164,26 +164,44 @@ State change events are fired when the speed-dial menu opens or closes, which ca
// ...
}
});

// Kotlin
fab.setOnSpeedDialMenuOpenListener { floatingActionButton ->
// ...
}

### Show/Hide Controls

The FAB can be hidden and shown with the `fab.hide()` and `fab.show()` methods, and the method `fab.isShown()` will return a boolean indicating the current state. These methods animate the FAB in and out of visibility. If the speed-dial menu is open when `.hide()` is called it will be closed.
The FAB can be hidden and shown with the `fab.hide()` and `fab.show()` methods, and the method `fab.isShown()` will return a boolean indicating the current state. These methods animate the FAB in and out of visibility. If the speed-dial menu is open when `.hide()` is called it will be closed.

The speed-dial menu can be manually opened and closed with `fab.openSpeedDialMenu()` and `fab.closeSpeedDialMenu()`. These methods will do nothing if no speed-dial menu adapter is set, if an adapter is set but disabled, if the FAB is hidden, or if they are called when the menu is already in the indicated state (i.e. `fab.openSpeedDialMenu()` will do nothing if the menu is already open).

### Access to Underlying Views

The FAB's key underlying views can be accessed using the three properties/methods detailed below:

// Java
fab.getCardView() // the card behind the button itself
fab.getContentCoverView() // the view that obscures content behind the speed-dial menu
fab.getIconWrapper() // the wrapper used to place icons in the button

// Kotlin
fab.cardView
fab.contentCoverView
fab.iconWrapper

The card view is implemented as a `CardView` on SDK 21+ and a `LinearLayout` on SDK 20 and below.

The content cover view and icon wrapper are implemented as a `View` and `LinearLayout` respectively on all SDKs.

### Note: Click Action Priority

As per Material Design specs, the FAB functions as a regular button **or** a trigger for the speed-dial menu, but not both. For this reason, the click listener and the speed-dial menu are never invoked at the same time.

The speed-dial menu is given priority: when the FAB is clicked the speed-dial menu will be shown if the speed-dial menu adapter is non-null, the adapter's `isEnabled()` function returns `true` and the adapter's `getCount()` returns a number greater than zero. Otherwise, the FAB's click listener will be called (if it has been set).

Setting a speed-dial menu adapter does not remove the click listener, and setting a click listener does not remove the speed-dial menu adapter. For an example of how the two operation modes interact, check the demo app's source code.

To receive state change updates when the speed-dial menu is opened or closed, use the open/close listeners described above.

### Note: State Preservation
Expand Down
31 changes: 18 additions & 13 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
buildscript {
repositories {
jcenter()
maven {
url "https://maven.google.com"
}
google()
}

dependencies {
classpath 'com.android.tools.build:gradle:2.3.0'
classpath 'com.android.tools.build:gradle:3.1.3'
}
}

Expand All @@ -16,14 +20,14 @@ apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {
compileSdkVersion 26
buildToolsVersion "26.0.1"
compileSdkVersion 27
buildToolsVersion '27.0.3'

defaultConfig {
applicationId "uk.co.markormesher.android_fab.app"

minSdkVersion 14
targetSdkVersion 26
targetSdkVersion 27

versionCode properties['version_code']
versionName properties['version_name']
Expand Down Expand Up @@ -58,10 +62,6 @@ android {
}

debug {
// signing
//noinspection GroovyAssignabilityCheck
signingConfig signingConfigs.main

// minify
minifyEnabled false

Expand All @@ -74,12 +74,17 @@ android {

repositories {
jcenter()
maven {
url "https://maven.google.com"
}
google()
}

dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:support-v4:26.0.1'
compile 'com.android.support:appcompat-v7:26.0.1'
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
compile project(':fab')
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:support-v4:27.1.1'
implementation 'com.android.support:design:27.1.1'
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation project(':fab')
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package uk.co.markormesher.android_fab.app

import android.content.Context
import android.graphics.Typeface
import android.os.*
import android.support.annotation.StringRes
import android.support.design.widget.Snackbar
import android.support.v7.app.AppCompatActivity
import android.view.KeyEvent
import android.view.Menu
import android.view.MenuItem
import android.view.MotionEvent
import android.widget.TextView
import android.widget.Toast
import kotlinx.android.synthetic.main.demo_activity.*
import uk.co.markormesher.android_fab.FloatingActionButton
Expand Down Expand Up @@ -63,14 +66,21 @@ class DemoActivity: AppCompatActivity() {
Pair("Faint Orange", 0xccff9900.toInt())
)

private val snackbarEnabledOptions = arrayOf(
Pair("Off", 0),
Pair("On", 1)
)

private var buttonShown = 0
private var buttonPosition = 0
private var buttonBackgroundColour = 0
private var buttonIcon = 0
private var speedDialSize = 0
private var contentCoverColour = 0
private var snackbarEnabled = 0

private var activeToast: Toast? = null
private var snackbar: Snackbar? = null
private var clickCounter = 0

private var stressTestActive = false
Expand Down Expand Up @@ -99,6 +109,14 @@ class DemoActivity: AppCompatActivity() {
return true
}

override fun onPrepareItemLabel(context: Context, position: Int, label: TextView) {
// make the first item bold if there are multiple items
// (this isn't a design pattern, it's just to demo the functionality)
if (position == 0 && speedDialSize > 1) {
label.setTypeface(label.typeface, Typeface.BOLD)
}
}

// rotate the "+" icon only
override fun fabRotationDegrees(): Float = if (buttonIcon == 0) 135F else 0F
}
Expand All @@ -121,6 +139,7 @@ class DemoActivity: AppCompatActivity() {
updateButtonIcon()
updateSpeedDialSize()
updateContentCoverColour()
updateSnackbarEnabled()

if (stressTestActive) {
startStressTest()
Expand All @@ -135,6 +154,7 @@ class DemoActivity: AppCompatActivity() {
outState.putInt("buttonIcon", buttonIcon)
outState.putInt("speedDialSize", speedDialSize)
outState.putInt("contentCoverColour", contentCoverColour)
outState.putInt("snackbarEnabled", snackbarEnabled)

outState.putBoolean("stressTestActive", stressTestActive)
}
Expand All @@ -147,6 +167,7 @@ class DemoActivity: AppCompatActivity() {
buttonIcon = savedInstanceState.getInt("buttonIcon")
speedDialSize = savedInstanceState.getInt("speedDialSize")
contentCoverColour = savedInstanceState.getInt("contentCoverColour")
snackbarEnabled = savedInstanceState.getInt("snackbarEnabled")

stressTestActive = savedInstanceState.getBoolean("stressTestActive")
}
Expand Down Expand Up @@ -229,6 +250,15 @@ class DemoActivity: AppCompatActivity() {
contentCoverColour = (contentCoverColour + contentCoverColourOptions.size - 1).rem(contentCoverColourOptions.size)
updateContentCoverColour()
}

set_snackbar_enabled_next.setOnClickListener {
snackbarEnabled = (snackbarEnabled + 1).rem(snackbarEnabledOptions.size)
updateSnackbarEnabled()
}
set_snackbar_enabled_prev.setOnClickListener {
snackbarEnabled = (snackbarEnabled + snackbarEnabledOptions.size - 1).rem(snackbarEnabledOptions.size)
updateSnackbarEnabled()
}
}

private fun toast(@StringRes str: Int) {
Expand Down Expand Up @@ -275,6 +305,16 @@ class DemoActivity: AppCompatActivity() {
fab.setContentCoverColour(contentCoverColourOptions[contentCoverColour].second)
}

private fun updateSnackbarEnabled() {
snackbar_enabled.text = snackbarEnabledOptions[snackbarEnabled].first
if (snackbarEnabled == 1) {
snackbar = Snackbar.make(root_view, "Hey there!", Snackbar.LENGTH_INDEFINITE)
snackbar?.show()
} else {
snackbar?.dismiss()
}
}

private fun startStressTest() {
stressTestActive = true
if (Build.VERSION.SDK_INT < 24) {
Expand Down
Loading

0 comments on commit ad96356

Please sign in to comment.