Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GlassActionBar and NavigationDrawer #7

Open
magx2 opened this issue Jun 30, 2014 · 6 comments
Open

GlassActionBar and NavigationDrawer #7

magx2 opened this issue Jun 30, 2014 · 6 comments

Comments

@magx2
Copy link

magx2 commented Jun 30, 2014

Will you do sample app using NavigationDrawer and GlassActionBar?

@ManuelPeinado
Copy link
Owner

Sorry Martin but I don't have time to devote to the library at the moment.

On Mon, Jun 30, 2014 at 11:05 PM, Martin notifications@github.com wrote:

Will you do sample app using NavigationDrawer and GlassActionBar?


Reply to this email directly or view it on GitHub
#7.

@magx2
Copy link
Author

magx2 commented Jul 1, 2014

Can you give me any tip how to do this? Maybe I will do some sample.

@Chuckytuh
Copy link

I've been trying to implement it and I believe that instead of using helper.createView() on your activity::onCreate() you might be able to use the helper on your fragment::onCreateView() and instead of using the inflater to inflate your fragment you simply pass your fragment layout (The one you would inflate using the inflater and return as the result of fragment::onCreateView()) to the helper.createView function...Ex:

On your Fragment

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    GlassActionBarHelper helper = new GlassActionBarHelper().contentLayout(R.layout.fragment_event_info);
    View root = helper.createView(getActivity());
    (...)
    return root;

}

Though this is partially working here...the view is loaded and added correctly to the screen but the problem arrives when I try to scroll the scrollview because this exception gets thrown:

6445-6445/pt.idc E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.IllegalArgumentException: y + height must be <= bitmap.height()
            at android.graphics.Bitmap.createBitmap(Bitmap.java:549)
            at android.graphics.Bitmap.createBitmap(Bitmap.java:514)
            at com.manuelpeinado.glassactionbar.GlassActionBarHelper.updateBlurOverlay(GlassActionBarHelper.java:226)
            at com.manuelpeinado.glassactionbar.GlassActionBarHelper.onNewScroll(GlassActionBarHelper.java:264)
            at com.manuelpeinado.glassactionbar.GlassActionBarHelper.onScrollChanged(GlassActionBarHelper.java:250)
            at com.cyrilmottier.android.translucentactionbar.NotifyingScrollView.onScrollChanged(NotifyingScrollView.java:44)
            at android.view.View.scrollTo(View.java:10057)
            at android.widget.ScrollView.onOverScrolled(ScrollView.java:763)
            at android.view.View.overScrollBy(View.java:16540)
            at android.widget.ScrollView.onTouchEvent(ScrollView.java:634)
            at android.view.View.dispatchTouchEvent(View.java:7246)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2168)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1903)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1953)
            at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1405)
            at android.app.Activity.dispatchTouchEvent(Activity.java:2410)
            at android.support.v7.app.ActionBarActivityDelegateICS$WindowCallbackWrapper.dispatchTouchEvent(ActionBarActivityDelegateICS.java:260)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1901)
            at android.view.View.dispatchPointerEvent(View.java:7426)
            at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3220)
            at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3165)
            at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4292)
            at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4271)
            at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4363)
            at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:179)
            at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
            at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:171)
            at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:4342)
            at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:4382)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
            at android.view.Choreographer.doCallbacks(Choreographer.java:562)
            at android.view.Choreographer.doFrame(Choreographer.java:530)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
            at android.os.Handler.handleCallback(Handler.java:725)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5041)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Metho

@Chuckytuh
Copy link

Here's what I found now, I started a blank project with activity + fragment. Using the bootstrap code from the Android Studio I changed:

  • The activity style to set the overlay and background properties of the actionbar
  • The "fragment_main.xml" layout in order to have a NotifyingScrollView as the root view
  • The "Placeholder" fragment in order to include the following code:
@Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            GlassActionBarHelper helper = new GlassActionBarHelper().contentLayout(R.layout.fragment_main);
            View rootView = helper.createView(getActivity());
            return rootView;
        }

After those changes I simply ran the app and it crashes but (strangely!) no exception is to be seen on the logcat..oh yeah I'm using genymotion!

Then I proceed to add an ImageView inside the NotifiyingScrollView, like so:

<com.cyrilmottier.android.translucentactionbar.NotifyingScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/new_york_city_1"
            android:scaleType="fitStart"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Text View"/>

    </LinearLayout>

</com.cyrilmottier.android.translucentactionbar.NotifyingScrollView>

Et voila, it works but it is necessary to have an ImageView as the first child on the LinearLayout..not quite sure why but I didn't look at the GlassActionbarHelper code properly!

@Chuckytuh
Copy link

Another finding...if the height of the LinearLayout is less than the height of the ActionBar the exception that I posted earlier is thrown ( "java.lang.IllegalArgumentException: y + height must be <= bitmap.height()" ) and my previous comment about the first item needing to be an ImageView isn't totally true, I tried the following layout:

<com.cyrilmottier.android.translucentactionbar.NotifyingScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="YADA YADA"/>
        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="YADA YADA"/>
        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="YADA YADA"/>
        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="YADA YADA"/>
    </LinearLayout>

</com.cyrilmottier.android.translucentactionbar.NotifyingScrollView>

and this is the result: http://i.imgur.com/HcZKwZ1.png

Maybe some more values checks should be done in order to prevent ANR and probably there could be support for non scroll/list views

Edit 1: Another finding lol..if your layout contains a view with visibility set to gone then the same exception as before will be present...my 2 cents here is that when there's a view set to gone, for example, one of the the TextViews above, the measured sizes will return 0 for the wrapping view and this is causing the bitmap created from the container view to have width and height of -1 so when we try to run "Bitmap actionBarSection = Bitmap.createBitmap(...)" it throws the exception..

Any ideas to circumvent this situation?

Edit2: Another conclusion that I made! The measurements are made when theres a OnGlobalLayout and in my case I am loading images using the UniversalImageLoader meaning that they have their loading and rendering deferred.. my conclusion here is that when you have something that is loaded and presented asynchronously on your view you need to somehow "block" the execution of the GlassActionbarHelper code until your view is completely loaded otherwise the first time it runs the OnGlobalLayout handler the view width/height might be -1 resulting on the IllegalArgumentException!

@Chuckytuh
Copy link

More work has been done! (By the way, sorry for the constant spam, I'm doing this in order to document as max as possible so that others don't have the same problems that I'm facing)

If you have the need to load, lets say, an image asynchronously and place it as the first item on your scrollview you'll need to somehow inform the GlassActionbarHelper to only call the onGlobalLayout callback after all the view as been loaded because that's the place where GlassActionbarHelper measures the content view and sets its width and height properties.
Here's what I did:

public class MyCustomGlassActionBarHelper extends GlassActionBarHelper {

    public boolean isViewLoaded() {
        return mViewLoaded;
    }

    public void setIsViewLoaded(boolean mViewLoaded) {
        this.mViewLoaded = mViewLoaded;
    }

    private boolean mViewLoaded = false;

    @Override
    public void onGlobalLayout() {
        if(!mViewLoaded)
            return;
        super.onGlobalLayout();
    }
}

so instead of using the GlassActionbarHelper now I use MyCustomGlassActionBarHelper. The second thing that is VERY IMPORTANT to do is to set the mViewLoaded property as true when your view is fully loaded...if you're using an asynctask to load an image and to place it on your ImageView than you must go ahead and call the setter on the helper when the asynctask ends.
This works because when an image is set on the ImageView the layout is invalidated and the onGlobalLayout event from the ViewTreeObserver is called. This way we know that the measurements done have the correct values.

Although this might be enough I still got a glitch:

width_bug

As you can see the image blurred is a scaled version of the content and this happens because when the content.measure() function is called on GlassActionbarHelper::onGlobalLayout the resulting width get a really strange value ( 16777464 , yeah go figure) so what I did next was to change the line

int widthMeasureSpec = MeasureSpec.makeMeasureSpec(frame.getWidth(), MeasureSpec.AT_MOST);

to

int widthMeasureSpec = MeasureSpec.makeMeasureSpec(frame.getWidth(), MeasureSpec.EXACTLY);

and this is the result:

screen shot 2014-07-04 at 5 09 48 pm

Now the blurred image is correctly created and it seems to work properly..

Next I need to think in a way to include the NavDrawer so that this doesn't happens:
screen shot 2014-07-04 at 5 46 03 pm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants