├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── qwert2603 │ │ └── floating_action_mode_example │ │ └── MainActivity.kt │ └── res │ ├── drawable │ ├── action_mode_background.xml │ ├── ic_check_box_white_24dp.xml │ ├── ic_delete_white_24dp.xml │ ├── ic_select_all_white_24dp.xml │ └── klimt_1918.png │ ├── layout │ ├── activity_main.xml │ ├── item.xml │ ├── user_list_action_mode.xml │ └── user_list_action_mode_2.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── integers.xml │ ├── strings.xml │ └── styles.xml ├── art ├── device-2017-01-11-133834.png ├── device-2017-01-11-133856.png ├── device-2017-01-11-133905.png ├── device-2017-01-11-133940.png ├── device-2017-01-11-134000.png ├── device-2017-01-12-115335.png ├── device-2017-01-12-115349.png ├── device-2017-01-12-115403.png ├── device-2017-01-12-115420.png ├── qq.png └── qq2.png ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── library ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── qwert2603 │ │ └── floating_action_mode │ │ ├── FloatingActionMode.kt │ │ └── Utils.kt │ └── res │ ├── drawable-v21 │ └── fam_image_button_background.xml │ ├── drawable │ ├── fam_ic_close_white_24dp.xml │ ├── fam_ic_drag_white_24dp.xml │ └── fam_image_button_background.xml │ ├── layout │ └── floating_action_mode.xml │ └── values │ ├── attrs.xml │ └── colors.xml └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | 1.8 51 | 52 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FloatingActionMode 2 | 3 | [![](https://www.jitpack.io/v/qwert2603/FloatingActionMode.svg)](https://www.jitpack.io/#qwert2603/FloatingActionMode) 4 | 5 | Floating Action Mode (FAM) is the custom view for context actions on Android. (*minSdkVersion* ***15***) 6 | 7 | FAM can be dragged over screen or it can be fixed at the top or bottom (with disabled dragging). 8 | 9 | ## [Demo Video (Fixed)](https://www.youtube.com/watch?v=1tn0MQV0ZrQ) 10 | ## [Demo Video (Dragging)](https://www.youtube.com/watch?v=PbQ8N7pWGt4) 11 | 12 | ## Fixed 13 | ![Art](https://github.com/qwert2603/FloatingActionMode/blob/master/art/qq2.png) 14 | 15 | 16 | ## Dragging 17 | ![Art](https://github.com/qwert2603/FloatingActionMode/blob/master/art/qq.png) 18 | 19 | ## XML-Attributes 20 | 21 | FAM has following XML-attributes (they also may be changed programmatically): 22 | 23 | * ***fam_opened*** defines whether FAM opened when created. (false by default) 24 | 25 | * ***fam_content_res*** is LayoutRes that represents content of FAM (e.g. some buttons). (no content by default) 26 | * ***fam_can_close*** defines whether FAM has button for closing itself. (true by default) 27 | 28 | * ***fam_close_icon*** is DrawableRes for closing button. (has default value) 29 | 30 | * ***fam_can_drag*** defines whether FAM has button for gragging itself. (true by default) 31 | 32 | * ***fam_drag_icon*** is DrawableRes for dragging button. (has default value) 33 | 34 | * ***fam_can_dismiss*** defines whether FAM may be dismissed (and closed) if transtationX while dragging is big enough. (true by default) 35 | 36 | * ***fam_dismiss_threshold*** is fraction that used to solve threshold translationX for dismissing. (0.4f by default) 37 | 38 | * ***fam_minimize_direction*** defines minimize direction of FAM. This attribute may have following values (nearest by default): 39 | * *top* - FAM will be translated to the top border of parent (excluding offsets) while minimizing. 40 | * *bottom* - FAM will be translated to the bottom border of parent (excluding offsets) while minimizing. 41 | * *nearest* - FAM will be translated to the nearest (top or bottom) border of parent (excluding offsets) while minimizing. 42 | 43 | * ***fam_animation_duration*** defines duration of minimize/maximize animations. (400 by default) 44 | 45 | FAM has ***OnCloseListener*** that allows to get callback when FAM was dismissed or closed by user. 46 | 47 | ## Using in CoordinatorLayout 48 | 49 | FAM has its special CoordinatorLayout.Behavior and can be used in CoordinatorLayout. 50 | FloatingActionModeBehavior allows to offset FAM of AppBarLayout and Snackbar.SnackbarLayout. 51 | Also it allows to minimize/maximize FAM on scroll. 52 | 53 | FAM has no background by default, so you can use any one you want. 54 | 55 | *android:translationZ="8dp"* can be used for shadow. 56 | 57 | *android:animateLayoutChanges="true"* can be used to animate contentChanges (*fam_content_res* attribute). 58 | FAM animates *fam_close_button* and *fam_drag_button* changes by default. 59 | 60 | ``` 61 | 62 | 63 | 64 | ... 65 | 66 | 67 | 69 | 70 | 85 | 86 | 87 | ``` 88 | 89 | ## Download 90 | 91 | ``` 92 | allprojects { 93 | repositories { 94 | ... 95 | maven { url "https://www.jitpack.io" } 96 | } 97 | } 98 | ``` 99 | 100 | ``` 101 | dependencies { 102 | compile 'com.github.qwert2603:FloatingActionMode:x.y.z' 103 | } 104 | ``` 105 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | 5 | android { 6 | compileSdkVersion 25 7 | buildToolsVersion "25.0.2" 8 | defaultConfig { 9 | applicationId "com.qwert2603.floating_action_mode_example" 10 | minSdkVersion 15 11 | targetSdkVersion 25 12 | versionCode 1 13 | versionName "1.0" 14 | } 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | sourceSets { 22 | main.java.srcDirs += 'src/main/kotlin' 23 | } 24 | } 25 | kapt { 26 | generateStubs = true 27 | } 28 | 29 | dependencies { 30 | ext.support_version = '25.1.0' 31 | 32 | compile fileTree(dir: 'libs', include: ['*.jar']) 33 | compile project(':library') 34 | 35 | compile "com.android.support:appcompat-v7:$support_version" 36 | compile "com.android.support:design:$support_version" 37 | 38 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 39 | } 40 | repositories { 41 | mavenCentral() 42 | maven { 43 | url "http://repository.jetbrains.com/all" 44 | } 45 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Users\alex\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/qwert2603/floating_action_mode_example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.qwert2603.floating_action_mode_example 2 | 3 | import android.annotation.SuppressLint 4 | import android.graphics.Color 5 | import android.os.Bundle 6 | import android.support.design.widget.Snackbar 7 | import android.support.v7.app.AppCompatActivity 8 | import android.support.v7.widget.DividerItemDecoration 9 | import android.support.v7.widget.LinearLayoutManager 10 | import android.support.v7.widget.RecyclerView 11 | import android.view.LayoutInflater 12 | import android.view.View 13 | import android.view.ViewGroup 14 | import com.qwert2603.floating_action_mode.FloatingActionMode 15 | import kotlinx.android.synthetic.main.activity_main.* 16 | import kotlinx.android.synthetic.main.item.view.* 17 | 18 | class MainActivity : AppCompatActivity() { 19 | 20 | var b: Boolean = true 21 | 22 | override fun onCreate(savedInstanceState: Bundle?) { 23 | super.onCreate(savedInstanceState) 24 | setContentView(R.layout.activity_main) 25 | 26 | setSupportActionBar(toolbar) 27 | 28 | recycler_view.layoutManager = LinearLayoutManager(this) 29 | recycler_view.adapter = ItemsAdapter() 30 | recycler_view.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL)) 31 | 32 | floating_action_mode.onOpenListener = object : FloatingActionMode.OnOpenListener { 33 | override fun onOpen() { 34 | fab.animate().translationY(activity_main.height - fab.top.toFloat()) 35 | } 36 | } 37 | 38 | floating_action_mode.onCloseListener = object : FloatingActionMode.OnCloseListener { 39 | override fun onClose() { 40 | fab.animate().translationY(0f) 41 | if (b) { 42 | Snackbar.make(activity_main, "closed", Snackbar.LENGTH_SHORT).show() 43 | } 44 | b = !b 45 | } 46 | } 47 | } 48 | 49 | private inner class ItemsAdapter : RecyclerView.Adapter() { 50 | 51 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = VH(LayoutInflater.from(this@MainActivity).inflate(R.layout.item, parent, false)) 52 | 53 | override fun onBindViewHolder(holder: VH, position: Int) = holder.bind(position) 54 | 55 | override fun getItemCount() = 100 56 | 57 | internal inner class VH(itemView: View) : RecyclerView.ViewHolder(itemView) { 58 | 59 | init { 60 | itemView.setOnClickListener { 61 | Snackbar.make(this@MainActivity.activity_main, itemView.text.text, Snackbar.LENGTH_SHORT).show() 62 | if (adapterPosition == 14) { 63 | floating_action_mode.canDrag = !floating_action_mode.canDrag 64 | } 65 | if (adapterPosition == 17) { 66 | floating_action_mode.canClose = !floating_action_mode.canClose 67 | } 68 | if (adapterPosition == 19) { 69 | val minimizeDirection = FloatingActionMode.MinimizeDirection 70 | .values()[(floating_action_mode.minimizeDirection.ordinal + 1) % FloatingActionMode.MinimizeDirection.values().size] 71 | floating_action_mode.minimizeDirection = minimizeDirection 72 | Snackbar.make(this@MainActivity.activity_main, minimizeDirection.name, Snackbar.LENGTH_SHORT).show() 73 | } 74 | if (adapterPosition == 26) { 75 | if (floating_action_mode.contentRes == 0) floating_action_mode.contentRes = R.layout.user_list_action_mode else 76 | if (floating_action_mode.contentRes == R.layout.user_list_action_mode) floating_action_mode.contentRes = R.layout.user_list_action_mode_2 else 77 | if (floating_action_mode.contentRes == R.layout.user_list_action_mode_2) floating_action_mode.contentRes = 0 78 | } 79 | } 80 | itemView.setOnLongClickListener { 81 | floating_action_mode.open() 82 | return@setOnLongClickListener true 83 | } 84 | } 85 | 86 | @SuppressLint("SetTextI18n") 87 | fun bind(i: Int) = with(itemView) { 88 | color.setBackgroundColor(Color.argb(i * 256 / 100, 0, 0, 0xff)) 89 | text.text = "Text #" + i 90 | } 91 | } 92 | 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/action_mode_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_check_box_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_delete_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_select_all_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/klimt_1918.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qwert2603/FloatingActionMode/a30a754a77b7ae7eb8a15225575355fde37a3986/app/src/main/res/drawable/klimt_1918.png -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 22 | 23 | 29 | 30 | 36 | 37 | 38 | 39 | 40 | 41 | 47 | 48 | 55 | 56 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 14 | 15 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/user_list_action_mode.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 15 | 16 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/layout/user_list_action_mode_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 21 | 22 | 28 | 29 | 35 | 36 | 37 | 38 | 43 | 44 | 50 | 51 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qwert2603/FloatingActionMode/a30a754a77b7ae7eb8a15225575355fde37a3986/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qwert2603/FloatingActionMode/a30a754a77b7ae7eb8a15225575355fde37a3986/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qwert2603/FloatingActionMode/a30a754a77b7ae7eb8a15225575355fde37a3986/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qwert2603/FloatingActionMode/a30a754a77b7ae7eb8a15225575355fde37a3986/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qwert2603/FloatingActionMode/a30a754a77b7ae7eb8a15225575355fde37a3986/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qwert2603/FloatingActionMode/a30a754a77b7ae7eb8a15225575355fde37a3986/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qwert2603/FloatingActionMode/a30a754a77b7ae7eb8a15225575355fde37a3986/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qwert2603/FloatingActionMode/a30a754a77b7ae7eb8a15225575355fde37a3986/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qwert2603/FloatingActionMode/a30a754a77b7ae7eb8a15225575355fde37a3986/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qwert2603/FloatingActionMode/a30a754a77b7ae7eb8a15225575355fde37a3986/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | #D90000 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 16dp 3 | 8dp 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/values/integers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 400 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Floating Action Mode Example 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 |