我有一个应用(here)中带有Admob横幅,我不喜欢每次更改方向后都会重新加载横幅的事实,所以很长一段时间以来,同样的解决方法,以避免重新创建活动,从而避免重新创建Admob视图:
<activity ... android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" android:screenOrientation="fullUser" ...>
这很好用,但是它并不是一个好的解决方案,也不推荐使用。由于这个问题,我不得不使用一种变通方法(对此here表示敬意)。
问题在于某些UI元素(例如工具栏)没有根据新的方向进行更改。
这导致工具栏与应用程序启动时保持相同的高度和相同的字体大小。
纵向->风景示例:
如您所见,横向的高度保持较大,字体大小也保持较大。
关于风景->肖像的示例:
在这里您看到相反的情况。高度保持较小,字体大小也保持较小。
布局基本上是这样的:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.drawerlayout.widget.DrawerLayout
android:id="@+id/activity_app_list__drawerLayout" android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary">
<androidx.appcompat.widget.Toolbar
android:id="@+id/activity_main__toolbar" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:background="@null"
android:theme="?attr/actionBarTheme" tools:ignore="UnusedAttribute"/>
</FrameLayout>
<RelativeLayout
android:layout_width="match_parent" android:layout_height="match_parent">
<FrameLayout
android:id="@+id/activity_app_list__fragmentContainer"
android:layout_width="match_parent" android:layout_height="match_parent"
android:layout_above="@+id/activity_app_list__adContainer"/>
<ImageView
android:layout_width="match_parent" android:layout_height="wrap_content"
android:src="@drawable/msl__action_bar_shadow"
tools:ignore="ContentDescription"/>
<FrameLayout
android:id="@+id/activity_app_list__adContainer"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
</LinearLayout>
<ScrollView
android:id="@+id/activity_app_list__drawerView" android:layout_width="240dp"
android:layout_height="match_parent" android:layout_gravity="start"
android:background="?android:attr/windowBackground">
<LinearLayout
android:layout_width="match_parent" android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/activity_app_list__appToolsContainer"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:divider="?attr/gridded_listview__divider" android:orientation="vertical"
android:showDividers="middle"
tools:ignore="MissingRegistered,UnusedAttribute"/>
<View
android:layout_width="match_parent" android:layout_height="1dp"
android:layout_marginBottom="8dp" android:layout_marginTop="8dp"
android:background="?attr/activity_app_list__drawer_lisview_divider"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/activity_app_list__usefulShortcutsContainer"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:divider="?attr/gridded_listview__divider" android:orientation="vertical"
android:showDividers="middle"
tools:ignore="MissingRegistered,UnusedAttribute"/>
<View
android:layout_width="match_parent" android:layout_height="1dp"
android:layout_marginBottom="8dp" android:layout_marginTop="8dp"
android:background="?attr/activity_app_list__drawer_lisview_divider"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/activity_app_list__appOtherContainer"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:divider="?attr/gridded_listview__divider" android:orientation="vertical"
android:showDividers="middle"
tools:ignore="MissingRegistered,UnusedAttribute"/>
</LinearLayout>
</ScrollView>
</androidx.drawerlayout.widget.DrawerLayout>
</RelativeLayout>
我尝试使用该属性将工具栏的高度重置为它应该具有的高度,但是没有用。还尝试将工具栏标题的文本外观设置为新的方向,但这没有帮助。
我也尝试调用requestLayout,但是它也不起作用。
如何告诉各种UI元素(例如工具栏),它应该根据新的配置更改而更改?
或者,即使我使用configChanges
,也可以将工具栏的样式和高度设置为基于新配置吗?
答案 0 :(得分:2)
Ref:Android - ActionBar not resizing with onConfigurationChanged ( AppCompat )
指出您应该保存并恢复实例状态,而不是尽可能自己处理配置更改。如果您有充分的理由不这样做,则可以在更改配置后尝试更新工具栏的高度和文本外观。
以下代码应适用于工具栏的支持库版本。支持库提供了actionBarSize,titleTextAppearance和subtitleTextAppearance属性。
代码假定您具有在attrs.xml中声明的自定义属性appToolbarStyle。如果不需要,可以修改代码以直接使用R.style.Widget_AppCompat_Toolbar。
import android.support.v7.widget.Toolbar;
...
private Toolbar toolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
toolbar = findViewById(R.id.toolbar);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
updateToolbar();
}
private void updateToolbar() {
if (toolbar == null)
return;
final Context context = toolbar.getContext();
int[] attr = new int[] { R.attr.actionBarSize, R.attr.appToolbarStyle };
int idxActionBarSize = 0;
int idxAppToolbarStyle = 1;
TypedArray a = context.obtainStyledAttributes(attr);
int actionBarSize = a.getDimensionPixelSize(idxActionBarSize, 0);
int appToolbarStyle = a.getResourceId(idxAppToolbarStyle, R.style.Widget_AppCompat_Toolbar);
a.recycle();
if (actionBarSize != 0) {
ViewGroup.LayoutParams layoutParams = toolbar.getLayoutParams();
if (layoutParams != null) {
layoutParams.height = actionBarSize;
}
toolbar.setMinimumHeight(actionBarSize);
}
attr = new int[] { R.attr.titleTextAppearance, R.attr.subtitleTextAppearance };
int idxTitleTextAppearance = 0;
int idxSubtitleTextAppearance = 1;
a = context.obtainStyledAttributes(appToolbarStyle, attr);
int titleTextAppearance = a.getResourceId(idxTitleTextAppearance, 0);
int subtitleTextAppearance = a.getResourceId(idxSubtitleTextAppearance, 0);
a.recycle();
if (titleTextAppearance != 0) {
toolbar.setTitleTextAppearance(context, titleTextAppearance);
}
if (subtitleTextAppearance != 0) {
toolbar.setSubtitleTextAppearance(context, subtitleTextAppearance);
}
toolbar.requestLayout();
}
答案 1 :(得分:0)
通过声明configChange,您确认自己将自行处理onConfigurationChanged()方法。 这是Android docs提供的示例:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
}
}
答案 2 :(得分:0)
尝试使用android:titleTextAppearance
代替app:titleTextAppearance
<android.support.v7.widget.Toolbar
android:id="@+id/main_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:titleTextAppearance="@style/ToolbarTitle"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
工具栏样式:
<style name="ToolbarTitle" parent="@style/TextAppearance.Widget.AppCompat.Toolbar.Title">
<item name="android:textSize">20sp</item>
</style>
我从here得到了这个答案。看看