为什么从约束布局1.0.2切换到1.1.3会破坏我的自定义工具栏?

斯蒂芬M-罢工-

我们有一个Android应用程序,其中一些活动共享一个工具栏。一切运行良好,直到(根据Android Studio的建议)我将build.gradle文件从constraint-layout:1.0.2切换到1.1.3。现在,工具栏覆盖了整个可见屏幕。我不确定为什么会这样或如何解决。我当前的解决方法是回到1.0.2。

关于这种情况为什么发生以及如何解决的任何想法?

这是build.gradle依赖项:

dependencies {
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    implementation 'com.android.support:support-v4:26.1.0'
    implementation 'com.android.support:design:26.1.0'
    implementation project(':pocketsphinx-android-5prealpha-release')
    implementation project(':models')
    implementation 'com.ibm.watson.developer_cloud:java-sdk:4.2.1'
    implementation ('net.java.dev.jna:jna:4.2.2')
    implementation 'com.ibm.watson.developer_cloud:java-sdk:3.9.1'
    implementation project(':ibm-library')
    implementation project(':annotations')
    implementation files('../../../../lib/findBugs-2.0.2/annotations.jar')
    annotationProcessor project(':annotations')
    implementation project(':falcon') // Supports screenshots

    testImplementation 'junit:junit:4.12'
    // We use Mockito because it doesn't need extra code to mock final methods and classes.
    // JMock could work, if DexOpener worked (like JDave-Unfinalizer, but for DEX files), but
    // I was unable to make it work.  Hence I switched to Mockito, which is the favorite among Android
    // Developers (SMM)
//    testImplementation 'org.mockito:mockito-core:2.13.0'
//    testImplementation 'org.mockito:mockito-inline:2.13.0'
    testImplementation files('../../../../lib/jmock-2.8.4/hamcrest-core-1.3.jar')
    testImplementation files('../../../../lib/jmock-2.8.4/hamcrest-library-1.3.jar')
    testImplementation files('../../../../nb/ORCCommon/dist/ORCCommon-test.jar')
    testImplementation files('../../../../nb/CommonLibrary/dist/CommonLibrary-test.jar')
    androidTestImplementation 'com.android.support.test:rules:1.0.1'
    androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.1', {
        exclude group: 'com.google.code.findbugs' // We already have findbugs
    })
}

这是工具栏:

<?xml version="1.0" encoding="utf-8"?>

<com.hcs.android.orconnect.ui.widget.ORConnectToolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:background="?attr/colorPrimary"
    android:minHeight="?attr/actionBarSize"
    android:theme="?attr/actionBarTheme"
    app:titleTextAppearance="@style/TextAppearance.Widget.Event.Toolbar.Title"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:logo="@mipmap/ic_launcher">

</com.hcs.android.orconnect.ui.widget.ORConnectToolbar>

这是工具栏代码:

package com.hcs.android.orconnect.ui.widget;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.Toolbar;
import android.text.Layout;
import android.util.AttributeSet;
import android.view.ViewTreeObserver;
import android.widget.TextView;

import com.hcs.android.orconnect.ORConnectApplication;
import com.hcs.android.orconnect.R;

import java.lang.reflect.Field;
import java.util.GregorianCalendar;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Custom toolbar, that also serves as our "red bar" much like the downTimePanel in FullScreenFrame in ORC.
 */
public class ORConnectToolbar extends Toolbar {
    private static final Logger log = Logger.getLogger("com.hcs.android.orconnect.ui.widget.ORConnectToolbar");
    /** The old title when we've changed the title for something like a connection failure. */
    private CharSequence defaultTitle;
    /** The default background color. */
    private int defaultBackgroundColor;
    /** True if we are showing a connection failure. */
    private boolean redBarVisible = false;
    /** Keep this so we only create one and clean up after ourselves. */
    private ViewTreeObserver.OnGlobalLayoutListener layoutListener = null;

    public ORConnectToolbar(Context context) {
        super(context);
    }

    public ORConnectToolbar(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public ORConnectToolbar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if(layoutListener != null) {
            TextView titleView = getActionBarTextView();
            if (titleView != null) {
                ViewTreeObserver viewTreeObserver = titleView.getViewTreeObserver();
                viewTreeObserver.removeOnGlobalLayoutListener(layoutListener);
                layoutListener = null;
            }
        }
    }

    @Override
    public void setTitle(int resId) {
        setTitle(getContext().getText(resId));
    }

    @Override
    public void setTitle(CharSequence title) {
        super.setTitle(title);
        // Since the layout listener is going to shrink things, but not make them bigger, we on every
        // title change, we reset the font.
        setTitleTextAppearance(getContext(), R.style.TextAppearance_Widget_Event_Toolbar_Title);
        // If we do not have a layout listener to adjust the text size to avoid ellipsis
        if(layoutListener == null) {
            // This is hacky, but Android doesn't provide us another way to get the Title Text View so we can listen to it.  Thanks, Google!
            TextView titleView = getActionBarTextView();
            if (titleView != null) {
                ViewTreeObserver viewTreeObserver = titleView.getViewTreeObserver();
                layoutListener = () -> {
                    // Do we have ellipses on the end of our title?  Very bad, Google!  Shrink to fit!
                    Layout layout = titleView.getLayout();
                    if (layout != null) {
                        int lines = layout.getLineCount();
                        if (layout.getEllipsisCount(lines) > 0) {
                            // Yes, we have ellipsis, grrr...
                            float currentSize = titleView.getTextSize() / titleView.getPaint().density; // Google, won't let us get the scaled pixels, so we have to do the scaling ourselves... really guys!
                            titleView.setTextSize(currentSize - 2);
                        }
                    }
                };
                viewTreeObserver.addOnGlobalLayoutListener(layoutListener);
            }
        }
    }

    /**
     * Google forgot to make the titleTextView protected so we could do things with it.  So, we use
     * reflection to work around that (yuck!).
     *
     * Thanks Google!
     * @return the title text view, if we were able to get it.
     */
    private TextView getActionBarTextView() {
        TextView titleTextView = null;
        try {
            Field f = Toolbar.class.getDeclaredField("mTitleTextView");
            f.setAccessible(true);
            titleTextView = (TextView) f.get(this);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            log.log(Level.WARNING, "Unable to get Toolbar Title TextView by reflection.  Shrink to fit may not work!", e);
        }
        return titleTextView;
    }
}

最后,一个显示问题的活动:

<?xml version="1.0" encoding="utf-8"?>

<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <include layout="@layout/toolbar"/> <!-- Bring the tool bar in -->

    <TextView
        android:id="@+id/textView12"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Loading..."
        android:textSize="90sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/toolbar"
        tools:ignore="UnknownId,UnknownIdInLayout"
        tools:text="Loading..." />

</android.support.constraint.ConstraintLayout>
我是

将工具栏的高度从更改match_parent?attr/actionBarSize

android:layout_height="?attr/actionBarSize"

此外,请删除此属性,因为它没有任何作用:

android:minHeight="?attr/actionBarSize

请注意,ConstraintLayout它不支持match_parent其子级。如果要“匹配父级”行为,则应将0dp具有左约束,右约束或顶约束和下约束的维组合到父级。

然而,即使ConstraintLayout不正式支持match_parent,它确实有时“工作”。这会因版本而异,因构建而异,等等。因此,您的旧版本可能忽略了它,而新版本并未忽略它(因此您的工具栏正在显示整个屏幕)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章