Last active
April 4, 2016 13:06
-
-
Save FabianTerhorst/6fefdce4a4b9c5bc2a60e66a6452bc4a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<android.support.design.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:background="@color/md_white_1000" | |
android:fitsSystemWindows="true"> | |
<android.support.design.widget.AppBarLayout | |
android:id="@+id/appbar" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:theme="@style/AppTheme.AppBarOverlay"> | |
<!--android:fitsSystemWindows="true"--> | |
<android.support.v7.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" /> | |
<!--app:layout_scrollFlags="scroll|enterAlways|snap"--> | |
</android.support.design.widget.AppBarLayout> | |
<android.support.v7.widget.RecyclerView | |
android:id="@+id/recyclerView" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:clipToPadding="false" | |
android:fitsSystemWindows="true" | |
app:layout_behavior="@string/appbar_scrolling_view_behavior" /> | |
<android.support.design.widget.FloatingActionButton | |
android:id="@+id/fab" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_gravity="bottom|end" | |
android:layout_margin="@dimen/fab_margin" | |
android:src="@android:drawable/ic_dialog_email" | |
app:layout_anchor="@id/recyclerView" | |
app:layout_anchorGravity="bottom|right|end" | |
app:layout_behavior="@string/floating_actionbutton_scrolling_view_behavior" /> | |
</android.support.design.widget.CoordinatorLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ScrollingViewBehavior extends AppBarLayout.ScrollingViewBehavior { | |
public ScrollingViewBehavior(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
} | |
@Override | |
public boolean onLayoutChild(CoordinatorLayout parent, View child, int layoutDirection) { | |
if (child instanceof RecyclerView) | |
child.setPadding(0, 0, 0, child.getPaddingBottom() != 0 ? child.getPaddingBottom() * 2 - child.getPaddingTop() : child.getPaddingTop()); | |
return super.onLayoutChild(parent, child, layoutDirection); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<string name="appbar_scrolling_view_behavior" translatable="false">io.github.massivezerginc.chest.ScrollingViewBehavior</string> | |
<string name="floating_actionbutton_scrolling_view_behavior" translatable="false">io.github.massivezerginc.chest.FloatingActionButtonBehavior</string> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* https://github.com/mikepenz/Materialize/blob/988d9809a9c6ea72c41fdbfdfa68fc20bd88e3af/library/src/main/java/com/mikepenz/materialize/util/UIUtils.java | |
* | |
**/ | |
@SuppressLint("InlinedApi") | |
public class UIUtils { | |
/** | |
* a helper method to get the color from an attribute | |
* | |
* @param ctx | |
* @param attr | |
* @return | |
*/ | |
public static int getThemeColor(Context ctx, @AttrRes int attr) { | |
TypedValue tv = new TypedValue(); | |
if (ctx.getTheme().resolveAttribute(attr, tv, true)) { | |
return tv.data; | |
} | |
return 0; | |
} | |
/** | |
* helper method to get the color by attr (which is defined in the style) or by resource. | |
* | |
* @param ctx | |
* @param attr | |
* @param res | |
* @return | |
*/ | |
public static int getThemeColorFromAttrOrRes(Context ctx, @AttrRes int attr, @ColorRes int res) { | |
int color = getThemeColor(ctx, attr); | |
if (color == 0) { | |
color = ContextCompat.getColor(ctx, res); | |
} | |
return color; | |
} | |
/** | |
* helper method to set the background depending on the android version | |
* | |
* @param v | |
* @param d | |
*/ | |
@SuppressLint("NewApi") | |
public static void setBackground(View v, Drawable d) { | |
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) { | |
v.setBackgroundDrawable(d); | |
} else { | |
v.setBackground(d); | |
} | |
} | |
/** | |
* helper method to set the background depending on the android version | |
* | |
* @param v | |
* @param drawableRes | |
*/ | |
public static void setBackground(View v, @DrawableRes int drawableRes) { | |
setBackground(v, getCompatDrawable(v.getContext(), drawableRes)); | |
} | |
/** | |
* helper method to get the drawable by its resource. specific to the correct android version | |
* | |
* @param c | |
* @param drawableRes | |
* @return | |
*/ | |
public static Drawable getCompatDrawable(Context c, @DrawableRes int drawableRes) { | |
Drawable d = null; | |
try { | |
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { | |
d = c.getResources().getDrawable(drawableRes); | |
} else { | |
d = c.getResources().getDrawable(drawableRes, c.getTheme()); | |
} | |
} catch (Exception ex) { | |
} | |
return d; | |
} | |
/** | |
* Returns the size in pixels of an attribute dimension | |
* | |
* @param context the context to get the resources from | |
* @param attr is the attribute dimension we want to know the size from | |
* @return the size in pixels of an attribute dimension | |
*/ | |
public static int getThemeAttributeDimensionSize(Context context, @AttrRes int attr) { | |
TypedArray a = null; | |
try { | |
a = context.getTheme().obtainStyledAttributes(new int[]{attr}); | |
return a.getDimensionPixelSize(0, 0); | |
} finally { | |
if (a != null) { | |
a.recycle(); | |
} | |
} | |
} | |
/** | |
* helper to calculate the navigationBar height | |
* | |
* @param context | |
* @return | |
*/ | |
public static int getNavigationBarHeight(Context context) { | |
Resources resources = context.getResources(); | |
int id = resources.getIdentifier(context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ? "navigation_bar_height" : "navigation_bar_height_landscape", "dimen", "android"); | |
if (id > 0) { | |
return resources.getDimensionPixelSize(id); | |
} | |
return 0; | |
} | |
/** | |
* helper to calculate the actionBar height | |
* | |
* @param context | |
* @return | |
*/ | |
public static int getActionBarHeight(Context context) { | |
int actionBarHeight = UIUtils.getThemeAttributeDimensionSize(context, R.attr.actionBarSize); | |
if (actionBarHeight == 0) { | |
actionBarHeight = context.getResources().getDimensionPixelSize(R.dimen.abc_action_bar_default_height_material); | |
} | |
return actionBarHeight; | |
} | |
/** | |
* helper to calculate the statusBar height | |
* | |
* @param context | |
* @return | |
*/ | |
public static int getStatusBarHeight(Context context) { | |
return getStatusBarHeight(context, false); | |
} | |
/** | |
* helper to calculate the statusBar height | |
* | |
* @param context | |
* @param force pass true to get the height even if the device has no translucent statusBar | |
* @return | |
*/ | |
public static int getStatusBarHeight(Context context, boolean force) { | |
int result = 0; | |
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); | |
if (resourceId > 0) { | |
result = context.getResources().getDimensionPixelSize(resourceId); | |
} | |
int dimenResult = context.getResources().getDimensionPixelSize(R.dimen.tool_bar_top_padding); | |
//if our dimension is 0 return 0 because on those devices we don't need the height | |
if (dimenResult == 0 && !force) { | |
return 0; | |
} else { | |
//if our dimens is > 0 && the result == 0 use the dimenResult else the result; | |
return result == 0 ? dimenResult : result; | |
} | |
} | |
/** | |
* This method converts dp unit to equivalent pixels, depending on device density. | |
* | |
* @param dp A value in dp (density independent pixels) unit. Which we need to convert into pixels | |
* @param context Context to get resources and device specific display metrics | |
* @return A float value to represent px equivalent to dp depending on device density | |
*/ | |
public static float convertDpToPixel(float dp, Context context) { | |
Resources resources = context.getResources(); | |
DisplayMetrics metrics = resources.getDisplayMetrics(); | |
float px = dp * (metrics.densityDpi / 160f); | |
return px; | |
} | |
/** | |
* This method converts device specific pixels to density independent pixels. | |
* | |
* @param px A value in px (pixels) unit. Which we need to convert into db | |
* @param context Context to get resources and device specific display metrics | |
* @return A float value to represent dp equivalent to px value | |
*/ | |
public static float convertPixelsToDp(float px, Context context) { | |
Resources resources = context.getResources(); | |
DisplayMetrics metrics = resources.getDisplayMetrics(); | |
float dp = px / (metrics.densityDpi / 160f); | |
return dp; | |
} | |
/** | |
* helper method to set the TranslucentStatusFlag | |
* | |
* @param on | |
*/ | |
public static void setTranslucentStatusFlag(Activity activity, boolean on) { | |
if (Build.VERSION.SDK_INT >= 19) { | |
setFlag(activity, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, on); | |
} | |
} | |
/** | |
* helper method to set the TranslucentNavigationFlag | |
* | |
* @param on | |
*/ | |
public static void setTranslucentNavigationFlag(Activity activity, boolean on) { | |
if (Build.VERSION.SDK_INT >= 19) { | |
setFlag(activity, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, on); | |
} | |
} | |
/** | |
* helper method to activate or deactivate a specific flag | |
* | |
* @param bits | |
* @param on | |
*/ | |
public static void setFlag(Activity activity, final int bits, boolean on) { | |
Window win = activity.getWindow(); | |
WindowManager.LayoutParams winParams = win.getAttributes(); | |
if (on) { | |
winParams.flags |= bits; | |
} else { | |
winParams.flags &= ~bits; | |
} | |
win.setAttributes(winParams); | |
} | |
/** | |
* helper to create a stateListDrawable for the icon | |
* | |
* @param icon | |
* @param selectedIcon | |
* @return | |
*/ | |
public static StateListDrawable getIconStateList(Drawable icon, Drawable selectedIcon) { | |
StateListDrawable iconStateListDrawable = new StateListDrawable(); | |
iconStateListDrawable.addState(new int[]{android.R.attr.state_selected}, selectedIcon); | |
iconStateListDrawable.addState(new int[]{}, icon); | |
return iconStateListDrawable; | |
} | |
/** | |
* helper to get the system default selectable background inclusive an active state | |
* | |
* @param ctx the context | |
* @param selected_color the selected color | |
* @param animate true if you want to fade over the states (only animates if API newer than Build.VERSION_CODES.HONEYCOMB) | |
* @return the StateListDrawable | |
*/ | |
public static StateListDrawable getSelectableBackground(Context ctx, int selected_color, boolean animate) { | |
StateListDrawable states = new StateListDrawable(); | |
ColorDrawable clrActive = new ColorDrawable(selected_color); | |
states.addState(new int[]{android.R.attr.state_selected}, clrActive); | |
states.addState(new int[]{}, getSelectableBackground(ctx)); | |
//if possible we enable animating across states | |
if (animate && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { | |
int duration = ctx.getResources().getInteger(android.R.integer.config_shortAnimTime); | |
states.setEnterFadeDuration(duration); | |
states.setExitFadeDuration(duration); | |
} | |
return states; | |
} | |
/** | |
* helper to get the system default selectable background inclusive an active and pressed state | |
* | |
* @param ctx the context | |
* @param selected_color the selected color | |
* @param pressed_alpha 0-255 | |
* @param animate true if you want to fade over the states (only animates if API newer than Build.VERSION_CODES.HONEYCOMB) | |
* @return the StateListDrawable | |
*/ | |
public static StateListDrawable getSelectablePressedBackground(Context ctx, int selected_color, int pressed_alpha, boolean animate) { | |
StateListDrawable states = getSelectableBackground(ctx, selected_color, animate); | |
ColorDrawable clrPressed = new ColorDrawable(adjustAlpha(selected_color, pressed_alpha)); | |
states.addState(new int[]{android.R.attr.state_pressed}, clrPressed); | |
return states; | |
} | |
/** | |
* adjusts the alpha of a color | |
* | |
* @param color the color | |
* @param alpha the alpha value we want to set 0-255 | |
* @return the adjusted color | |
*/ | |
public static int adjustAlpha(int color, int alpha) { | |
return (alpha << 24) | (color & 0x00ffffff); | |
} | |
/** | |
* helper to get the system default selectable background res | |
* | |
* @param ctx | |
* @return | |
*/ | |
public static int getSelectableBackgroundRes(Context ctx) { | |
if (Build.VERSION.SDK_INT >= 11) { | |
// If we're running on Honeycomb or newer, then we can use the Theme's | |
// selectableItemBackground to ensure that the View has a pressed state | |
TypedValue outValue = new TypedValue(); | |
//it is important here to not use the android.R because this wouldn't add the latest drawable | |
ctx.getTheme().resolveAttribute(R.attr.selectableItemBackground, outValue, true); | |
return outValue.resourceId; | |
} else { | |
TypedValue outValue = new TypedValue(); | |
ctx.getTheme().resolveAttribute(android.R.attr.itemBackground, outValue, true); | |
return outValue.resourceId; | |
} | |
} | |
/** | |
* helper to get the system default selectable background | |
* | |
* @param ctx | |
* @return | |
*/ | |
public static Drawable getSelectableBackground(Context ctx) { | |
int selectableBackgroundRes = getSelectableBackgroundRes(ctx); | |
if (Build.VERSION.SDK_INT >= 11) { | |
return ContextCompat.getDrawable(ctx, selectableBackgroundRes); | |
} else { | |
return UIUtils.getCompatDrawable(ctx, selectableBackgroundRes); | |
} | |
} | |
/** | |
* Returns the screen width in pixels | |
* | |
* @param context is the context to get the resources | |
* @return the screen width in pixels | |
*/ | |
public static int getScreenWidth(Context context) { | |
DisplayMetrics metrics = context.getResources().getDisplayMetrics(); | |
return metrics.widthPixels; | |
} | |
/** | |
* Returns the screen height in pixels | |
* | |
* @param context is the context to get the resources | |
* @return the screen height in pixels | |
*/ | |
public static int getScreenHeight(Context context) { | |
DisplayMetrics metrics = context.getResources().getDisplayMetrics(); | |
return metrics.heightPixels; | |
} | |
/** | |
* set the alpha of a specific view | |
* | |
* @param v | |
* @param value | |
*/ | |
public static void setAlpha(View v, float value) { | |
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { | |
AlphaAnimation alpha = new AlphaAnimation(value, value); | |
alpha.setDuration(0); // Make animation instant | |
alpha.setFillAfter(true); // Tell it to persist after the animation ends | |
v.startAnimation(alpha); | |
} else { | |
v.setAlpha(value); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment