package net.xpece.material.navigationdrawer.list;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.support.v4.widget.SlidingPaneLayout;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import com.nineoldandroids.view.ViewHelper;
/**
* @author https://github.com/chiuki/sliding-pane-layout
* @author http://blog.sqisland.com/2015/01/partial-slidingpanelayout.html
*/
public class CrossFadeSlidingPaneLayout extends SlidingPaneLayout {
private View partialView = null;
private View fullView = null;
// helper flag pre honeycomb - visibility and click response handling
private boolean mWasOpened = false;
public CrossFadeSlidingPaneLayout(Context context) {
super(context);
}
public CrossFadeSlidingPaneLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CrossFadeSlidingPaneLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
if (getChildCount() < 1) {
return;
}
View panel = getChildAt(0);
if (!(panel instanceof ViewGroup)) {
return;
}
ViewGroup viewGroup = (ViewGroup) panel;
if (viewGroup.getChildCount() != 2) {
return;
}
fullView = viewGroup.getChildAt(0);
partialView = viewGroup.getChildAt(1);
super.setPanelSlideListener(crossFadeListener);
}
@Override
public void setPanelSlideListener(final PanelSlideListener listener) {
if (listener == null) {
super.setPanelSlideListener(crossFadeListener);
return;
}
super.setPanelSlideListener(new PanelSlideListener() {
@Override
public void onPanelSlide(View panel, float slideOffset) {
crossFadeListener.onPanelSlide(panel, slideOffset);
listener.onPanelSlide(panel, slideOffset);
}
@Override
public void onPanelOpened(View panel) {
crossFadeListener.onPanelOpened(panel);
listener.onPanelOpened(panel);
}
@Override
public void onPanelClosed(View panel) {
crossFadeListener.onPanelClosed(panel);
listener.onPanelClosed(panel);
}
});
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
// this has to be done on each layout (changed means views were added or removed)
if (partialView != null) {
updateVisibility(isOpen());
}
}
private SimplePanelSlideListener crossFadeListener = new SimplePanelSlideListener() {
@Override
public void onPanelSlide(View panel, float slideOffset) {
super.onPanelSlide(panel, slideOffset);
if (partialView == null || fullView == null) {
return;
}
updateVisibility(slideOffset);
setAlpha(partialView, 1 - slideOffset); // only top view should fade
// setAlpha(fullView, slideOffset); // full view should be opaque anyway
// this could save some overdraw
}
};
private void updateVisibility(float slideOffset) {
if (Build.VERSION.SDK_INT < 11) {
updateVisibilityBase(slideOffset);
} else {
updateVisibilityHoneycomb(slideOffset == 1);
}
}
private void updateVisibility(boolean visible) {
if (Build.VERSION.SDK_INT < 11) {
updateVisibilityBase(visible);
} else {
updateVisibilityHoneycomb(visible);
}
}
private void updateVisibilityBase(float slideOffset) {
if (slideOffset == 1 && !mWasOpened) {
updateVisibilityBase(true);
mWasOpened = true;
} else if (slideOffset < 1 && mWasOpened) {
updateVisibilityBase(false);
mWasOpened = false;
}
}
/**
* Pre-Honeycomb the views have to be physically repositioned otherwise they still listen
* on original places for touch.
* Curiously this happened here even when visibility was set to gone.
*
* @param visible
*/
private void updateVisibilityBase(boolean visible) {
if (visible) {
partialView.layout(-partialView.getWidth(), 0, 0, partialView.getHeight());
} else {
partialView.layout(0, 0, partialView.getWidth(), partialView.getHeight());
}
}
private void updateVisibilityHoneycomb(boolean visible) {
partialView.setVisibility(visible ? View.GONE : VISIBLE);
}
@TargetApi(11)
private static void setAlpha(View view, float alpha) {
if (Build.VERSION.SDK_INT >= 11) {
view.setAlpha(alpha);
} else {
ViewHelper.setAlpha(view, alpha);
}
}
}