Как программно оформить тему, чтобы она была похожа на диалог?

Вопрос

Как это сделать программно (не касаясь AndroidManifext.xml) установить тему Activity чтобы это выглядело как диалог?

Примечание: я в порядке с изменением AndroidManifext.xml до тех пор, пока его не нужно изменять, чтобы переключаться между тем, чтобы он выглядел как обычная деятельность или диалог.

Что я пробовал до сих пор

Я попробовал следующее согласно этому ответу stackru:

public class DialogActivity extends Activity
{

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        setTheme(android.R.style.Theme_DeviceDefault_Dialog);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dialog);
        Log.d(TAG,"Build.VERSION.SDK_INT: "+Build.VERSION.SDK_INT); // 23
    }
}

Но это заканчивается тем, что затемняет все на заднем плане.

Я также видел этот ответ stackru и попытался:

public class DialogActivity extends Activity
{

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        setTheme(android.R.style.Theme_DeviceDefault_Dialog);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dialog);
        getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
    }
}

но в итоге все становится черным.

Что? Спасибо.

4 ответа

Решение

Фон

Activity за Acivity рисуется, если тема переднего плана в соответствии с ее AndroidManifest.xml это диалог; в противном случае Android OS не будет рисовать Activity за ним (возможно, чтобы сохранить память, так как обычно ее не видно).

Чтобы использовать это, мы устанавливаем тему нашего Acitvity к диалогу в манифесте, заставляя ОС Android нарисовать Activity за этим, но позже, программно установить наш ActivityТема для всего, что нам нравится во время выполнения.

Пример на github

Я сделал пример и поместил его на github.

Руководство

Шаг 1: создайте две собственные темы для вашего приложения в styles.xml, Один для обычной деятельности, а другой для диалоговой деятельности. Важно, чтобы пользовательская тема диалога наследовалась от базовой темы, которая также является диалогом. В моем случае родительская тема Base.Theme.AppCompat.Light.Dialog.FixedSize). Вот мой styles.xml:

<resources>

    <!-- custom normal activity theme -->    
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    </style>

    <!-- custom dialog activity theme -->
    <style name="AppTheme.Dialog" parent="Base.Theme.AppCompat.Light.Dialog.FixedSize">
        <!-- removing the dialog's action bar -->
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

</resources>

Шаг 2: в AndroidManifest.xmlзадайте тему Activity под вопросом любая тема диалога. Это заставляет Android OS думать, что Activity это диалог, поэтому он будет рисовать Activity за ним, а не зачеркнуть. В моем случае я использовал Theme.AppCompat.Dialog, Ниже мой AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.eric.questiondialog_artifact">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name">
        <activity
            android:name=".DialogActivity"
            android:label="@string/app_name"
            android:theme="@style/Theme.AppCompat.Dialog"> <-- IMPORTANT!!! -->
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>

Шаг 3: в реальном упражнении задайте тему программно либо как тему для обычных занятий, либо как тему для диалогов. мой DialogActivity.java ниже:

package com.example.eric.questiondialog_artifact;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;

public class DialogActivity extends AppCompatActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        setTheme(R.style.AppTheme_Dialog); // can either use R.style.AppTheme_Dialog or R.style.AppTheme as deined in styles.xml
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dialog);
    }
}

Если то, что вы ищете, это просто тема с прозрачным фоном для вашей деятельности, просто используйте это:

<style name="Theme.Transparent" parent="android:Theme">
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowIsFloating">true</item>
    <item name="android:backgroundDimEnabled">false</item>
</style>

применить этот стиль к вашей деятельности в вашем файле AndroidManifest, и это все

Я опаздываю, но для будущих пользователей вам нужно вызвать приведенный ниже код после setTheme()Вызов этого позволяет снова увидеть действие, стоящее за этим. Как только все такие действия будут перерисованы

      // setTheme()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            try {
            Method getActivityOptions = Activity.class.getDeclaredMethod("getActivityOptions");
            getActivityOptions.setAccessible(true);
            Object options = getActivityOptions.invoke(activity);

            Class<?>[] classes = Activity.class.getDeclaredClasses();
            Class<?> translucentConversionListenerClazz = null;
            for (Class clazz : classes) {
                if (clazz.getSimpleName().contains("TranslucentConversionListener")) {
                    translucentConversionListenerClazz = clazz;
                }
            }
            Method convertToTranslucent = Activity.class.getDeclaredMethod("convertToTranslucent",
                    translucentConversionListenerClazz, ActivityOptions.class);
            convertToTranslucent.setAccessible(true);
            convertToTranslucent.invoke(activity, null, options);
        } catch (Throwable t) {
        }
        } else {
            try {
            Class<?>[] classes = Activity.class.getDeclaredClasses();
            Class<?> translucentConversionListenerClazz = null;
            for (Class clazz : classes) {
                if (clazz.getSimpleName().contains("TranslucentConversionListener")) {
                    translucentConversionListenerClazz = clazz;
                }
            }
            Method method = Activity.class.getDeclaredMethod("convertToTranslucent",
                    translucentConversionListenerClazz);
            method.setAccessible(true);
            method.invoke(activity, new Object[] {
                null
            });
        } catch (Throwable t) {
        }
        }

Попробуйте этот код, прежде чем dailog.setMessage(...);

Dialog id  = new AlertDialog.Builder(this,AlertDialog.THEME_DEVICE_DEFAULT_DARK);

Dialog ID = new AlertDialog.Builder(this,AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);

//Default theme 

Попробуйте это для старой темы Dialog ID = new AlertDialog.Builder(this,AlertDialog.THEME_TRADITIONAL);

Попробуйте это для темы KITKAT

Dialog ID = new AlertDialog.Builder(this,AlertDialog.THEME_DEVICE_DEFAULT_DARK); //Dark


Dialog ID = new AlertDialog.Builder(this,AlertDialog.THEME_HOLO_LIGHT);

Попробуйте эти коды для Прагматично

Exmaple

    dialog = new AlertDialog.Builder(this);
            dialog = new AlertDialog.Builder(this,AlertDialog.THEME_DEVICE_DEFAULT_DARK);
            dialog.setTitle("HAI");
            dialog.setMessage("look");
            dialog.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
Toast toast= Toast.makeText(getApplicationContext(), "This is exmaple theme", Toast.LENGTH_LONG);
Другие вопросы по тегам