descargar - android nougat juego
Nougat de Android: TextureView no admite mostrar un dibujable de fondo (3)
Los siguientes son fragmentos del código fuente de View
for Android Nougat:
/**
* Allow setForeground/setBackground to be called (and ignored) on a textureview,
* without throwing
*/
static boolean sTextureViewIgnoresDrawableSetters = false;
En el constructor de argumento único (llamado de todos los demás):
// Prior to N, TextureView would silently ignore calls to setBackground/setForeground.
// On N+, we throw, but that breaks compatibility with apps that use these methods.
sTextureViewIgnoresDrawableSetters = targetSdkVersion <= M;
En el constructor de View
donde se lanza su excepción:
...
switch (attr) {
case com.android.internal.R.styleable.View_background:
background = a.getDrawable(attr);
break;
...
if (background != null) {
setBackground(background); // <--- this is the problematic line, apparently "background" is not null here
}
La definición real de setBackground
:
/**
* Set the background to a given Drawable, or remove the background. If the
* background has padding, this View''s padding is set to the background''s
* padding. However, when a background is removed, this View''s padding isn''t
* touched. If setting the padding is desired, please use
* {@link #setPadding(int, int, int, int)}.
*
* @param background The Drawable to use as the background, or null to remove the
* background
*/
public void setBackground(Drawable background) {
//noinspection deprecation
setBackgroundDrawable(background);
}
Luego, la anulación de setBackgroundDrawable
en TextureView
:
@Override
public void setBackgroundDrawable(Drawable background) {
if (background != null && !sTextureViewIgnoresDrawableSetters) {
throw new UnsupportedOperationException(
"TextureView doesn''t support displaying a background drawable");
}
}
Entonces, lo que puede juntar de todo esto es: 1) Tiene un SDK N (Nougat) de destino: obvio desde su archivo de compilación; 2) El constructor desde View
determina un fondo no nulo (no puedo explicar esta parte en este momento).
Eso es todo lo que se necesita para que esto sea un problema real. No veo que hayas logrado definir un dibujable en tu xml, por lo que anular setBackground
o setBackgroundDrawable
parece ser la posibilidad más sensata de resolver el problema para mí. Puede haber otra solución alternativa (o tal vez "uso sugerido" sería una mejor terminología) por lo que puede administrar forzar la variable de background
en el constructor para que permanezca nula.
He estado usando un TextureView en mi aplicación de Android, y estaba funcionando bien. Hace poco probé mi código en un dispositivo Android con Android API 25 (7.1.2). El mismo código ahora no funciona y java.lang.UnsupportedOperationException: TextureView doesn''t support displaying a background drawable
el error, java.lang.UnsupportedOperationException: TextureView doesn''t support displaying a background drawable
.
Sé que void setBackgroundDrawable (Drawable background)
ha estado en desuso durante mucho tiempo , y ahora debe haber sido eliminado. Pero ni siquiera lo estoy poniendo por mi cuenta.
Estoy usando el último buildTools y SDK. Entonces, me pregunto por qué no se ha actualizado la implementación interna de textureView.
Aquí está el rastro de pila relevante:
java.lang.UnsupportedOperationException: TextureView doesn''t support displaying a background drawable
at android.view.TextureView.setBackgroundDrawable(TextureView.java:315)
at android.view.View.setBackground(View.java:18124)
at android.view.View.<init>(View.java:4573)
at android.view.View.<init>(View.java:4082)
at android.view.TextureView.<init>(TextureView.java:159)
at com.abdulwasaetariq.xyz.ui.customView.AutoFitTextureView.<init>(AutoFitTextureView.java:24)
at com.abdulwasaetariq.xyz.ui.customView.AutoFitTextureView.<init>(AutoFitTextureView.java:20)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
[...]
at java.lang.Thread.run(Thread.java:745)
Aquí es cómo uso mi TextureView personalizado (todavía no personalizado):
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context="com.abdulwasaetariq.xyz.ui.activity.MainActivity">
<com.abdulwasaetariq.xyz.ui.customView.AutoFitTextureView
android:id="@+id/texture"
android:layout_width="1080px"
android:layout_height="1080px"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true" />
</RelativeLayout>
Aquí está mi AutoFitTextureView.java relevante: enter code here
public class AutoFitTextureView extends TextureView {
private int mRatioWidth = 0;
private int mRatioHeight = 0;
public AutoFitTextureView(Context context) {
this(context, null);
}
public AutoFitTextureView(Context context, AttributeSet attrs) {
this(context, attrs, 0); //(LINE#20)
}
public AutoFitTextureView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle); //(LINE#24)
}
public void setAspectRatio(int width, int height) {
if (width < 0 || height < 0) {
throw new IllegalArgumentException("Size cannot be negative.");
}
mRatioWidth = width;
mRatioHeight = height;
requestLayout();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
if (0 == mRatioWidth || 0 == mRatioHeight) {
setMeasuredDimension(width, height);
} else {
if (width < height * mRatioWidth / mRatioHeight) {
setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);
} else {
setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);
}
}
}}
Entonces, como puede ver, las excepciones se producen en los métodos super()
, lo que significa que mi TextureView personalizado no es responsable de esta excepción. Es una llamada interna.
Aquí está mi configuración de gradle:
apply plugin: ''com.android.application''
android {
compileSdkVersion 25
buildToolsVersion ''25.0.2''
defaultConfig {
applicationId "com.abdulwasaetariq.xyz"
minSdkVersion 21
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile(''proguard-android.txt''), ''proguard-rules.pro''
}
}
}
dependencies {
compile fileTree(dir: ''libs'', include: [''*.jar''])
testCompile ''junit:junit:4.12''
androidTestCompile(''com.android.support.test.espresso:espresso-core:2.2.2'', {
exclude group: ''com.android.support'', module: ''support-annotations''
})
compile ''com.android.support.constraint:constraint-layout:1.0.0-alpha8''
compile ''com.github.hotchemi:permissionsdispatcher:2.3.2''
annotationProcessor ''com.github.hotchemi:permissionsdispatcher-processor:2.3.2''
}
¿Alguna idea de por qué esto puede estar pasando? ¿Alguna nota de lanzamiento de la API de Android 25, donde se habla de este cambio?
Si observa el origen de la vista de textura para API 24, verá lo siguiente:
/**
* Subclasses of TextureView cannot do their own rendering
* with the {@link Canvas} object.
*
* @param canvas The Canvas to which the View is rendered.
*/
@Override
public final void draw(Canvas canvas) {
// NOTE: Maintain this carefully (see View#draw)
mPrivateFlags = (mPrivateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN;
/* Simplify drawing to guarantee the layer is the only thing drawn - so e.g. no background,
scrolling, or fading edges. This guarantees all drawing is in the layer, so drawing
properties (alpha, layer paint) affect all of the content of a TextureView. */
if (canvas.isHardwareAccelerated()) {
DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas;
HardwareLayer layer = getHardwareLayer();
if (layer != null) {
applyUpdate();
applyTransformMatrix();
mLayer.setLayerPaint(mLayerPaint); // ensure layer paint is up to date
displayListCanvas.drawHardwareLayer(layer);
}
}
}
El comentario en el cuerpo de draw()
da la razón para el cambio que ha visto. Esta es la única documentación que he encontrado. Compare esto con TextureView
de API 23:
/**
* Subclasses of TextureView cannot do their own rendering
* with the {@link Canvas} object.
*
* @param canvas The Canvas to which the View is rendered.
*/
@Override
public final void draw(Canvas canvas) {
// NOTE: Maintain this carefully (see View.java)
mPrivateFlags = (mPrivateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN;
applyUpdate();
applyTransformMatrix();
}
La API 24 también introdujo anulaciones para los métodos "establecer fondo" que no están anulados en la API 23. La configuración de un fondo ahora está claramente desaconsejada y simplemente no está permitida. Si está viendo la excepción de operación no admitida y no está configurando un fondo de manera explícita, es probable que se esté entrometiendo en sus estilos. Intente configurar android:background="@null"
en su XML para forzar que el fondo sea nulo para evitar el error. También puede agregar el siguiente código a su vista personalizada para conservar la funcionalidad en aquellas versiones que admiten la configuración de un fondo:
@Override
public void setBackgroundDrawable(Drawable background) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N && background != null) {
setBackgroundDrawable(background);
}
}
No está claro cómo reemplazar la funcionalidad que ha perdido para API 24+ o si incluso la necesita, pero solo desea tener la herramienta de fondo en su arsenal.
Solo por mencionar, no solo TextureView: encontré, que GridLayout tampoco admite la visualización de un fondo dibujable desde la API 24.
Lo intenté:
A) gridLayout.setBackgroundResource(R.drawable.board_960x960px_border_in_bg);
B) Resources res = getResources(); Drawable drawable = res.getDrawable(R.drawable.board_960x960px_border_in_bg); gridLayout.setBackground(drawable);
Resources res = getResources(); Drawable drawable = res.getDrawable(R.drawable.board_960x960px_border_in_bg); gridLayout.setBackground(drawable);
Ninguno de los anteriores parece estar funcionando por encima de la API 23.
Sin embargo, el fondo de TableLayout no desaparecerá incluso en API 24+, así que reescribí todo mi código relevante de GridLayout a TableLayout y ahora está bien.