gpt4 book ai didi

java - 无法以编程方式启动 DialogPreference(抛出空指针异常)

转载 作者:太空狗 更新时间:2023-10-29 13:29:58 28 4
gpt4 key购买 nike

我有一个扩展 DialogPreference 的自定义类。如果从“首选项”菜单启动,它会完美运行。我也希望能够从 Activity 启动它。下面是我的 DialogPreference 类,我在其中公开了 showDialog() 方法 suggested by this thread .当我调用它时,我得到一个 Null Pointer Exception,但一直无法弄清楚原因。

错误在调用 hText.setText() 的 onBindDialogView() 中的第 27 行抛出。

package com.jumptuck.recipebrowser;

import android.content.Context;
import android.content.SharedPreferences;
import android.preference.DialogPreference;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.EditText;

// Pop-up dialog used to set and modify host and login credentials
public class HostCredentialsDialogPreference extends DialogPreference {
static final String TAG = "HostCredentialsDialogPreference";
EditText hText, uText, pText;

public HostCredentialsDialogPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setDialogLayoutResource(R.layout.dialog_host_credentials);
}

@Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
Log.d(TAG,"onBindDialogView");

SharedPreferences sp = getSharedPreferences();
hText.setText(sp.getString("host", ""));
uText.setText(sp.getString("username", ""));
pText.setText(sp.getString("password", ""));
}

@Override
protected View onCreateDialogView() {
// Guide for this technique found at:
// http://alexfu.tumblr.com/post/23683149440/android-dev-custom-dialogpreference
Log.d(TAG,"onCreateDialogView");
View root = super.onCreateDialogView();
hText = (EditText) root.findViewById(R.id.host);
uText = (EditText) root.findViewById(R.id.username);
pText = (EditText) root.findViewById(R.id.password);
return root;
}

@Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if (positiveResult){
Log.d(TAG,"Clicked Save");
SharedPreferences sp = getSharedPreferences();
SharedPreferences.Editor editor = sp.edit();
editor.putString("host", hText.getText().toString());
editor.putString("username", uText.getText().toString());
editor.putString("password", pText.getText().toString());
editor.commit();
}
else {
Log.d(TAG,"Clicked Cancel");
}
}

void show() {
showDialog(null);
}

}

我正在使用“测试”按钮尝试从另一个 Activity 启动对话框:

public boolean onOptionsItemSelected(MenuItem item) {
Log.d(TAG, "onOptionsItemSelected");

switch (item.getItemId()) {
case R.id.item_prefs:
startActivity(new Intent(this, PrefsActivity.class));
return true;
case R.id.refresh:
if (credentialsExist()) {
refreshListView();
}
return true;
case R.id.recipe_dir:
startActivity(new Intent(this, RecipeDisplayActivity.class));
return true;
case R.id.testing:
HostCredentialsDialogPreference hc = new HostCredentialsDialogPreference(this, null);
hc.show();
return true;

default:
return false;
}
}

这是我的首选项和对话框首选项的 xml 文件:

<?xml version="1.0" encoding="utf-8"?>

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<com.jumptuck.recipebrowser.HostCredentialsDialogPreference
android:key="dialog_credentials"
android:title="Server Address and Login"
android:summary="Set Host, Username and Password" />

</PreferenceScreen>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >

<TextView
android:id="@+id/dialog_hostname_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/dialog_hint_uri" />

<EditText
android:id="@+id/host"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textUri" />

<TextView
android:id="@+id/dialog_username_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/dialog_hint_user" />

<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text" />

<TextView
android:id="@+id/dialog_password_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/dialog_hint_password" />

<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif"
android:inputType="textPassword" />

</LinearLayout>

最后是 Logcat:

D/RecipeListActivity( 5894): onOptionsItemSelected
D/HostCredentialsDialogPreference( 5894): onCreateDialogView
D/HostCredentialsDialogPreference( 5894): onBindDialogView
D/AndroidRuntime( 5894): Shutting down VM
W/dalvikvm( 5894): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
E/AndroidRuntime( 5894): FATAL EXCEPTION: main
E/AndroidRuntime( 5894): java.lang.NullPointerException
E/AndroidRuntime( 5894): at com.jumptuck.recipebrowser.HostCredentialsDialogPreference.onBindDialogView(HostCredentialsDialogPreference.java:27)
E/AndroidRuntime( 5894): at android.preference.DialogPreference.showDialog(DialogPreference.java:289)
E/AndroidRuntime( 5894): at com.jumptuck.recipebrowser.HostCredentialsDialogPreference.show(HostCredentialsDialogPreference.java:62)
E/AndroidRuntime( 5894): at com.jumptuck.recipebrowser.RecipeListActivity.onOptionsItemSelected(RecipeListActivity.java:192)
E/AndroidRuntime( 5894): at android.app.Activity.onMenuItemSelected(Activity.java:2534)
E/AndroidRuntime( 5894): at com.android.internal.policy.impl.PhoneWindow.onMenuItemSelected(PhoneWindow.java:958)
E/AndroidRuntime( 5894): at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:735)
E/AndroidRuntime( 5894): at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:149)
E/AndroidRuntime( 5894): at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:874)
E/AndroidRuntime( 5894): at com.android.internal.view.menu.ListMenuPresenter.onItemClick(ListMenuPresenter.java:166)
E/AndroidRuntime( 5894): at android.widget.AdapterView.performItemClick(AdapterView.java:298)
E/AndroidRuntime( 5894): at android.widget.AbsListView.performItemClick(AbsListView.java:1086)
E/AndroidRuntime( 5894): at android.widget.AbsListView$PerformClick.run(AbsListView.java:2859)
E/AndroidRuntime( 5894): at android.widget.AbsListView$1.run(AbsListView.java:3533)
E/AndroidRuntime( 5894): at android.os.Handler.handleCallback(Handler.java:615)
E/AndroidRuntime( 5894): at android.os.Handler.dispatchMessage(Handler.java:92)
E/AndroidRuntime( 5894): at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime( 5894): at android.app.ActivityThread.main(ActivityThread.java:4745)
E/AndroidRuntime( 5894): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 5894): at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime( 5894): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
E/AndroidRuntime( 5894): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
E/AndroidRuntime( 5894): at dalvik.system.NativeStart.main(Native Method)
W/ActivityManager( 148): Force finishing activity com.jumptuck.recipebrowser/.RecipeListActivity
W/WindowManager( 148): Failure taking screenshot for (246x410) to layer 21025
W/ActivityManager( 148): Activity pause timeout for ActivityRecord{412097e0 com.jumptuck.recipebrowser/.RecipeListActivity}
I/Choreographer( 281): Skipped 39 frames! The application may be doing too much work on its main thread.
W/ActivityManager( 148): Activity destroy timeout for ActivityRecord{412097e0 com.jumptuck.recipebrowser/.RecipeListActivity}

有人知道我做错了什么吗?谢谢!

最佳答案

最佳答案can be found here但我认为它只需要一点澄清,因为该答案错误地建议 list 有两种不同的样式声明。

如果你想从一个 Activity 启动一个对话框,并且仍然能够从一个首选项中启动它,你只需要创建一个启动对话框的 Activity 。然后该 Activity 可以作为首选项 XML 中的 Intent 或从另一个 Activity 启动。诀窍在于你如何设计它。您想要将 Activity 设置为 Dialog 的样式。这样,您的 Activity 启动的对话框就会看起来正确。这种方法的副作用是 float 操作栏将显示在对话框后面的屏幕中间。解决方法是使用不带 ActionBar 的对话框样式。我正在使用 Holo.Light 主题,所以我将其放入我的 AndroidManifest

<activity android:name=".DemoDialogActivity"
android:theme="@android:style/Theme.Holo.Light.Dialog.NoActionBar" />

难题的另一部分是确保调用 finish();完成后(这是我在 OnClickListener 中为两个按钮所做的最后一件事)。如果不这样做,对话框将关闭,但 Activity 仍将打开,并在变暗的屏幕中间留下一个小的空白矩形。

这是 Activity 的一个工作示例:

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;

public class DemoDialogActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

LayoutInflater lf = LayoutInflater.from(this);
// This adds XML elements as a custom view (optional):
final View customElementsView = lf.inflate(
R.layout.activity_credentials, null);
AlertDialog alert = new AlertDialog.Builder(this)
// This adds the custom view to the Dialog (optional):
.setView(customElementsView)
.setTitle("This is the Title")
.setMessage("This is the AlertDialog message (optional)")
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog,
int which) {
// Cancel was clicked; do something
// Close Activity
finish();
}
})
.setPositiveButton("OK", new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {
// OK was clicked; do something
// Close Activity
finish();
}
}).create();

// Show the dialog
alert.show();
}
}

以编程方式启动它:

Intent launch_dialog = new Intent(getApplicationContext(),
DemoDialogActivity.class);
startActivity(launch_dialog);

或者作为 XML 中的首选项:

<Preference
android:key="demo_dialog"
android:title="Title of item on Prefs screen"
android:summary="This will be small text below the title">
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.example.package.DemoDialogActivity"
android:targetPackage="com.example.package" />
</Preference>

关于java - 无法以编程方式启动 DialogPreference(抛出空指针异常),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16883811/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com