如果我启动一个Activity而不是显示对话框,我可以让它工作,但这会占用整个屏幕。是否有一种标准方法可以使用DialogFragment来实现这一点?
借鉴Google论坛帖子的想法,我成功地为活动设置了样式。建议您将高度和宽度修改为您选择的“动态”大小,然后设置任何ActionBar按钮。
<style name="PopupTheme" parent="android:Theme.Holo.Light.Dialog">
<item name="android:windowIsFloating">false</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowSoftInputMode">stateAlwaysHidden</item>
<item name="android:windowActionModeOverlay">true</item>
<item name="android:windowIsTranslucent">true</item>
</style>
--
public static void showAsPopup(Activity activity) {
//To show activity as dialog and dim the background, you need to declare android:theme="@style/PopupTheme" on for the chosen activity on the manifest
activity.requestWindowFeature(Window.FEATURE_ACTION_BAR);
activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND,
WindowManager.LayoutParams.FLAG_DIM_BEHIND);
LayoutParams params = activity.getWindow().getAttributes();
params.height = 850; //fixed height
params.width = 850; //fixed width
params.alpha = 1.0f;
params.dimAmount = 0.5f;
activity.getWindow().setAttributes((android.view.WindowManager.LayoutParams) params);
setContentView(R.layout.activity_main);
}
super.onCreate(...)
调用之后立即让onCreate(...)
方法调用showAsPopup()
(您可以省略参数并使用this
,因为它是同一Activity类的方法)。 - Brian Whiteactivity.setContentView(R.layout.activity_main);
。 - medo<style name="PopupTheme" parent="Theme.Sherlock">
<item name="android:windowFrame">@null</item>
<item name="android:windowIsFloating">false</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
<item name="android:windowSoftInputMode">stateAlwaysHidden</item>
<item name="android:windowActionModeOverlay">true</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowCloseOnTouchOutside">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="windowContentOverlay">@null</item>
</style>
根据Luke Sleeman的回答,初始化一个带有PopupTheme的SherlockActivity。
private void showAsPopup(SherlockActivity activity) {
//To show activity as dialog and dim the background, you need to declare android:theme="@style/PopupTheme" on for the chosen activity on the manifest
//activity.requestWindowFeature(Window.FEATURE_ACTION_BAR); // NO NEED to call this line.
activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND,
WindowManager.LayoutParams.FLAG_DIM_BEHIND);
LayoutParams params = activity.getWindow().getAttributes();
params.alpha = 1.0f;
params.dimAmount = 0.5f;
activity.getWindow().setAttributes((android.view.WindowManager.LayoutParams) params);
// This sets the window size, while working around the IllegalStateException thrown by ActionBarView
activity.getWindow().setLayout(width,height);
}
结果:
在实施StrikeForceZero和Luke Sleeman建议的解决方案时遇到了些问题,所以我想分享一下我的经验。我相信只是有些地方我漏掉了,所以希望能得到反馈。
我所做的是:
使用提供的PopupTheme创建样式,直接复制/粘贴:
<style name="PopupTheme" parent="android:Theme.Holo.Light.Dialog">
<item name="android:windowIsFloating">false</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowSoftInputMode">stateAlwaysHidden</item>
<item name="android:windowActionModeOverlay">true</item>
<item name="android:windowIsTranslucent">true</item>
</style>
将showAsPopup()方法作为片段中的一个方法添加,该方法将打开假对话框片段,直接复制/粘贴:
在片段中添加showAsPopup()方法作为一种方法,该方法将打开一个虚拟对话框片段,直接复制/粘贴:
private void showAsPopup(Activity activity) {
//To show activity as dialog and dim the background, you need to declare android:theme="@style/PopupTheme" on for the chosen activity on the manifest
activity.requestWindowFeature(Window.FEATURE_ACTION_BAR);
activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND,
WindowManager.LayoutParams.FLAG_DIM_BEHIND);
LayoutParams params = activity.getWindow().getAttributes();
params.alpha = 1.0f;
params.dimAmount = 0f;
activity.getWindow().setAttributes((android.view.WindowManager.LayoutParams) params);
// This sets the window size, while working around the IllegalStateException thrown by ActionBarView
activity.getWindow().setLayout(850,850);
}
使用简单的new()调用创建一个新活动的实例,然后将其传递给showAsPopup()方法: DialogTestActivity test = new DialogTestActivity();
showAsPopup(test);
为了测试的目的(我只是想确认我能否打开一个以操作栏呈现为对话框的活动),我使用了一个非常简单的测试,直接从按钮视图api演示中窃取(有关布局文件,请参见api演示中的buttons_1.xml)。public class DialogTestActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.buttons_test);
}
}
很遗憾,每次我尝试这样做时,都会在第一次调用activity.requestWindowFeature(Window.FEATURE_ACTION_BAR)时出现未指定的空指针异常。
(说明:该段内容讲述在进行某项操作时,出现了一个空指针异常错误)
04-29 16:39:05.361: W/System.err(15134): java.lang.NullPointerException
04-29 16:39:05.361: W/System.err(15134): at android.app.Activity.requestWindowFeature(Activity.java:3244)
04-29 16:39:05.371: W/System.err(15134): at packagenameremovedforlegalreasons.classname.showAsPopup(classname.java:602)
04-29 16:39:05.371: W/System.err(15134): at packagenameremovedforlegalreasons.classname.onMapLongClick(classname.java:595)
04-29 16:39:05.371: W/System.err(15134): at com.google.android.gms.maps.GoogleMap$5.onMapLongClick(Unknown Source)
04-29 16:39:05.371: W/System.err(15134): at com.google.android.gms.internal.k$a.onTransact(Unknown Source)
04-29 16:39:05.381: W/System.err(15134): at android.os.Binder.transact(Binder.java:310)
04-29 16:39:05.381: W/System.err(15134): at com.google.android.gms.maps.internal.IOnMapLongClickListener$Stub$Proxy.onMapLongClick(IOnMapLongClickListener.java:93)
04-29 16:39:05.381: W/System.err(15134): at maps.i.s.a(Unknown Source)
04-29 16:39:05.381: W/System.err(15134): at maps.y.v.d(Unknown Source)
04-29 16:39:05.381: W/System.err(15134): at maps.y.bf.onLongPress(Unknown Source)
04-29 16:39:05.381: W/System.err(15134): at maps.d.v.onLongPress(Unknown Source)
04-29 16:39:05.381: W/System.err(15134): at maps.d.h.c(Unknown Source)
04-29 16:39:05.381: W/System.err(15134): at maps.d.h.c(Unknown Source)
04-29 16:39:05.381: W/System.err(15134): at maps.d.j.handleMessage(Unknown Source)
04-29 16:39:05.391: W/System.err(15134): at android.os.Handler.dispatchMessage(Handler.java:99)
04-29 16:39:05.391: W/System.err(15134): at android.os.Looper.loop(Looper.java:137)
04-29 16:39:05.391: W/System.err(15134): at android.app.ActivityThread.main(ActivityThread.java:5041)
04-29 16:39:05.391: W/System.err(15134): at java.lang.reflect.Method.invokeNative(Native Method)
04-29 16:39:05.391: W/System.err(15134): at java.lang.reflect.Method.invoke(Method.java:511)
04-29 16:39:05.391: W/System.err(15134): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
04-29 16:39:05.391: W/System.err(15134): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
04-29 16:39:05.391: W/System.err(15134): at dalvik.system.NativeStart.main(Native Method)
从堆栈跟踪中可以看出,预期行为是在GoogleMap实例上长按打开窗口(使用API 2中的MapFragments)。因此,我最初的想法是可能由于尝试从片段中打开而导致问题,因此我将调用传回了拥有的Activity。同样的错误,没有额外的信息。
我目前的最佳猜测是,new()调用并未充分地实例化类/视图,以使调用修改其视图。结果证明这至少在某种程度上是正确的,因为将视图修改代码迁移到活动中并以正常方式打开活动即可解决:
调用活动:
public void openMapDialog()
{
Intent intent = new Intent(this, DialogTestActivity.class);
startActivity(intent);
}
新的类代码:
public class DialogTestActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// From: https://dev59.com/7Wgu5IYBdhLWcg3wTVU6
this.requestWindowFeature(Window.FEATURE_ACTION_BAR);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND, WindowManager.LayoutParams.FLAG_DIM_BEHIND);
LayoutParams params = this.getWindow().getAttributes();
params.alpha = 1.0f;
params.dimAmount = 0f;
this.getWindow().setAttributes((android.view.WindowManager.LayoutParams) params);
// This sets the window size, while working around the IllegalStateException thrown by ActionBarView
this.getWindow().setLayout(600,600);
setContentView(R.layout.buttons_test);
}
}
所以我发这篇文章的目的就是为了澄清,如果你想做上面的建议,就不能只 new() 一个 activity 然后调用 showAsPopup()。也许这是我在 Android 上缺乏经验所表现出来的,但是尽管这似乎有点显而易见,但自然而然地把 showAsPopup() 解释为由当前视图调用,而不是由正在创建的视图调用,因为你传递的是 Activity 实例(如果像我一样在 onCreate() 中结束时执行)。
所以,如果意图是在创建活动中调用 showAsPopup(),而不是在已创建活动中调用它,那么如何在 onCreate() 之前获取可修改的 Activity 实例并不明显。问题在于,在 setContentView() 被调用之后就无法调用 requestWindowFeature() 等类似的方法(示例),而这通常是在 onCreate() 中调用的。
再次强调,如果有更容易/更好的方法,请给予反馈。希望这对想使用此方法的人有所帮助。
showAsPopup(Activity activity)
方法更改为“public static”方法,然后在onCreate
调用它之前(除了super.onCreate
)调用它。 - Ldev我花费了大量时间来尝试解决这个问题。接受的答案在Galaxy Nexus 7(Android 4.2)上有效,但在Samsung Galaxy SIII(Android 4.1)和Samsung Galaxy Tab 10.2(Android 4.0)上失败,会出现以下异常:
IllegalStateException: ActionBarView can only be used with android:layout_width="match_parent" (or fill_parent)
private void showAsPopup(Activity activity) {
//To show activity as dialog and dim the background, you need to declare android:theme="@style/PopupTheme" on for the chosen activity on the manifest
activity.requestWindowFeature(Window.FEATURE_ACTION_BAR);
activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND,
WindowManager.LayoutParams.FLAG_DIM_BEHIND);
LayoutParams params = activity.getWindow().getAttributes();
params.alpha = 1.0f;
params.dimAmount = 0f;
activity.getWindow().setAttributes((android.view.WindowManager.LayoutParams) params);
// This sets the window size, while working around the IllegalStateException thrown by ActionBarView
activity.getWindow().setLayout(850,850);
}
为了完整起见,这里再次提供PopupTheme:
<style name="PopupTheme" parent="android:Theme.Holo.Light.Dialog">
<item name="android:windowIsFloating">false</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowSoftInputMode">stateAlwaysHidden</item>
<item name="android:windowActionModeOverlay">true</item>
<item name="android:windowIsTranslucent">true</item>
</style>
我找到了一个不错的方法来实现它,使用setCustomTitle在DialogFragment的alertDialog构建器上(也可以在alertDialog本身上)。
public Dialog onCreateDialog(final Bundle savedInstanceState) {
final AlertDialog.Builder builder = new AlertDialog.Builder(activity,...);
final Toolbar toolbar = (Toolbar) inflater.inflate(R.layout.dialog_app_filter_toolbar, null, false);
// <= prepare toolbar and dialog here
return builder.create();
}
并且结果(来自我的应用):
如果您不想使用AlertDialog,仍然可以将工具栏放入对话框的布局中并使用它。我在这方面可能没有太多经验,但我会使用一个活动,添加操作栏项目,然后:
<activity android:name=".YourActivity"
android:theme="@android:style/Theme.Holo.Light.Dialog" />
希望能对你有所帮助!
Theme.Holo.Light.Dialog
继承的自定义主题,并将 android:windowActionBar
属性设置为 true
。一旦这样做,我就会收到一个异常 java.lang.IllegalStateException: ActionBarImpl can only be used with a compatible window decor layout
。 - Paul Blessing就像Veeti所暗示的那样,您可能希望尝试使用对话框主题实现一个Activity。在Android清单文件中:
<activity android:name=".YourActivity" android:theme="@android:style/Theme.Dialog </activity>
希望这能有所帮助。
我知道这不是真正的答案,但以上解决方案似乎很不优雅,人们可能认为完全避免操作栏会更容易,例如从带有.noActionBar的主题继承对话框主题,然后在面板顶部创建一个模拟操作栏的视图,至少这样所有内容都保留在xlm中。
DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); getWindow().setLayout(metrics.widthPixels - 80, metrics.heightPixels - 80);
- Abandoned Cart