Skip to content

Commit

Permalink
Merge pull request google#32 from google/develop
Browse files Browse the repository at this point in the history
Release v0.9.7
  • Loading branch information
matthew-carroll authored Feb 27, 2017
2 parents 7d544e0 + 9b42d99 commit 09c184b
Show file tree
Hide file tree
Showing 35 changed files with 607 additions and 7 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ Download
Hover is available through jCenter:

```groovy
compile 'io.mattcarroll.hover:hover:0.9.6'
compile 'io.mattcarroll.hover:hover:0.9.7'
```

Issues
Expand Down
1 change: 1 addition & 0 deletions hover-demo-nonfullscreen/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
22 changes: 22 additions & 0 deletions hover-demo-nonfullscreen/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Non-Fullscreen Hover Menu

Your Hover Menu does not have to take up the full height of the screen. You can choose to make
your Hover Menu take up only the height needed by the content. To achieve this, you need to set
the LayoutParams on the View returned by your NavigatorContent to use WRAP_CONTENT for its height.

For example:

```java
@Override
public View getView() {
if (null == mContent) {
mContent = LayoutInflater.from(mContext).inflate(R.layout.content_non_fullscreen, null);

// We present our desire to be non-fullscreen by using WRAP_CONTENT for height. This
// preference will be honored by the Hover Menu to make our content only as tall as we
// want to be.
mContent.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
}
return mContent;
}
```
33 changes: 33 additions & 0 deletions hover-demo-nonfullscreen/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
apply plugin: 'com.android.application'

android {
compileSdkVersion 24
buildToolsVersion "24.0.3"

defaultConfig {
applicationId "io.mattcarroll.hoverdemonon_fullscreen"
minSdkVersion 15
targetSdkVersion 24
versionCode 1
versionName "1.0"

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:24.2.1'
compile project(':hover')
testCompile 'junit:junit:4.12'
}
17 changes: 17 additions & 0 deletions hover-demo-nonfullscreen/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/matt/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package io.mattcarroll.hoverdemonon_fullscreen;

import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.*;

/**
* Instrumentation test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();

assertEquals("io.mattcarroll.hoverdemonon_fullscreen", appContext.getPackageName());
}
}
23 changes: 23 additions & 0 deletions hover-demo-nonfullscreen/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="io.mattcarroll.hoverdemonon_fullscreen"
xmlns:android="http://schemas.android.com/apk/res/android">

<application
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="false"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>

<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<service
android:name="io.mattcarroll.hoverdemonon_fullscreen.DemoHoverMenuService"
/>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package io.mattcarroll.hoverdemonon_fullscreen;

import android.content.Context;
import android.content.res.Resources;
import android.os.Build;
import android.support.annotation.ColorInt;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.util.TypedValue;
import android.view.View;

import io.mattcarroll.hover.HoverMenuAdapter;
import io.mattcarroll.hover.NavigatorContent;

/**
* A Hover Menu Adapter tells the Hover Menu how many tabs/pages should appear in the Hover menu. It
* also provides the content for those pages.
*/
public class DemoHoverMenuAdapter implements HoverMenuAdapter {

private final Context mContext;
private final NonFullscreenContent mTheOnlyScreen;

public DemoHoverMenuAdapter(@NonNull Context context) {
mContext = context.getApplicationContext();
mTheOnlyScreen = new NonFullscreenContent(context);
}

@Override
public int getTabCount() {
return 1;
}

@Override
public long getTabId(int position) {
return position;
}

@Override
public View getTabView(int position) {
return createTabView(R.drawable.ic_orange_circle, 0xFFFF9600, null);
}

@Override
public NavigatorContent getNavigatorContent(int position) {
return mTheOnlyScreen;
}

@Override
public void addContentChangeListener(@NonNull ContentChangeListener listener) {
// No-op.
}

@Override
public void removeContentChangeListener(@NonNull ContentChangeListener listener) {
// No-op.
}

private View createTabView(@DrawableRes int tabBitmapRes, @ColorInt int backgroundColor, @ColorInt Integer iconColor) {
Resources resources = mContext.getResources();
int padding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, resources.getDisplayMetrics());

DemoTabView view = new DemoTabView(mContext, resources.getDrawable(R.drawable.tab_background), resources.getDrawable(tabBitmapRes));
view.setTabBackgroundColor(backgroundColor);
view.setTabForegroundColor(iconColor);
view.setPadding(padding, padding, padding, padding);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
view.setElevation(padding);
}
return view;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* 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 io.mattcarroll.hoverdemonon_fullscreen;

import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.ContextThemeWrapper;

import io.mattcarroll.hover.HoverMenuAdapter;
import io.mattcarroll.hover.Navigator;
import io.mattcarroll.hover.defaulthovermenu.DefaultNavigator;
import io.mattcarroll.hover.defaulthovermenu.window.HoverMenuService;

/**
* Demo {@link HoverMenuService}.
*/
public class DemoHoverMenuService extends HoverMenuService {

private static final String TAG = "DemoHoverMenuService";

public static void showFloatingMenu(Context context) {
context.startService(new Intent(context, DemoHoverMenuService.class));
}

@Override
public void onCreate() {
super.onCreate();
}

@Override
public void onDestroy() {
super.onDestroy();
}

@Override
protected Context getContextForHoverMenu() {
return new ContextThemeWrapper(this, R.style.AppTheme);
}

@Override
protected HoverMenuAdapter createHoverMenuAdapter() {
return new DemoHoverMenuAdapter(getApplicationContext());
}

@Override
protected Navigator createNavigator() {
return new DefaultNavigator(getApplicationContext(), false);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
* 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 io.mattcarroll.hoverdemonon_fullscreen;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorInt;
import android.support.annotation.Nullable;
import android.util.TypedValue;
import android.view.View;

/**
* Visual representation of a top-level tab in a Hover menu.
*/
public class DemoTabView extends View {

private int mBackgroundColor;
private Integer mForegroundColor;

private Drawable mCircleDrawable;
private Drawable mIconDrawable;
private int mIconInsetLeft, mIconInsetTop, mIconInsetRight, mIconInsetBottom;

public DemoTabView(Context context, Drawable backgroundDrawable, Drawable iconDrawable) {
super(context);
mCircleDrawable = backgroundDrawable;
mIconDrawable = iconDrawable;
init();
}

private void init() {
int insetsDp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getContext().getResources().getDisplayMetrics());
mIconInsetLeft = mIconInsetTop = mIconInsetRight = mIconInsetBottom = insetsDp;
}

public void setTabBackgroundColor(@ColorInt int backgroundColor) {
mBackgroundColor = backgroundColor;
mCircleDrawable.setColorFilter(mBackgroundColor, PorterDuff.Mode.SRC_ATOP);
}

public void setTabForegroundColor(@ColorInt Integer foregroundColor) {
mForegroundColor = foregroundColor;
if (null != mForegroundColor) {
mIconDrawable.setColorFilter(mForegroundColor, PorterDuff.Mode.SRC_ATOP);
} else {
mIconDrawable.setColorFilter(null);
}
}

public void setIcon(@Nullable Drawable icon) {
mIconDrawable = icon;
if (null != mForegroundColor && null != mIconDrawable) {
mIconDrawable.setColorFilter(mForegroundColor, PorterDuff.Mode.SRC_ATOP);
}
updateIconBounds();

invalidate();
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);

// Make circle as large as View minus padding.
mCircleDrawable.setBounds(getPaddingLeft(), getPaddingTop(), w - getPaddingRight(), h - getPaddingBottom());

// Re-size the icon as necessary.
updateIconBounds();

invalidate();
}

private void updateIconBounds() {
if (null != mIconDrawable) {
Rect bounds = new Rect(mCircleDrawable.getBounds());
bounds.set(bounds.left + mIconInsetLeft, bounds.top + mIconInsetTop, bounds.right - mIconInsetRight, bounds.bottom - mIconInsetBottom);
mIconDrawable.setBounds(bounds);
}
}

@Override
protected void onDraw(Canvas canvas) {
mCircleDrawable.draw(canvas);
if (null != mIconDrawable) {
mIconDrawable.draw(canvas);
}
}
}
Loading

0 comments on commit 09c184b

Please sign in to comment.