Как программно оформить тему, чтобы она была похожа на диалог?
Вопрос
Как это сделать программно (не касаясь 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);