package com.sqisland.android.sliding_pane_layout; 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; public class CrossFadeSlidingPaneLayout extends SlidingPaneLayout { private View partialView = null; private View fullView = null; // helper flag pre honeycomb used in visibility and click response handling // helps avoid unnecessary layouts private boolean wasOpened = 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) { listener.onPanelOpened(panel); } @Override public void onPanelClosed(View 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); if (partialView != null) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { // "changed" means that views were added or removed // we need to move the partial view out of the way in any case (if it's supposed to of course) updatePartialViewVisibilityPreHoneycomb(isOpen()); } else { partialView.setVisibility(isOpen() ? View.GONE : VISIBLE); } } } private SimplePanelSlideListener crossFadeListener = new SimplePanelSlideListener() { @Override public void onPanelSlide(View panel, float slideOffset) { super.onPanelSlide(panel, slideOffset); if (partialView == null || fullView == null) { return; } if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { if (slideOffset == 1 && !wasOpened) { // the layout was just opened, move the partial view off screen updatePartialViewVisibilityPreHoneycomb(true); wasOpened = true; } else if (slideOffset < 1 && wasOpened) { // the layout just started to close, move the partial view back, so it can be shown animating updatePartialViewVisibilityPreHoneycomb(false); wasOpened = false; } } else { partialView.setVisibility(isOpen() ? View.GONE : VISIBLE); } ViewHelper.setAlpha(partialView, 1 - slideOffset); ViewHelper.setAlpha(fullView, slideOffset); } }; private void updatePartialViewVisibilityPreHoneycomb(boolean slidingPaneOpened) { // below API 11 the top view must be moved so it does not consume clicks intended for the bottom view // this applies curiously even when setting its visibility to GONE // this might be due to platform limitations or it may have been introduced by NineOldAndroids library if (slidingPaneOpened) { partialView.layout(-partialView.getWidth(), 0, 0, partialView.getHeight()); } else { partialView.layout(0, 0, partialView.getWidth(), partialView.getHeight()); } } }