android - FrameLayout.LayoutParams 不起作用
问题描述
我试图避免活动中出现以下情况(活动的屏幕截图)。当我使用 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,最简洁的方法是扩展它并创建自己的,您可以在其中自己测量和布局视图。hacky、难以维护和令人困惑的方法是ViewTreeObserver
用来监听变化并对它们做出反应。这很糟糕,因为在触发另一个布局之前,您必须等待完整的布局通过。
不要在这里使用 FrameLayout。
推荐阅读
- java - Launcher Activity 和 Thread run() 被调用两次
- python - Python中函数的静态变量是什么?
- html - 像谷歌一样制作按钮动画(涟漪效应)
- regex - Spring Cloud Gateway:在传入请求中重写 URI
- javascript - 如何在我的 React 项目中导入为 JQuery 设计的小部件?
- mongodb - 如何乘以 MongoDB 中 csv 字符串的数量?
- docker - Docker使用套接字组成容器之间没有连接
- python - 为什么我的 Ubuntu Apache 服务器上的 Flask 应用程序得到 ERR_CONNECTION_REFUSED?
- python - 使用 Python Pandas 根据多个条件创建一个名为 df['EV_Sales_Score'] 的列
- ubuntu - 如何匹配文件中的某些单词并列出该匹配单词的所有行?(没有正则表达式)