Android: Collapsing Linearlayout instead of Collapsing Toolbar

前端 未结 4 724
生来不讨喜
生来不讨喜 2020-12-30 10:52

I\'m trying to create a Master/Detail transaction in a single fragment. I thought of using LinearLayout as the container of my edittext for my header. Then a RecyclerView fo

4条回答
  •  佛祖请我去吃肉
    2020-12-30 11:25

    You can use a timer and gradually shrink the height/margin of the topbar's LinearLayout (Edit: flaws in Anton Maiorov's answer is fixed here)

    See below snippet (tested on devices)

    Approach I: Anton Maiorov's answer, flaws fixed, this is much simpler than the 2nd implementation below

    public class MainActivity extends AppCompatActivity {
    
        LinearLayout toolbar;
        int mOriginalHeight;
        boolean initialSizeObtained = false;    
        boolean isShrink = false;
    
        Animation _hideAnimation = new Animation() {
            @Override
            protected void applyTransformation(float interpolatedTime, Transformation t) {
                LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) toolbar.getLayoutParams();
                params.topMargin = -(int) (mOriginalHeight * interpolatedTime);
                toolbar.setLayoutParams(params);
            }
        };
    
        Animation _showAnimation = new Animation() {
            @Override
            protected void applyTransformation(float interpolatedTime, Transformation t) {
                LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) toolbar.getLayoutParams();
                params.topMargin = (int) (mOriginalHeight * (interpolatedTime - 1));
                toolbar.setLayoutParams(params);
            }
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            toolbar = (LinearLayout) findViewById(R.id.toolbar);
            //Get the original height, which is measured according to WRAP_CONTENT
            toolbar.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    if (initialSizeObtained)
                        return;
                    initialSizeObtained = true;
                    mOriginalHeight = toolbar.getMeasuredHeight();
                }
            });
            _hideAnimation.setDuration(2000);
            _showAnimation.setDuration(2000);
        }
    
        //Click on the Olimpic image --> Toggles the top toolbar
        public void ToggleTopBar(View view) {
            isShrink = !isShrink;
    
            toolbar.clearAnimation();  //Important            
            toolbar.startAnimation(isShrink? _hideAnimation : _showAnimation);
        }
    }
    

    Approach II: my original answer by changing the toolbar's height, and also using timer manually, which is more involved:

    public class MainActivity extends AppCompatActivity {
    
        LinearLayout toolbar;
        int mOriginalHeight;
        boolean initialSizeObtained = false;
        int currentHeight;
        boolean isShrink = false;
        Timer timer;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            toolbar = (LinearLayout) findViewById(R.id.toolbar);
            toolbar.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    if (initialSizeObtained)
                        return;
                    initialSizeObtained = true;
                    mOriginalHeight = toolbar.getMeasuredHeight();
                    currentHeight = mOriginalHeight;
                    Log.d("Demo", "Original height is " + mOriginalHeight);
                }
            });
        }
    
        //Click on the Olimpic image --> Toggles the top toolbar
        public void ToggleTopBar(View view) {
            isShrink = !isShrink;
            Resize(isShrink, toolbar, 250);
        }
    
    
        void Resize(final boolean isShrink, final LinearLayout layout, final int minHeight) {
            final int H0 = mOriginalHeight;
            timer = runTimerAction(10, new Runnable() {
                        public void run() {
                            Log.d("demo", "Current Height= " + currentHeight);
                            if (isShrink && currentHeight > minHeight) {
                                currentHeight -= 10;
                                layout.getLayoutParams().height = currentHeight;
                                refreshToolbar();
                            } else if (!isShrink && currentHeight < H0) {
                                currentHeight += 10;
                                layout.getLayoutParams().height = currentHeight;
                                refreshToolbar();
                            } else {
                                layout.getLayoutParams().height = isShrink ? minHeight : H0;
                                refreshToolbar();
                                if (timer != null)
                                    timer.cancel();
                            }
                        }
                    }
            );
        }
    
        public void refreshToolbar() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    toolbar.requestLayout();
                }
            });
        }
    

提交回复
热议问题