Skip to content

Commit fef729e

Browse files
author
Keisuke
committed
Add library
1 parent 5586a7c commit fef729e

File tree

35 files changed

+414
-4
lines changed

35 files changed

+414
-4
lines changed

.idea/gradle.xml

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules.xml

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/build.gradle

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,12 @@ android {
2020
}
2121

2222
dependencies {
23-
compile fileTree(dir: 'libs', include: ['*.jar'])
23+
compile fileTree(include: ['*.jar'], dir: 'libs')
2424
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
2525
exclude group: 'com.android.support', module: 'support-annotations'
2626
})
2727
compile 'com.android.support:appcompat-v7:25.3.1'
2828
compile 'com.android.support.constraint:constraint-layout:1.0.2'
2929
testCompile 'junit:junit:4.12'
30+
compile project(':library')
3031
}

app/src/main/java/io/github/kobakei/materialfabspeeddialexample/MainActivity.java

+18
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,30 @@
22

33
import android.support.v7.app.AppCompatActivity;
44
import android.os.Bundle;
5+
import android.view.View;
6+
import android.widget.Button;
7+
8+
import io.github.kobakei.materialfabspeeddial.FabSpeedDial;
59

610
public class MainActivity extends AppCompatActivity {
711

812
@Override
913
protected void onCreate(Bundle savedInstanceState) {
1014
super.onCreate(savedInstanceState);
1115
setContentView(R.layout.activity_main);
16+
17+
final FabSpeedDial fab = (FabSpeedDial) findViewById(R.id.fab);
18+
19+
Button button = (Button) findViewById(R.id.button);
20+
button.setOnClickListener(new View.OnClickListener() {
21+
@Override
22+
public void onClick(View v) {
23+
if (fab.isShown()) {
24+
fab.hide();
25+
} else {
26+
fab.show();
27+
}
28+
}
29+
});
1230
}
1331
}
Loading
602 Bytes
Loading
664 Bytes
Loading
694 Bytes
Loading
386 Bytes
Loading
404 Bytes
Loading
Loading
Loading
761 Bytes
Loading
Loading
Loading
Loading
+19-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
2+
<android.support.constraint.ConstraintLayout
3+
xmlns:android="http://schemas.android.com/apk/res/android"
34
xmlns:app="http://schemas.android.com/apk/res-auto"
45
xmlns:tools="http://schemas.android.com/tools"
56
android:layout_width="match_parent"
67
android:layout_height="match_parent"
78
tools:context="io.github.kobakei.materialfabspeeddialexample.MainActivity">
89

9-
<TextView
10+
<Button
11+
android:id="@+id/button"
1012
android:layout_width="wrap_content"
1113
android:layout_height="wrap_content"
1214
android:text="Hello World!"
@@ -15,4 +17,19 @@
1517
app:layout_constraintRight_toRightOf="parent"
1618
app:layout_constraintTop_toTopOf="parent" />
1719

20+
<io.github.kobakei.materialfabspeeddial.FabSpeedDial
21+
android:id="@+id/fab"
22+
android:layout_width="0dp"
23+
android:layout_height="0dp"
24+
app:layout_constraintTop_toTopOf="parent"
25+
android:layout_marginTop="0dp"
26+
android:layout_marginRight="0dp"
27+
app:layout_constraintRight_toRightOf="parent"
28+
app:layout_constraintBottom_toBottomOf="parent"
29+
android:layout_marginBottom="0dp"
30+
android:layout_marginLeft="0dp"
31+
app:layout_constraintVertical_bias="0.0"
32+
app:layout_constraintLeft_toLeftOf="parent"
33+
app:fab_menu="@menu/fab"/>
34+
1835
</android.support.constraint.ConstraintLayout>

app/src/main/res/menu/fab.xml

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<menu xmlns:android="http://schemas.android.com/apk/res/android">
3+
<item
4+
android:id="@+id/one"
5+
android:title="One"
6+
android:icon="@drawable/ic_action_alarm"/>
7+
<item
8+
android:id="@+id/two"
9+
android:title="Two"
10+
android:icon="@drawable/ic_action_cut"/>
11+
<item
12+
android:id="@+id/three"
13+
android:title="Three"
14+
android:icon="@drawable/ic_action_camera"/>
15+
</menu>

library/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

library/build.gradle

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
apply plugin: 'com.android.library'
2+
3+
android {
4+
compileSdkVersion 25
5+
buildToolsVersion "25.0.3"
6+
7+
defaultConfig {
8+
minSdkVersion 16
9+
targetSdkVersion 25
10+
versionCode 1
11+
versionName "1.0"
12+
13+
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
14+
15+
}
16+
buildTypes {
17+
release {
18+
minifyEnabled false
19+
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
20+
}
21+
}
22+
}
23+
24+
dependencies {
25+
compile fileTree(dir: 'libs', include: ['*.jar'])
26+
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
27+
exclude group: 'com.android.support', module: 'support-annotations'
28+
})
29+
compile 'com.android.support:appcompat-v7:25.3.1'
30+
compile 'com.android.support:design:25.3.1'
31+
testCompile 'junit:junit:4.12'
32+
}

library/proguard-rules.pro

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Add project specific ProGuard rules here.
2+
# By default, the flags in this file are appended to flags specified
3+
# in /Users/keisukekobayashi/Library/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
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package io.github.kobakei.materialfabspeeddial;
2+
3+
import android.content.Context;
4+
import android.support.test.InstrumentationRegistry;
5+
import android.support.test.runner.AndroidJUnit4;
6+
7+
import org.junit.Test;
8+
import org.junit.runner.RunWith;
9+
10+
import static org.junit.Assert.*;
11+
12+
/**
13+
* Instrumentation test, which will execute on an Android device.
14+
*
15+
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
16+
*/
17+
@RunWith(AndroidJUnit4.class)
18+
public class ExampleInstrumentedTest {
19+
@Test
20+
public void useAppContext() throws Exception {
21+
// Context of the app under test.
22+
Context appContext = InstrumentationRegistry.getTargetContext();
23+
24+
assertEquals("io.github.kobakei.materialfabspeeddial.test", appContext.getPackageName());
25+
}
26+
}

library/src/main/AndroidManifest.xml

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2+
3+
package="io.github.kobakei.materialfabspeeddial">
4+
5+
<application android:allowBackup="true" android:label="@string/app_name"
6+
android:supportsRtl="true">
7+
8+
</application>
9+
10+
</manifest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package io.github.kobakei.materialfabspeeddial;
2+
3+
import android.content.Context;
4+
import android.content.res.TypedArray;
5+
import android.support.annotation.AttrRes;
6+
import android.support.annotation.NonNull;
7+
import android.support.annotation.Nullable;
8+
import android.support.design.widget.FloatingActionButton;
9+
import android.util.AttributeSet;
10+
import android.view.Gravity;
11+
import android.view.LayoutInflater;
12+
import android.view.View;
13+
import android.view.ViewGroup;
14+
import android.widget.FrameLayout;
15+
import android.widget.LinearLayout;
16+
import android.widget.TextView;
17+
18+
import java.util.ArrayList;
19+
import java.util.List;
20+
21+
/**
22+
* Created by keisukekobayashi on 2017/06/12.
23+
*/
24+
25+
public class FabSpeedDial extends FrameLayout {
26+
27+
private FloatingActionButton fabMain;
28+
private LinearLayout menuContainer;
29+
private View touchGuard;
30+
private List<View> itemViews = new ArrayList<>();
31+
32+
private boolean isOpened = false;
33+
34+
public FabSpeedDial(@NonNull Context context) {
35+
super(context);
36+
initLayout(context, null, 0);
37+
}
38+
39+
public FabSpeedDial(@NonNull Context context, @Nullable AttributeSet attrs) {
40+
super(context, attrs);
41+
initLayout(context, attrs, 0);
42+
}
43+
44+
public FabSpeedDial(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
45+
super(context, attrs, defStyleAttr);
46+
initLayout(context, attrs, defStyleAttr);
47+
}
48+
49+
private void initLayout(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
50+
LayoutInflater inflater = LayoutInflater.from(context);
51+
View view = inflater.inflate(R.layout.fab_speed_dial, this, false);
52+
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
53+
params.gravity = Gravity.BOTTOM | Gravity.END;
54+
addView(view, params);
55+
56+
fabMain = (FloatingActionButton) findViewById(R.id.fab_main);
57+
fabMain.setOnClickListener(new OnClickListener() {
58+
@Override
59+
public void onClick(View v) {
60+
if (isOpened) {
61+
closeMenu();
62+
} else {
63+
openMenu();
64+
}
65+
}
66+
});
67+
68+
menuContainer = (LinearLayout) findViewById(R.id.menu_container);
69+
for (int i = 0; i < 3; i++) {
70+
View itemView = inflater.inflate(R.layout.fab_speed_dial_item, menuContainer, false);
71+
FloatingActionButton miniFab = (FloatingActionButton) itemView.findViewById(R.id.fab_mini);
72+
miniFab.setOnClickListener(new OnClickListener() {
73+
@Override
74+
public void onClick(View v) {
75+
76+
}
77+
});
78+
TextView label = (TextView) itemView.findViewById(R.id.text);
79+
label.setOnClickListener(new OnClickListener() {
80+
@Override
81+
public void onClick(View v) {
82+
83+
}
84+
});
85+
menuContainer.addView(itemView);
86+
itemViews.add(itemView);
87+
}
88+
89+
touchGuard = findViewById(R.id.touch_guard);
90+
touchGuard.setOnClickListener(new OnClickListener() {
91+
@Override
92+
public void onClick(View v) {
93+
closeMenu();
94+
}
95+
});
96+
97+
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.FabSpeedDial, defStyleAttr, 0);
98+
99+
// TODO
100+
int menuId = ta.getResourceId(R.styleable.FabSpeedDial_fab_menu, 0);
101+
102+
ta.recycle();
103+
}
104+
105+
public void openMenu() {
106+
fabMain.animate().rotation(45.0f)
107+
.setDuration(300L)
108+
.start();
109+
110+
for (int i = itemViews.size() - 1; i >= 0; i--) {
111+
View itemView = itemViews.get(i);
112+
113+
itemView.setAlpha(0.0f);
114+
itemView.setTranslationY(24.0f);
115+
116+
itemView.animate()
117+
.translationY(0.0f)
118+
.alpha(1.0f)
119+
.setDuration(100L)
120+
.setStartDelay((itemViews.size() - 1 - i) * 50L)
121+
.start();
122+
}
123+
124+
menuContainer.setVisibility(View.VISIBLE);
125+
touchGuard.setVisibility(View.VISIBLE);
126+
isOpened = true;
127+
}
128+
129+
public void closeMenu() {
130+
fabMain.animate().rotation(0.0f)
131+
.setDuration(300L)
132+
.start();
133+
134+
menuContainer.setVisibility(View.GONE);
135+
touchGuard.setVisibility(View.GONE);
136+
isOpened = false;
137+
}
138+
139+
public void show() {
140+
fabMain.show();
141+
}
142+
143+
public void hide() {
144+
fabMain.hide();
145+
}
146+
147+
public boolean isShown() {
148+
return fabMain.isShown();
149+
}
150+
}
Loading
Loading
Loading
Loading
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<shape xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:shape="rectangle">
4+
<corners
5+
android:radius="2dp"/>
6+
<solid
7+
android:color="@android:color/white"/>
8+
<stroke
9+
android:color="@android:color/darker_gray"
10+
android:width="1dp"/>
11+
</shape>

0 commit comments

Comments
 (0)