前言:這個問題在目前的開發生涯中,令我比較深刻,以至于過去快1年了,我還記憶猶新,在此記錄一下,
場景:大約在1年前,當時負責的一個WMS倉儲管理APP(Kotlin專案),線上突然反饋了“輸入框被軟鍵盤遮擋的問題”,接手問題后,使用線下物聯網定制手持機除錯復現中,系統版本為Android 8.0,
問題現象:目前暫時沒有設備,因而無法復現,故暫時不上gif圖,這邊口頭描述一下:在頁面中間部分有一個輸入框,點擊輸入框喚出軟鍵盤時,輸入框被軟鍵盤遮擋了一部分,這一部分就看不到了,遮擋程度取決于輸入框位置,可能被遮擋部分或被全遮擋;位于頁面上方的,比如搜索框之類的,不受影響;對于軟體盤輸入事件不影響,輸入的資料還是能拿到的,
解決:當時遇到這個問題,比較懵逼,且也找不到相關資料,只能不斷試錯,通過猜測進行嘗試,中間也橫向對比了其他專案,在該手持機上跑;轉折點在“部分遮擋”情況下,部分遮擋的時候,輸入的文字、游標都展示了一半,就感覺是可能是渲染問題,于是開啟了專案全域硬體加速進行嘗試,最終解決了問題,
<application>
...
android:hardwareAccelerated="true"
</application>

總結:一般沒有沖突或其它連帶問題情況下,硬體加速優先還是開啟比較好,如果遇到專案不得不開啟硬體加速,而其他地方開啟硬體加速會出現問題的情況,則可以結合Application、Activity、Window、View這四個層面對硬體加速打開或關閉,
View開啟硬體加速方法view.setLayerType(),原始碼如下:
/**
* <p>Specifies the type of layer backing this view. The layer can be
* {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
* {@link #LAYER_TYPE_HARDWARE}.</p>
*
* <p>A layer is associated with an optional {@link android.graphics.Paint}
* instance that controls how the layer is composed on screen. The following
* properties of the paint are taken into account when composing the layer:</p>
* <ul>
* <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li>
* <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li>
* <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li>
* </ul>
*
* <p>If this view has an alpha value set to < 1.0 by calling
* {@link #setAlpha(float)}, the alpha value of the layer's paint is superseded
* by this view's alpha value.</p>
*
* <p>Refer to the documentation of {@link #LAYER_TYPE_NONE},
* {@link #LAYER_TYPE_SOFTWARE} and {@link #LAYER_TYPE_HARDWARE}
* for more information on when and how to use layers.</p>
*
* @param layerType The type of layer to use with this view, must be one of
* {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
* {@link #LAYER_TYPE_HARDWARE}
* @param paint The paint used to compose the layer. This argument is optional
* and can be null. It is ignored when the layer type is
* {@link #LAYER_TYPE_NONE}
*
* @see #getLayerType()
* @see #LAYER_TYPE_NONE
* @see #LAYER_TYPE_SOFTWARE
* @see #LAYER_TYPE_HARDWARE
* @see #setAlpha(float)
*
* @attr ref android.R.styleable#View_layerType
*/
public void setLayerType(int layerType, @Nullable Paint paint) {
if (layerType < LAYER_TYPE_NONE || layerType > LAYER_TYPE_HARDWARE) {
throw new IllegalArgumentException("Layer type can only be one of: LAYER_TYPE_NONE, "
+ "LAYER_TYPE_SOFTWARE or LAYER_TYPE_HARDWARE");
}
boolean typeChanged = mRenderNode.setLayerType(layerType);
if (!typeChanged) {
setLayerPaint(paint);
return;
}
if (layerType != LAYER_TYPE_SOFTWARE) {
// Destroy any previous software drawing cache if present
// NOTE: even if previous layer type is HW, we do this to ensure we've cleaned up
// drawing cache created in View#draw when drawing to a SW canvas.
destroyDrawingCache();
}
mLayerType = layerType;
mLayerPaint = mLayerType == LAYER_TYPE_NONE ? null : paint;
mRenderNode.setLayerPaint(mLayerPaint);
// draw() behaves differently if we are on a layer, so we need to
// invalidate() here
invalidateParentCaches();
invalidate(true);
}
Window開啟硬體加速:
window.setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED)
引數解釋如下:
/**
* <p>Indicates whether this window should be hardware accelerated.
* Requesting hardware acceleration does not guarantee it will happen.</p>
*
* <p>This flag can be controlled programmatically <em>only</em> to enable
* hardware acceleration. To enable hardware acceleration for a given
* window programmatically, do the following:</p>
*
* <pre>
* Window w = activity.getWindow(); // in Activity's onCreate() for instance
* w.setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
* WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
* </pre>
*
* <p>It is important to remember that this flag <strong>must</strong>
* be set before setting the content view of your activity or dialog.</p>
*
* <p>This flag cannot be used to disable hardware acceleration after it
* was enabled in your manifest using
* {@link android.R.attr#hardwareAccelerated}. If you need to selectively
* and programmatically disable hardware acceleration (for automated testing
* for instance), make sure it is turned off in your manifest and enable it
* on your activity or dialog when you need it instead, using the method
* described above.</p>
*
* <p>This flag is automatically set by the system if the
* {@link android.R.attr#hardwareAccelerated android:hardwareAccelerated}
* XML attribute is set to true on an activity or on the application.</p>
*/
public static final int FLAG_HARDWARE_ACCELERATED = 0x01000000;
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/289730.html
標籤:其他
上一篇:Git的使用教程(詳細)
下一篇:Javaweb新手軟體推薦
