Skip to content

Instantly share code, notes, and snippets.

@frogermcs
Last active August 29, 2015 14:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save frogermcs/c587f6f76253f8a1547a to your computer and use it in GitHub Desktop.
Save frogermcs/c587f6f76253f8a1547a to your computer and use it in GitHub Desktop.
InstaMaterial source files - post 4
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<!--...-->
<include
android:id="@+id/toolbar"
layout="@layout/view_feed_toolbar" />
<!--...-->
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<!--drawable/btn_context_menu.xml-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/btn_context_menu_normal" android:state_focused="false" android:state_pressed="false" />
<item android:drawable="@color/btn_context_menu_pressed" android:state_pressed="true" />
<item android:drawable="@color/btn_context_menu_pressed" android:state_focused="true" />
</selector>
<?xml version="1.0" encoding="utf-8"?>
<!--drawable-v21/btn_context_menu.xml-->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/btn_context_menu_pressed">
<item>
<shape android:shape="rectangle">
<solid android:color="@color/btn_context_menu_normal" />
</shape>
</item>
</ripple>
public class FeedContextMenu extends LinearLayout {
private static final int CONTEXT_MENU_WIDTH = Utils.dpToPx(240);
private int feedItem = -1;
private OnFeedContextMenuItemClickListener onItemClickListener;
public FeedContextMenu(Context context) {
super(context);
init();
}
private void init() {
LayoutInflater.from(getContext()).inflate(R.layout.view_context_menu, this, true);
setBackgroundResource(R.drawable.bg_container_shadow);
setOrientation(VERTICAL);
setLayoutParams(new LayoutParams(CONTEXT_MENU_WIDTH, ViewGroup.LayoutParams.WRAP_CONTENT));
}
public void bindToItem(int feedItem) {
this.feedItem = feedItem;
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
ButterKnife.inject(this);
}
public void dismiss() {
((ViewGroup) getParent()).removeView(FeedContextMenu.this);
}
@OnClick(R.id.btnReport)
public void onReportClick() {
if (onItemClickListener != null) {
onItemClickListener.onReportClick(feedItem);
}
}
@OnClick(R.id.btnSharePhoto)
public void onSharePhotoClick() {
if (onItemClickListener != null) {
onItemClickListener.onSharePhotoClick(feedItem);
}
}
@OnClick(R.id.btnCopyShareUrl)
public void onCopyShareUrlClick() {
if (onItemClickListener != null) {
onItemClickListener.onCopyShareUrlClick(feedItem);
}
}
@OnClick(R.id.btnCancel)
public void onCancelClick() {
if (onItemClickListener != null) {
onItemClickListener.onCancelClick(feedItem);
}
}
public void setOnFeedMenuItemClickListener(OnFeedContextMenuItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
public interface OnFeedContextMenuItemClickListener {
public void onReportClick(int feedItem);
public void onSharePhotoClick(int feedItem);
public void onCopyShareUrlClick(int feedItem);
public void onCancelClick(int feedItem);
}
}
public class FeedContextMenuManager implements View.OnAttachStateChangeListener {
private static FeedContextMenuManager instance;
private FeedContextMenu contextMenuView;
public static FeedContextMenuManager getInstance() {
if (instance == null) {
instance = new FeedContextMenuManager();
}
return instance;
}
@Override
public void onViewAttachedToWindow(View v) {
}
@Override
public void onViewDetachedFromWindow(View v) {
contextMenuView = null;
}
}
public void toggleContextMenuFromView(View openingView, int feedItem, FeedContextMenu.OnFeedContextMenuItemClickListener listener) {
if (contextMenuView == null) {
showContextMenuFromView(openingView, feedItem, listener);
} else {
hideContextMenu();
}
}
private void showContextMenuFromView(final View openingView, int feedItem, FeedContextMenu.OnFeedContextMenuItemClickListener listener) {
if (!isContextMenuShowing) {
isContextMenuShowing = true;
contextMenuView = new FeedContextMenu(openingView.getContext());
contextMenuView.bindToItem(feedItem);
contextMenuView.addOnAttachStateChangeListener(this);
contextMenuView.setOnFeedMenuItemClickListener(listener);
((ViewGroup) openingView.getRootView().findViewById(android.R.id.content)).addView(contextMenuView);
contextMenuView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
contextMenuView.getViewTreeObserver().removeOnPreDrawListener(this);
setupContextMenuInitialPosition(openingView);
performShowAnimation();
return false;
}
});
}
}
private void setupContextMenuInitialPosition(View openingView) {
final int[] openingViewLocation = new int[2];
openingView.getLocationOnScreen(openingViewLocation);
int additionalBottomMargin = Utils.dpToPx(16);
contextMenuView.setTranslationX(openingViewLocation[0] - contextMenuView.getWidth() / 3);
contextMenuView.setTranslationY(openingViewLocation[1] - contextMenuView.getHeight() - additionalBottomMargin);
}
private void performShowAnimation() {
contextMenuView.setPivotX(contextMenuView.getWidth() / 2);
contextMenuView.setPivotY(contextMenuView.getHeight());
contextMenuView.setScaleX(0.1f);
contextMenuView.setScaleY(0.1f);
contextMenuView.animate()
.scaleX(1f).scaleY(1f)
.setDuration(150)
.setInterpolator(new OvershootInterpolator())
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
isContextMenuShowing = false;
}
});
}
public void hideContextMenu() {
if (!isContextMenuDismissing) {
isContextMenuDismissing = true;
performDismissAnimation();
}
}
private void performDismissAnimation() {
contextMenuView.setPivotX(contextMenuView.getWidth() / 2);
contextMenuView.setPivotY(contextMenuView.getHeight());
contextMenuView.animate()
.scaleX(0.1f).scaleY(0.1f)
.setDuration(150)
.setInterpolator(new AccelerateInterpolator())
.setStartDelay(100)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (contextMenuView != null) {
contextMenuView.dismiss();
}
isContextMenuDismissing = false;
}
});
}
public class FeedContextMenuManager extends RecyclerView.OnScrollListener implements View.OnAttachStateChangeListener {
//...
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (contextMenuView != null) {
hideContextMenu();
contextMenuView.setTranslationY(contextMenuView.getTranslationY() - dy);
}
}
//..
}
<?xml version="1.0" encoding="utf-8"?>
<!-- styles.xml-->
<resources>
<!--...-->
<style name="ContextMenuButton">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:background">@drawable/btn_context_menu</item>
<item name="android:gravity">left|center_vertical</item>
<item name="android:paddingLeft">20dp</item>
<item name="android:paddingRight">20dp</item>
<item name="android:textColor">?attr/colorPrimary</item>
<item name="android:textSize">14sp</item>
</style>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:id="@+id/btnReport"
style="@style/ContextMenuButton"
android:text="REPORT"
android:textColor="@color/btn_context_menu_text_red" />
<Button
android:id="@+id/btnSharePhoto"
style="@style/ContextMenuButton"
android:text="SHARE PHOTO" />
<Button
android:id="@+id/btnCopyShareUrl"
style="@style/ContextMenuButton"
android:text="COPY SHARE URL" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#eeeeee" />
<Button
android:id="@+id/btnCancel"
style="@style/ContextMenuButton"
android:text="CANCEL" />
</merge>
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/tools"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="@dimen/default_elevation"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<ImageView
android:id="@+id/ivLogo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:scaleType="center"
android:src="@drawable/img_toolbar_logo" />
</android.support.v7.widget.Toolbar>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment