代码之家  ›  专栏  ›  技术社区  ›  android developer

如何根据新的配置更改重新调整视图?

  •  6
  • android developer  · 技术社区  · 7 年前

    背景

    我有一个应用程序( here )其中包含AdMob横幅,我不喜欢每次改变方向时都会重新加载横幅,因此在很长一段时间内,我都有相同的解决方法,以避免重新创建活动,从而避免重新创建AdMob视图:

    <activity ... android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" android:screenOrientation="fullUser" ...>
    

    问题

    这很好用,但不是一个很好的解决方案或建议只是因为这个问题我不得不使用的一个变通方法 here ).

    问题是,一些ui元素(比如工具栏)不能根据新的方向进行更改。

    这会导致工具栏保持与应用程序启动时相同的高度和字体大小。

    纵向上的示例->横向:

    enter image description here

    如您所见,景观的高度保持较大,字体大小也保持较大。

    横向示例->纵向:

    enter image description here

    你看到的恰恰相反。它的高度很小,字体也很小。

    布局基本上是这样的:

    <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 是吗?

    4 回复  |  直到 6 年前
        1
  •  2
  •   Ashvin solanki    6 年前

    裁判: Android - ActionBar not resizing with onConfigurationChanged ( AppCompat )

    指出如果可能的话,您应该保存并恢复实例状态,而不是自己处理配置更改如果有充分的理由不这样做,则可以在配置更改后尝试更新工具栏的高度和文本外观。

    以下代码适用于工具栏的支持库版本。ActionBarSize、TitleTextAppearance和SubtitleTextAppearance属性由支持库提供。

    代码假设您在attrs.xml中声明了自定义属性appToolbarStyle如果不需要,可以调整代码,直接使用r.style.widget_appcompat_工具栏。

    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();
    }
    
        2
  •  0
  •   Ahmet Zorer    7 年前

    通过声明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();
        }
    }
    
        3
  •  0
  •   Niravdas    6 年前

    您可以使用简单的刷新按钮来刷新任何视图控件。 把刷新按钮放在下面的简单按钮上,你可以根据需要改变按钮的属性。

    <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Refresh"
            android:onClick="btnrefresh"/>
    

    现在简单地说,您可以在click事件中编写代码。

    public void btnrefresh(View view)
    {
     //Do your task here to change any View Control(including Layout Changes).
    }
    

    它将在您编写代码时对UI进行更改。

        4
  •  0
  •   Kevin Kurien    6 年前

    而不是 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 .看看