I have been searching for an answer to this for days, and while some things kinda work (and most don’t), I’m hoping I can find the best practice for what I’m trying to do.
I’m trying to get a notification bar to display in my app. Ideally, it would slide down from the top, while shifting other elements in the layout to accommodate. Here’s an illustration to help: illustration
Here is how the layout is structured (I took out a bit for brevity):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false">
<!-- notification -->
<RelativeLayout
android:id="@+id/notification_bar"
android:layout_width="match_parent"
android:layout_height="40dip"
android:background="@drawable/notification_background"
android:visibility="visible">
<!-- end notifcation -->
</RelativeLayout>
<!-- header -->
<RelativeLayout
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="47dip"
android:layout_alignParentTop="true" >
<ImageView
android:id="@+id/header_bg"
android:layout_width="match_parent"
android:layout_height="47dip"
android:src="@drawable/home_header" />
<!-- end header -->
</RelativeLayout>
<!-- buttons -->
<LinearLayout
android:id="@+id/buttons"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/footer"
android:layout_below="@id/notification_bar"
android:layout_gravity="center_horizontal">
<ImageButton
android:id="@+id/button1"
android:src="@drawable/button1"
android:layout_width="86dip"
android:layout_height="65dip"
android:layout_weight=".4" />
<ImageButton
android:id="@+id/button2"
android:src="@drawable/button2"
android:layout_width="98dip"
android:layout_height="73dip"
android:layout_weight=".2" />
<ImageButton
android:id="@+id/button3"
android:src="@drawable/button3"
android:layout_width="86dip"
android:layout_height="71dip"
android:layout_weight=".4" />
<!-- end buttons -->
</LinearLayout>
<!-- footer -->
<LinearLayout
android:id="@id/footer"
android:layout_width="match_parent"
android:layout_height="76dip"
android:layout_alignParentBottom="true"
android:background="@drawable/home_footer" >
<!-- end footer -->
</LinearLayout>
</RelativeLayout>
MAIN PROBLEM:
To start, I animated the notification bar. It moves, and at the end of the animation, it snaps back into place. Yes, I have fillAfter set to true. It doesn’t make a difference. Regardless, the 3 items that should shift are clickable, and from what I’ve read, the elements haven’t actually moved, they just look like they have.
SECONDARY PROBLEM:
The entire view is a RelativeLayout, however the three elements are in a LinearLayout set via the XML to be layout_below the notification bar. I had hoped that shifting the notification bar would squeeze this LinearLayout, shifting the buttons to accommodate, but no such luck. If I have to shift the three elements as separate animations, that’s fine. I’ve tried that, but they suffer from the same “snap-back” issue the notification bar does. I was hoping there would be a simpler, more logical approach, however.
I’ve found a number of posts about this snap-back problem, but none of the solutions quite work (or make sense to me, granted a bit of a noob). It sounds like something needs to happen in the onAnimationEnd handler. I think it’s something with adjusting the LayoutParams, but I’m not sure how or what to do there.
I’m targeting for API 8 (2.2), so the Honeycomb animation APIs won’t help. I’ve looked into NineOldAndroids, which looks promising, but figure there has got to be a way to do this with the native API.
** Bonus points if we can get the notification bar to be dismissed, and everything moves back to its original position.
** UPDATE: The following code KIND OF works **
Here is the animation method to slide the notification bar out:
private void showNotification() {
mNotificationBar.setVisibility(View.VISIBLE);
Animation slideOut = AnimationUtils.loadAnimation(this, R.anim.slide_notification_out);
slideOut.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
// do nothing
}
@Override
public void onAnimationRepeat(Animation animation) {
// do nothing
}
@Override
public void onAnimationEnd(Animation animation) {
// do SOMETHING
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mNotificationBar.getLayoutParams();
params.addRule(RelativeLayout.BELOW, mHeader.getId());
mNotificationBar.setLayoutParams(params);
mNotificationBar.clearAnimation();
}
});
mNotificationBar.startAnimation(slideOut);
}
Altering the LayoutParams on AnimationEnd keeps the Notification bar in place. AND, when the animation is done, the Buttons layout squeezes to accommodate! BUT, the button layout doesn’t smoothly animate like the Notification Bar, it just snaps into place at the end of the animation. Also, the Notification Bar also jumps a bit at the very end of the animation, I’m guessing because the layout is being redrawn. SO CLOSE, but so far.
Snap back problemYou need to define the notification in the final place that you want it to appear in the layout. For you it’s probably as the first item in the
LinearLayoutyou refer above. Then you setvisibilitytogone.Finally you use a piece of code similar to the one bellow (I´m using it to animate buttons into the screen):
Squeeze problemThis one I’ve never tried with an animation, but you can set the
android:layout_weight="1.0"in each one of the items in your relative layout, to split the available space equaly between them (or play with the value to assign diferent space for each).Regards.