Question

I'm doing this bar

showing-refreshing-message-in-action-bar

It's work just fine.However, I want to animate it to slide down from the top.

I can animate other object which create in layout but not by getWindowManager().addview

This is work for my object in current layout

switch(item.getItemId())
{
    case R.id.zoomInOut:
        TextView image = (TextView)findViewById(R.id.textView);
        Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.myanimation);
        image.startAnimation(animation);
        return true;
    case R.id.rotate360:
        TextView image1 = (TextView)findViewById(R.id.textView);
        Animation animation1 = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.clockwise);
        image1.startAnimation(animation1);
        return true;
    case R.id.fadeInOut:
        TextView image2 = (TextView)findViewById(R.id.textView);
        Animation animation2 = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.fade);
        image2.startAnimation(animation2);
        return true;
}

This is not work for my view that add by getWindowManager().addview

    /** The notification layout */
    private TextView mMessage;

    public void showLoadingMessage(Context context,String msg) {

        // Initialize the layout
        if (mMessage == null) {
            final LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            mMessage = (TextView) inflater.inflate(R.layout.test, null);
            mMessage.setBackgroundColor(getResources().getColor(R.color.holo_green_light));
            mMessage.setText(msg);
        }

        // Add the View to the
        getWindowManager().addView(mMessage,getActionBarLayoutParams());

        //ANIMATION FOR THIS LAYOUT START HERE
        Animation aa = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.fade);
        mMessage.startAnimation(aa);

    }

    public void removeLoadingMessage() {
        if (mMessage != null && mMessage.getWindowToken() != null) {
            getWindowManager().removeViewImmediate(mMessage);
            mMessage = null;
        }
    }


    private WindowManager.LayoutParams getActionBarLayoutParams() {
        // Retrieve the height of the status bar
        final Rect rect = new Rect();
        getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
        final int statusBarHeight = rect.top;


        // Create the LayoutParams for the View
        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,200,
                WindowManager.LayoutParams.TYPE_APPLICATION_PANEL,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);
//        params.gravity = Gravity.TOP;
        params.x = 0;
        params.y = statusBarHeight;

        return params;
    }
Was it helpful?

Solution

I want to animate it to slide down from the top.

After you call WindowManager.addView you can attach a ViewTreeObserver.OnGlobalLayoutListener to the View and use that to get the height, then use an ObjectAnimator to perform the translation. Here's an example:

mMessage.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

    @Override
    public void onGlobalLayout() {
        // Get the height of the view
        final int h = mMessage.getHeight();
        // Remove the OnGlobalLayoutListener callback
        mMessage.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        // Slide down from the top
        final ObjectAnimator oa = ObjectAnimator.ofFloat(mMessage, "translationY", -h, 0f);
        oa.setDuration(250);
        oa.start();
    }

});

If you want to slide it back up later, perform the opposite translation and attach an AnimatorListener to know when to call WindowManager.removeViewImmediate. For instance:

private void removeLoadingMessage(boolean animate) {
    if (mMessage != null && mMessage.getWindowToken() != null) {
        // Detach the View immediately, don't wait for the animation to end
        if (!animate) {
            getWindowManager().removeViewImmediate(mMessage);
            mMessage = null;
            return;
        }

        // Slide back up
        final int h = mMessage.getHeight();
        final ObjectAnimator oa = ObjectAnimator.ofFloat(mMessage, "translationY", 0f, -h);
        oa.setDuration(250);
        // Wait until the end of the animation to detach the View
        oa.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                getWindowManager().removeViewImmediate(mMessage);
                mMessage = null;
            }
        });
        oa.start();
    }
}

To avoid any leaks, in Activity.onDestroy you'd want to use removeLoadingMessage(false); to ensure the View to properly detached from the Window.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top