FrameLayout.LayoutParams 无效

FrameLayout.LayoutParams doesn't work

我试图在 activity( screen shot of the activity) 中避免以下情况。当我使用 setMargins 添加边距时,它不起作用。我已经尝试通过 xml 代码添加边距并实现了最终结果,但它非常耗时并且不能保证它适用于所有设备。我怎样才能在代码中做到这一点?

这是代码。

package com.example.android.tourguide;

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.NavigationView;
import android.support.design.widget.TabLayout;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.widget.FrameLayout;

public class TouristAttractions extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
private NavigationView mNavigationView;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.menu_item);
    /*
      Finding the Toolbar that is defined in activity_main.xml via the id toolbar.
      Note:The following three lines should be repeated for all the activities that are opened from the MainActivity. Also the toolbar should have an orientation
      which is not zero.
     */
    android.support.v7.widget.Toolbar toolbar = (android.support.v7.widget.Toolbar) findViewById(R.id.toolbar_for_menu_items);
    /*
       Setting the action bar as the toolbar defined in the above code line
     */
    setSupportActionBar(toolbar);
    /*
      Setting the title text color of the app bar.
     */
    toolbar.setTitleTextColor(ContextCompat.getColor(this, R.color.color_of_text_of_app_bar));
    mNavigationView = (NavigationView) findViewById(R.id.navigation_view);
    /*
       Finding the drawerLayout so that when the user clicks on the menu item of the navigation drawer it should close as we invoke the method closeDrawers()
     */
    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {

            if (menuItem.getItemId() == R.id.home_menu) {
                /*
                Opening the home class that is the MainActivity when the Tourist Home menu button is clicked.
                 */
                Intent intentToOpenHomeClass = new Intent(TouristAttractions.this, MainActivity.class);
                startActivity(intentToOpenHomeClass);
            } else if (menuItem.getItemId() == R.id.entertainment_menu) {
                Intent intentToOpenEntertainmentClass = new Intent(TouristAttractions.this, Entertainment.class);
                startActivity(intentToOpenEntertainmentClass);
            } else if (menuItem.getItemId() == R.id.gardens_menu) {
                Intent intentToOpenGardenClass = new Intent(TouristAttractions.this, Garden.class);
                startActivity(intentToOpenGardenClass);
            } else {
                mDrawerLayout.closeDrawers();
            }
            return true;
        }
    });
    TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout_for_menu_items);
    ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager_for_menu_items);
    AdapterForFragmentOfTouristAttraction adapterForFragmentOfTouristAttraction = new AdapterForFragmentOfTouristAttraction(this, getSupportFragmentManager());
    viewPager.setAdapter(adapterForFragmentOfTouristAttraction);
    tabLayout.setupWithViewPager(viewPager);
    FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) toolbar.getLayoutParams();
    params.setMargins(0, toolbar.getHeight(), 0, 0);
    ActionBar actionbar = getSupportActionBar();
    /*
    actionBar.setDisplayHomeAsUpEnabled(true) will make the icon clickable and add the < at the left of the icon.

     */
    actionbar.setDisplayHomeAsUpEnabled(true);
    /*
    Enabling the menu icon of the navigation.However note we are simply adding the menu icon however clicking on the icon does absolutely nothing.
     */
    actionbar.setHomeAsUpIndicator(R.drawable.baseline_menu_white_24);

}

}

首先,最好使用垂直方向的 LinearLayout、RelativeLayout 或 ConstraintLayout 将视图放置在彼此下方。在更奇特的用例中,甚至 CoordinatorLayout 可能更适合。

FrameLayouts 主要用于简单地将视图相互叠加,它们之间没有依赖关系。


这就是说,您遇到的问题是因为您在添加视图后立即使用了 toolbar.getHeight(),它始终是 0。尝试附加调试器并亲自查看!

原因是 Android 需要一些时间来 measure -> layout -> draw 它的视图,如果您在添加布局后立即调用 getHeight 它不会完成其中任何一个步骤,在 0.

处保留未初始化的值

有很多方法可以解决这个问题,但同样,您最好同时使用不同的布局。如果您坚持使用 FrameLayout,最简洁的方法是扩展它并创建您自己的,您可以在其中自己测量和布局视图。骇人听闻、难以维护且令人困惑的方法是使用 ViewTreeObserver 来监听变化并对它们做出反应。这很糟糕,因为您必须等待完整的布局通过才能触发另一个。


不要在此处使用 FrameLayout。

你还没有完成

yourView.setLayoutParams(params);