Desfoque da janela do Android12 (1) Realize o efeito de desfoque gaussiano na atividade e na caixa de diálogo

prefácio

No Android 12, existem algumas APIs públicas para implementar efeitos de desfoque de janela, como desfoque de fundo e desfoque da tela traseira. Window Blur ou Cross-Window Blur é usado para desfocar a tela atrás de uma determinada janela.
Existem dois métodos de desfoque de janela que podem ser usados ​​para obter diferentes efeitos visuais:

  • Desfoque de fundo: Pode ser usado para criar janelas com fundo desfocado, criando um efeito de vidro fosco, onde a área desfocada é a janela.

  • Desfocar atrás: Pode ser usado para desfocar (diálogo) toda a tela atrás da janela, criando um efeito de profundidade de campo, onde a área desfocada é a tela inteira.

Esses dois efeitos podem ser usados ​​sozinhos ou combinados, conforme a imagem abaixo:

Realização da função de desfoque da janela
As três renderizações acima são renderizações oficiais fornecidas pelo Google:

(a) Desfoque de fundo somente (Desfoque atrás)
(b) Desfoque somente atrás da tela (Desfoque atrás)
(c) Desfoque de fundo e desfoque atrás da tela (Desfoque de fundo) + (Desfoque atrás)

A função de desfoque de janela fornecida pelo Android 12 pode ser usada em janelas, o que significa que essa função também pode funcionar quando há outros aplicativos atrás da janela, mas o desfoque entre janelas consome muitos recursos. Esse efeito é diferente do efeito de renderização de desfoque, que desfoca o conteúdo dentro da mesma janela. O desfoque de janela é útil para caixas de diálogo, barras de ação inferiores e outras janelas flutuantes.

Anexe a descrição oficial

1. Desfoque o fundo da janela

Para desfocar o fundo da janela, existem principalmente as seguintes operações:

1. Chame Window#setBackgroundBlurRadius(int) para definir o raio do desfoque de fundo. Como alternativa, defina R.attr.windowBackgroundBlurRadius no tema da janela.

2. Defina R.attr.windowIsTranslucent como true para tornar a janela translúcida. O desfoque é desenhado sob a superfície da janela, portanto, a janela deve ser semitransparente para mostrar o efeito de desfoque.

3. (Opcional) Chame Window#setBackgroundDrawableResource(int) para adicionar um desenhável de fundo de janela retangular com uma cor translúcida. Como alternativa, defina R.attr.windowBackground no tema da janela.

4. Para uma janela com cantos arredondados, os cantos arredondados da área desfocada podem ser determinados definindo o ShapeDrawable com cantos arredondados como o objeto desenhável de plano de fundo da janela.

5. O estado de ativação e desativação da ofuscação.

2. Desfoque a tela atrás da janela

Se você precisar desfocar a tela atrás da janela, existem principalmente as seguintes operações:

1. Adicione FLAG_BLUR_BEHIND aos sinalizadores de janela para ativar "desfoque atrás da tela". Como alternativa, defina R.attr.windowBlurBehindEnabled no tema da janela.

2. Chame WindowManager.LayoutParams#setBlurBehindRadius para definir o raio de "Blur Behind Screen". Como alternativa, defina R.attr.windowBlurBehindRadius no tema da janela.

3. (Opcional) Escolha uma tonalidade complementar. Janela#setDimAmount(quantidade flutuante)

4. Lide com o estado de ativação e desativação da ofuscação.

3. Renderização

A API para desfocar o plano de fundo da janela e a tela atrás da janela no Android 12 foi brevemente apresentada acima. A seguir está a renderização final de nossa implementação. Usando Dialog e Activity para desfocar apenas o plano de fundo atual, apenas a tela traseira, e o plano de fundo atual ao mesmo tempo E a tela traseira três efeitos de desfoque gaussiano comumente usados.

1. Use o diálogo para obter o efeito de desfoque gaussiano
insira a descrição da imagem aqui
2. Use a atividade para obter o efeito de desfoque gaussiano
insira a descrição da imagem aqui

Em quarto lugar, o código específico

Finalmente, vamos dar uma olhada no código completo do projeto.

1. arquivo de configuração gradle, arquivo de manifesto AndroidManifest.xml e arquivo de estilo style.xml

plugins {
    
    
    id 'com.android.application'
}

android {
    
    
    namespace 'com.example.myapplication'
    compileSdk 32

    defaultConfig {
    
    
        applicationId "com.example.myapplication"
        minSdk 31
        targetSdk 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
    
    
        release {
    
    
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
    
    
        sourceCompatibility JavaVersion.VERSION_11
        targetCompatibility JavaVersion.VERSION_11
    }
}

dependencies {
    
    
    implementation 'androidx.appcompat:appcompat:1.4.1'
    implementation 'com.google.android.material:material:1.5.0'
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name="com.example.blurapplication.MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.example.blurapplication.BlurActivity"
            android:exported="false"
            android:theme="@style/BlurActivityTheme" />
    </application>

</manifest>
<resources>
    <style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
    </style>

    <!--高斯模糊activity-->
    <style name="BlurActivityTheme" parent="Theme.MaterialComponents.Dialog">
        <item name="android:windowIsTranslucent">true</item>
    </style>

    <!--高斯模糊Dialog-->
    <style name="BlurDialogTheme" parent="Theme.MaterialComponents.Dialog">
        <item name="android:windowIsTranslucent">true</item>
    </style>
</resources>

2. Arquivos de layout MainActivity.java e activity_main.xml

public class MainActivity extends AppCompatActivity {
    
    

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.btn_dialog_blur_background).setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                //仅模糊背景
                BlurDialog dialog = new BlurDialog(MainActivity.this, BlurDialog.BLUR_TYPE_BLUR_BACKGROUND);
                dialog.show();
            }
        });
        findViewById(R.id.btn_dialog_blur_behind).setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                //仅模糊后方屏幕
                BlurDialog dialog = new BlurDialog(MainActivity.this, BlurDialog.BLUR_TYPE_BLUR_BEHIND);
                dialog.show();
            }
        });
        findViewById(R.id.btn_dialog_blur_background_and_behind).setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                //同时模糊背景和后方屏幕
                BlurDialog dialog = new BlurDialog(MainActivity.this, BlurDialog.BLUR_TYPE_BLUR_BACKGROUND_AND_BEHIND);
                dialog.show();
            }
        });
        findViewById(R.id.btn_activity_blur_background).setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                //仅模糊背景
                Intent intent = new Intent(MainActivity.this, BlurActivity.class);
                intent.putExtra(BlurActivity.EXTRA_KEY_BLUR_TYPE, BlurActivity.BLUR_TYPE_BLUR_BACKGROUND);
                startActivity(intent);
            }
        });
        findViewById(R.id.btn_activity_blur_behind).setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                //仅模糊后方屏幕
                Intent intent = new Intent(MainActivity.this, BlurActivity.class);
                intent.putExtra(BlurActivity.EXTRA_KEY_BLUR_TYPE, BlurActivity.BLUR_TYPE_BLUR_BEHIND);
                startActivity(intent);
            }
        });
        findViewById(R.id.btn_activity_blur_background_and_behind).setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                //同时模糊背景和后方屏幕
                Intent intent = new Intent(MainActivity.this, BlurActivity.class);
                intent.putExtra(BlurActivity.EXTRA_KEY_BLUR_TYPE, BlurActivity.BLUR_TYPE_BLUR_BACKGROUND_AND_BEHIND);
                startActivity(intent);
            }
        });
    }
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:background="@mipmap/img"
    android:orientation="vertical"
    tools:context="com.example.blurapplication.MainActivity">

    <Button
        android:id="@+id/btn_dialog_blur_background"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="模糊Dialog的背景"
        android:textAllCaps="false"
        android:textSize="24sp" />

    <Button
        android:id="@+id/btn_dialog_blur_behind"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="模糊Dialog后方屏幕"
        android:textAllCaps="false"
        android:textSize="24sp" />

    <Button
        android:id="@+id/btn_dialog_blur_background_and_behind"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="同时模糊Dialog的背景和后方屏幕"
        android:textAllCaps="false"
        android:textSize="24sp" />

    <Button
        android:id="@+id/btn_activity_blur_background"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="模糊Activity的背景"
        android:textAllCaps="false"
        android:textSize="24sp" />

    <Button
        android:id="@+id/btn_activity_blur_behind"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="模糊Activity后方屏幕"
        android:textAllCaps="false"
        android:textSize="24sp" />

    <Button
        android:id="@+id/btn_activity_blur_background_and_behind"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="同时模糊Activity的背景和后方屏幕"
        android:textAllCaps="false"
        android:textSize="24sp" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:background="#FFF"
        android:gravity="center"
        android:text="高斯模糊效果测试"
        android:textSize="46sp" />
</LinearLayout>

3. Arquivos de layout BackgroundBlurDialog.java e dialog_background_blur.xml

public class BlurDialog extends AlertDialog {
    
    

    private Window mWindow;

    //窗口背景高斯模糊程度,数值越高越模糊且越消耗性能
    private final int mBackgroundBlurRadius = 90;
    //窗口周边背景高斯模糊程度
    private final int mBlurBehindRadius = 20;

    //根据窗口高斯模糊功能是否开启来设置窗口周边暗色的程度
    private final float mDimAmountWithBlur = 0f;
    private final float mDimAmountNoBlur = 0.4f;

    // 根据窗口高斯模糊功能是否开启来为窗口设置不同的不透明度
    private final int mWindowBackgroundAlphaWithBlur = 170;
    private final int mWindowBackgroundAlphaNoBlur = 255;

    //使用一个矩形drawable文件作为窗口背景,这个矩形的轮廓和圆角确定了窗口高斯模糊的区域
    private Drawable mWindowBackgroundDrawable;

    /**
     * 高斯模糊的类型
     * 0代表只模糊背景
     * 1代表之模糊后方屏幕
     * 2代表同时模糊背景和后方屏幕
     */
    private int mBlurType = 0;
    public static final int BLUR_TYPE_BLUR_BACKGROUND = 0;
    public static final int BLUR_TYPE_BLUR_BEHIND = 1;
    public static final int BLUR_TYPE_BLUR_BACKGROUND_AND_BEHIND = 2;

    public BlurDialog(@NonNull Context context, int blurType) {
    
    
        super(context, R.style.BlurDialogTheme);
        mBlurType = blurType;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dialog_blur);
        initBlur();
    }

    private void initBlur() {
    
    
        mWindow = getWindow();
        //替换window默认的背景
        mWindowBackgroundDrawable = getContext().getDrawable(R.drawable.window_background);
        getWindow().setBackgroundDrawable(mWindowBackgroundDrawable);

        //注册一个监听者去监听窗口UI视图是否可见以便调整窗口高斯模糊功能是否开启
        setupWindowBlurListener();

        //允许背景模糊,也可以通过样式属性R.attr#windowBlurBehindEnabled来实现
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);

        // 允许背景变暗,也可以通过样式属性R.attr#backgroundDimEnabled来实现
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
    }

    /**
     * 设置一个窗口视图状态监听者,监听窗口视图是否可见以便是否更新窗口模糊的状态
     */
    private void setupWindowBlurListener() {
    
    
        Consumer<Boolean> windowBlurEnabledListener = this::updateWindowForBlurs;
        getWindow().getDecorView().addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
    
    
            @Override
            public void onViewAttachedToWindow(View v) {
    
    
                mWindow.getWindowManager().addCrossWindowBlurEnabledListener(windowBlurEnabledListener);
            }

            @Override
            public void onViewDetachedFromWindow(View v) {
    
    
                mWindow.getWindowManager().removeCrossWindowBlurEnabledListener(windowBlurEnabledListener);
            }
        });
    }

    /**
     * 更新窗口的高斯模糊效果
     *
     * @param blursEnabled
     */
    private void updateWindowForBlurs(boolean blursEnabled) {
    
    
        if (mBlurType == BLUR_TYPE_BLUR_BACKGROUND) {
    
    
            //仅模糊背景
            mWindowBackgroundDrawable.setAlpha(blursEnabled ? mWindowBackgroundAlphaWithBlur : mWindowBackgroundAlphaNoBlur);//调整背景的透明度
            getWindow().setDimAmount(blursEnabled ? mDimAmountWithBlur : mDimAmountNoBlur);//调整背景周边昏暗的程度
            getWindow().setBackgroundBlurRadius(mBackgroundBlurRadius);//设置背景模糊程度
            return;
        }
        if (mBlurType == BLUR_TYPE_BLUR_BEHIND) {
    
    
            //仅模糊后方屏幕
            getWindow().setDimAmount(blursEnabled ? mDimAmountWithBlur : mDimAmountNoBlur);//调整背景周边昏暗的程度
            getWindow().getAttributes().setBlurBehindRadius(mBlurBehindRadius);//设置背景周边模糊程度
            getWindow().setAttributes(getWindow().getAttributes());//让上面的高斯模糊效果生效
            return;
        }
        //同时模糊背景和后方屏幕
        mWindowBackgroundDrawable.setAlpha(blursEnabled ? mWindowBackgroundAlphaWithBlur : mWindowBackgroundAlphaNoBlur);//调整背景的透明度
        getWindow().setBackgroundBlurRadius(mBackgroundBlurRadius);//设置背景模糊程度
        getWindow().setDimAmount(blursEnabled ? mDimAmountWithBlur : mDimAmountNoBlur);//调整背景周边昏暗的程度
        getWindow().getAttributes().setBlurBehindRadius(mBlurBehindRadius);//设置背景周边模糊程度
        getWindow().setAttributes(getWindow().getAttributes());//让上面的高斯模糊效果生效
    }
}
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="20dp" />
    <solid android:color="#AAAAAA" />
</shape>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:gravity="center"
        android:text="你好,我是高斯模糊Dialog"
        android:textAllCaps="false"
        android:textSize="30sp" />

</LinearLayout>

4. Arquivos de layout BackgroundBlurActivity.java e activity_background_blur.xml

public class BlurActivity extends Activity {
    
    

    public static final String EXTRA_KEY_BLUR_TYPE = "blur_type";
    public static final int BLUR_TYPE_BLUR_BACKGROUND = 0;
    public static final int BLUR_TYPE_BLUR_BEHIND = 1;
    public static final int BLUR_TYPE_BLUR_BACKGROUND_AND_BEHIND = 2;

    //窗口背景高斯模糊程度,数值越高越模糊且越消耗性能
    private final int mBackgroundBlurRadius = 90;
    //窗口周边背景高斯模糊程度
    private final int mBlurBehindRadius = 20;

    //根据窗口高斯模糊功能是否开启来设置窗口周边暗色的程度
    private final float mDimAmountWithBlur = 0f;
    private final float mDimAmountNoBlur = 0.4f;

    // 根据窗口高斯模糊功能是否开启来为窗口设置不同的不透明度
    private final int mWindowBackgroundAlphaWithBlur = 170;
    private final int mWindowBackgroundAlphaNoBlur = 255;

    //使用一个矩形drawable文件作为窗口背景,这个矩形的轮廓和圆角确定了窗口高斯模糊的区域
    private Drawable mWindowBackgroundDrawable;

    /**
     * 高斯模糊的类型
     * 0代表只模糊背景
     * 1代表之模糊后方屏幕
     * 2代表同时模糊背景和后方屏幕
     */
    private int mBlurType = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        mBlurType = getIntent().getIntExtra(EXTRA_KEY_BLUR_TYPE, BLUR_TYPE_BLUR_BACKGROUND);
        setContentView(R.layout.activity_blur);
        initBlur();
    }

    private void initBlur() {
    
    
        //替换window默认的背景
        mWindowBackgroundDrawable = getDrawable(R.drawable.window_background);
        getWindow().setBackgroundDrawable(mWindowBackgroundDrawable);

        //注册一个监听者去监听窗口UI视图是否可见以便调整窗口高斯模糊功能是否开启
        setupWindowBlurListener();

        //允许背景模糊,也可以通过样式属性R.attr#windowBlurBehindEnabled来实现
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);

        // 允许背景变暗,也可以通过样式属性R.attr#backgroundDimEnabled来实现
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
        findViewById(R.id.ll_content).setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                finish();
            }
        });
    }

    /**
     * 设置一个窗口视图状态监听者,监听窗口视图是否可见以便是否更新窗口模糊的状态
     */
    private void setupWindowBlurListener() {
    
    
        Consumer<Boolean> windowBlurEnabledListener = this::updateWindowForBlurs;
        getWindow().getDecorView().addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
    
    
            @Override
            public void onViewAttachedToWindow(View v) {
    
    
                getWindowManager().addCrossWindowBlurEnabledListener(windowBlurEnabledListener);
            }

            @Override
            public void onViewDetachedFromWindow(View v) {
    
    
                getWindowManager().removeCrossWindowBlurEnabledListener(windowBlurEnabledListener);
            }
        });
    }

    /**
     * 更新窗口的高斯模糊效果
     *
     * @param blursEnabled
     */
    private void updateWindowForBlurs(boolean blursEnabled) {
    
    
        if (mBlurType == BLUR_TYPE_BLUR_BACKGROUND) {
    
    
            //仅模糊背景
            mWindowBackgroundDrawable.setAlpha(blursEnabled ? mWindowBackgroundAlphaWithBlur : mWindowBackgroundAlphaNoBlur);//调整背景的透明度
            getWindow().setDimAmount(blursEnabled ? mDimAmountWithBlur : mDimAmountNoBlur);//调整背景周边昏暗的程度
            getWindow().setBackgroundBlurRadius(mBackgroundBlurRadius);//设置背景模糊程度
            return;
        }
        if (mBlurType == BLUR_TYPE_BLUR_BEHIND) {
    
    
            //仅模糊后方屏幕
            getWindow().setDimAmount(blursEnabled ? mDimAmountWithBlur : mDimAmountNoBlur);//调整背景周边昏暗的程度
            getWindow().getAttributes().setBlurBehindRadius(mBlurBehindRadius);//设置背景周边模糊程度
            getWindow().setAttributes(getWindow().getAttributes());//让上面的高斯模糊效果生效
            return;
        }
        //同时模糊背景和后方屏幕
        mWindowBackgroundDrawable.setAlpha(blursEnabled ? mWindowBackgroundAlphaWithBlur : mWindowBackgroundAlphaNoBlur);//调整背景的透明度
        getWindow().setBackgroundBlurRadius(mBackgroundBlurRadius);//设置背景模糊程度
        getWindow().setDimAmount(blursEnabled ? mDimAmountWithBlur : mDimAmountNoBlur);//调整背景周边昏暗的程度
        getWindow().getAttributes().setBlurBehindRadius(mBlurBehindRadius);//设置背景周边模糊程度
        getWindow().setAttributes(getWindow().getAttributes());//让上面的高斯模糊效果生效
    }
}

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:id="@+id/ll_content"
    android:orientation="vertical">

    <TextView
        android:layout_width="300dp"
        android:layout_height="400dp"
        android:gravity="center"
        android:text="你好,我是高斯模糊Activity"
        android:textAllCaps="false"
        android:textSize="30sp" />

</LinearLayout>

5. Confirme se o dispositivo suporta desfoque gaussiano

Se a função de desfoque gaussiano não estiver habilitada no dispositivo, o código acima não pode obter o efeito de desfoque gaussiano; para verificar se o dispositivo Android12+ suporta desfoque de janela e se o desfoque de janela está habilitado no momento, existem dois métodos:

1. Use a linha de comando adb:

adb shell wm disable-blur 

1) O dispositivo oferece suporte e a chave da função de desfoque gaussiano está ativada

Blur supported on device: true
Blur enabled: true

2) O dispositivo não suporta

Blur supported on device: false
Blur enabled: false

2. Insira as configurações

1) Configurações -> Sistema -> Opções do desenvolvedor -> Renderização acelerada por hardware -> Permitir desfoque no nível da janela

2) Se você não encontrar a opção em Configurações, seu dispositivo não suporta desfoque de janela.

6. Ative a função Desfoque gaussiano para o dispositivo

1. Ative a função Gaussian Blur modificando o arquivo de compilação do sistema

Como a função de desfoque gaussiano consome muitos recursos da GPU, o código-fonte do sistema Android12 desativa a função de desfoque gaussiano por padrão durante a compilação.
insira a descrição da imagem aqui

device/qcom/msmnile_gvmq/msmnile_gvmq.mk

# enable surface flinger window blurs
PRODUCT_PROPERTY_OVERRIDES += \
       ro.surface_flinger.supports_background_blur=1

2. Depois de fazer root no sistema, modifique diretamente o arquivo de código-fonte do sistema

fornecedor/build.prop

ro.surface_flinger.supports_background_blur=1

Acho que você gosta

Origin blog.csdn.net/abc6368765/article/details/127657069
Recomendado
Clasificación