在 Android Java 中重用带有字符串参数的 onclick 侦听器
Reusing onclick listener with a string parameter in Android Java
我正在模仿这个 thread 中的代码来创建一个可重复使用的点击事件来启动浏览器。我想在实例化 class 时传递自定义 URL 目标。该示例在 eclipse 中没有明显错误,但在启动时崩溃:
FATAL EXCEPTION: main
02-19 12:45:57.416: E/AndroidRuntime(12465): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.app/com.app.ItemActivity}: java.lang.NullPointerException
错误应该出自这一行
btn.setOnClickListener(new ButtonInternetAccess("http://google.com"));
因为没有那条线它也能正常工作。
class ButtonInternetAccess
是否无法 return 导致空值的 onClickListener?我该如何解决?
主要Activity:
public class ItemActivity extends ActionBarActivity{
private static final View View = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item);
Bundle b = i.getExtras();
Button btn = (Button) findViewById(R.id.button_internet_access);
btn.setOnClickListener(new ButtonInternetAccess("http://google.com"));
}
}
按钮Class:
public class ButtonInternetAccess extends Activity implements OnClickListener {
String url;
public ButtonInternetAccess(String url) {
this.url = url;
}
public void onClick(View v) {
try {
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse(url));
startActivity(callIntent); // No Error here
System.out.println(url);
} catch (ActivityNotFoundException activityException) {
Log.e("Calling a Phone Number", "Call failed", activityException);
}
}
}
layout/activity_item
<TextView
android:id="@+id/response"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="" />
<include android:id="@+id/header" layout="@layout/button_internet_access">
layout/button_internet_access:
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/button_internet_access"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="go out" />
错误:
02-19 12:45:57.416: E/AndroidRuntime(12465): FATAL EXCEPTION: main
02-19 12:45:57.416: E/AndroidRuntime(12465): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.app/com.app.ItemActivity}: java.lang.NullPointerException
02-19 12:45:57.416: E/AndroidRuntime(12465): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
02-19 12:45:57.416: E/AndroidRuntime(12465): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
02-19 12:45:57.416: E/AndroidRuntime(12465): at android.app.ActivityThread.access0(ActivityThread.java:130)
02-19 12:45:57.416: E/AndroidRuntime(12465): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
02-19 12:45:57.416: E/AndroidRuntime(12465): at android.os.Handler.dispatchMessage(Handler.java:99)
02-19 12:45:57.416: E/AndroidRuntime(12465): at android.os.Looper.loop(Looper.java:137)
02-19 12:45:57.416: E/AndroidRuntime(12465): at android.app.ActivityThread.main(ActivityThread.java:4745)
02-19 12:45:57.416: E/AndroidRuntime(12465): at java.lang.reflect.Method.invokeNative(Native Method)
02-19 12:45:57.416: E/AndroidRuntime(12465): at java.lang.reflect.Method.invoke(Method.java:511)
02-19 12:45:57.416: E/AndroidRuntime(12465): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
02-19 12:45:57.416: E/AndroidRuntime(12465): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
02-19 12:45:57.416: E/AndroidRuntime(12465): at dalvik.system.NativeStart.main(Native Method)
02-19 12:45:57.416: E/AndroidRuntime(12465): Caused by: java.lang.NullPointerException
02-19 12:45:57.416: E/AndroidRuntime(12465): at com.app.ItemActivity.onCreate(ItemActivity.java:29)
02-19 12:45:57.416: E/AndroidRuntime(12465): at android.app.Activity.performCreate(Activity.java:5008)
02-19 12:45:57.416: E/AndroidRuntime(12465): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
02-19 12:45:57.416: E/AndroidRuntime(12465): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
已更新:
我已经成功地制作了一个插件 link。
最终作品:
Class 互联网:
public class Internet implements OnClickListener {
private String url;
private Context context;
public Internet(Context context, String url) {
this.context = context;
this.url = url;
}
@Override
public void onClick(View v) {
if (!url.contains("http://")){
url = "http://"+url;
}
Intent callIntent = new Intent(Intent.ACTION_VIEW);
callIntent.setData(Uri.parse(url));
context.startActivity(callIntent);
}
}
Class样式按钮:
public class StyleButton extends Button{
public StyleButton(Context context) {
super(context);
}
public StyleButton(Context context, AttributeSet attrs) {
super(context, attrs);
initStyleButton(attrs);
}
public StyleButton(Context context, AttributeSet attrs, int defStyle,String url) {
super(context, attrs, defStyle);
initStyleButton(attrs);
}
private void initStyleButton(AttributeSet attrs){
TypedArray a = getContext().obtainStyledAttributes(attrs,R.styleable.style_Button);
String Text1 = a.getString(R.styleable.style_Button_myText_1);
String Text2 = a.getString(R.styleable.style_Button_myText_2);
setText(Text1 + "\n" + Text2);
String url = a.getString(R.styleable.style_Button_url);
System.out.println(url);
setOnClickListener(new Internet(getContext(),url));
a.recycle();
}
}
/layout/item_activity
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:stylebutton= "http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id="@+id/response"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text=""/>
<com.button.StyleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
stylebutton:myText_1="My Text 1"
stylebutton:myText_2="My Text 2"
stylebutton:url="www.google.com"
/>
<com.button.StyleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
stylebutton:myText_1="Hello!"
stylebutton:myText_2="It's a Style Button:)"
stylebutton:url="www.yahoo.com"
/>
/value/attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="style_Button">
<attr name="myText_1" format="string" />
<attr name="myText_2" format="string" />
<attr name="url" format="string" />
</declare-styleable>
</resources>
将按钮 Class 更改为;
public class ButtonInternetAccess implements View.OnClickListener {
private String url;
private Context context;
public ButtonInternetAccess(Context context, String url) {
this.context = context;
this.url = url;
}
public void onClick(View v) {
System.out.println(url);
Intent callIntent = new Intent(Intent.ACTION_VIEW);
callIntent.setData(Uri.parse(url));
try {
context.startActivity(callIntent);
} catch (ActivityNotFoundException activityException) {
Log.e("ONCLICK", "No Activity found", activityException);
}
}
}
您的 setOnClickListener 应该如下所示:
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("http://google.com"));
startActivity(callIntent); // No Error here
System.out.println(url);
} catch (ActivityNotFoundException activityException) {
Log.e("Calling a Phone Number", "Call failed", activityException);
}
}
});
您似乎不需要将 URL 发送给另一个 class,因为您可以对 ItemActivity
本身执行相同的操作。
已编辑:如果您想推广一个 class,请将您的 ButtonInternetAccess 更新为以下方式:
public class ButtonInternetAccess implements OnClickListener {
String url;
Context mContext;
public ButtonInternetAccess(Context mContext,String url) {
this.url = url;
this.mContext=mContext;
}
public void onClick(View v) {
try {
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse(url));
mContext.startActivity(callIntent);
System.out.println(url);
} catch (ActivityNotFoundException activityException) {
Log.e("Calling a Phone Number", "Call failed", activityException);
}
}
}
创建您的 custom button 并在您的项目中使用它,这样就可以在全球范围内使用它。
public class ButtonInternetAccess extends UIButton implements OnClickListener {
String url;
Context mContext;
public ButtonInternetAccess(Context context, AttributeSet attrs,String url) {
super(context, attrs);
this.url = url;
this.mContext=mContext;
// TODO Auto-generated constructor stub
}
// initialize button and add click listener here.
}
您可以将该按钮添加到您的 xml 中,也可以像
<yourpackagename.ButtonInternetAccess
height=""
width = ""
other properties to include
/>
希望这会有所帮助。
我正在模仿这个 thread 中的代码来创建一个可重复使用的点击事件来启动浏览器。我想在实例化 class 时传递自定义 URL 目标。该示例在 eclipse 中没有明显错误,但在启动时崩溃:
FATAL EXCEPTION: main
02-19 12:45:57.416: E/AndroidRuntime(12465): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.app/com.app.ItemActivity}: java.lang.NullPointerException
错误应该出自这一行
btn.setOnClickListener(new ButtonInternetAccess("http://google.com"));
因为没有那条线它也能正常工作。
class ButtonInternetAccess
是否无法 return 导致空值的 onClickListener?我该如何解决?
主要Activity:
public class ItemActivity extends ActionBarActivity{
private static final View View = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item);
Bundle b = i.getExtras();
Button btn = (Button) findViewById(R.id.button_internet_access);
btn.setOnClickListener(new ButtonInternetAccess("http://google.com"));
}
}
按钮Class:
public class ButtonInternetAccess extends Activity implements OnClickListener {
String url;
public ButtonInternetAccess(String url) {
this.url = url;
}
public void onClick(View v) {
try {
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse(url));
startActivity(callIntent); // No Error here
System.out.println(url);
} catch (ActivityNotFoundException activityException) {
Log.e("Calling a Phone Number", "Call failed", activityException);
}
}
}
layout/activity_item
<TextView
android:id="@+id/response"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="" />
<include android:id="@+id/header" layout="@layout/button_internet_access">
layout/button_internet_access:
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/button_internet_access"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="go out" />
错误:
02-19 12:45:57.416: E/AndroidRuntime(12465): FATAL EXCEPTION: main
02-19 12:45:57.416: E/AndroidRuntime(12465): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.app/com.app.ItemActivity}: java.lang.NullPointerException
02-19 12:45:57.416: E/AndroidRuntime(12465): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
02-19 12:45:57.416: E/AndroidRuntime(12465): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
02-19 12:45:57.416: E/AndroidRuntime(12465): at android.app.ActivityThread.access0(ActivityThread.java:130)
02-19 12:45:57.416: E/AndroidRuntime(12465): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
02-19 12:45:57.416: E/AndroidRuntime(12465): at android.os.Handler.dispatchMessage(Handler.java:99)
02-19 12:45:57.416: E/AndroidRuntime(12465): at android.os.Looper.loop(Looper.java:137)
02-19 12:45:57.416: E/AndroidRuntime(12465): at android.app.ActivityThread.main(ActivityThread.java:4745)
02-19 12:45:57.416: E/AndroidRuntime(12465): at java.lang.reflect.Method.invokeNative(Native Method)
02-19 12:45:57.416: E/AndroidRuntime(12465): at java.lang.reflect.Method.invoke(Method.java:511)
02-19 12:45:57.416: E/AndroidRuntime(12465): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
02-19 12:45:57.416: E/AndroidRuntime(12465): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
02-19 12:45:57.416: E/AndroidRuntime(12465): at dalvik.system.NativeStart.main(Native Method)
02-19 12:45:57.416: E/AndroidRuntime(12465): Caused by: java.lang.NullPointerException
02-19 12:45:57.416: E/AndroidRuntime(12465): at com.app.ItemActivity.onCreate(ItemActivity.java:29)
02-19 12:45:57.416: E/AndroidRuntime(12465): at android.app.Activity.performCreate(Activity.java:5008)
02-19 12:45:57.416: E/AndroidRuntime(12465): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
02-19 12:45:57.416: E/AndroidRuntime(12465): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
已更新:
我已经成功地制作了一个插件 link。
最终作品:
Class 互联网:
public class Internet implements OnClickListener {
private String url;
private Context context;
public Internet(Context context, String url) {
this.context = context;
this.url = url;
}
@Override
public void onClick(View v) {
if (!url.contains("http://")){
url = "http://"+url;
}
Intent callIntent = new Intent(Intent.ACTION_VIEW);
callIntent.setData(Uri.parse(url));
context.startActivity(callIntent);
}
}
Class样式按钮:
public class StyleButton extends Button{
public StyleButton(Context context) {
super(context);
}
public StyleButton(Context context, AttributeSet attrs) {
super(context, attrs);
initStyleButton(attrs);
}
public StyleButton(Context context, AttributeSet attrs, int defStyle,String url) {
super(context, attrs, defStyle);
initStyleButton(attrs);
}
private void initStyleButton(AttributeSet attrs){
TypedArray a = getContext().obtainStyledAttributes(attrs,R.styleable.style_Button);
String Text1 = a.getString(R.styleable.style_Button_myText_1);
String Text2 = a.getString(R.styleable.style_Button_myText_2);
setText(Text1 + "\n" + Text2);
String url = a.getString(R.styleable.style_Button_url);
System.out.println(url);
setOnClickListener(new Internet(getContext(),url));
a.recycle();
}
}
/layout/item_activity
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:stylebutton= "http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id="@+id/response"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text=""/>
<com.button.StyleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
stylebutton:myText_1="My Text 1"
stylebutton:myText_2="My Text 2"
stylebutton:url="www.google.com"
/>
<com.button.StyleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
stylebutton:myText_1="Hello!"
stylebutton:myText_2="It's a Style Button:)"
stylebutton:url="www.yahoo.com"
/>
/value/attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="style_Button">
<attr name="myText_1" format="string" />
<attr name="myText_2" format="string" />
<attr name="url" format="string" />
</declare-styleable>
</resources>
将按钮 Class 更改为;
public class ButtonInternetAccess implements View.OnClickListener {
private String url;
private Context context;
public ButtonInternetAccess(Context context, String url) {
this.context = context;
this.url = url;
}
public void onClick(View v) {
System.out.println(url);
Intent callIntent = new Intent(Intent.ACTION_VIEW);
callIntent.setData(Uri.parse(url));
try {
context.startActivity(callIntent);
} catch (ActivityNotFoundException activityException) {
Log.e("ONCLICK", "No Activity found", activityException);
}
}
}
您的 setOnClickListener 应该如下所示:
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("http://google.com"));
startActivity(callIntent); // No Error here
System.out.println(url);
} catch (ActivityNotFoundException activityException) {
Log.e("Calling a Phone Number", "Call failed", activityException);
}
}
});
您似乎不需要将 URL 发送给另一个 class,因为您可以对 ItemActivity
本身执行相同的操作。
已编辑:如果您想推广一个 class,请将您的 ButtonInternetAccess 更新为以下方式:
public class ButtonInternetAccess implements OnClickListener {
String url;
Context mContext;
public ButtonInternetAccess(Context mContext,String url) {
this.url = url;
this.mContext=mContext;
}
public void onClick(View v) {
try {
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse(url));
mContext.startActivity(callIntent);
System.out.println(url);
} catch (ActivityNotFoundException activityException) {
Log.e("Calling a Phone Number", "Call failed", activityException);
}
}
}
创建您的 custom button 并在您的项目中使用它,这样就可以在全球范围内使用它。
public class ButtonInternetAccess extends UIButton implements OnClickListener {
String url;
Context mContext;
public ButtonInternetAccess(Context context, AttributeSet attrs,String url) {
super(context, attrs);
this.url = url;
this.mContext=mContext;
// TODO Auto-generated constructor stub
}
// initialize button and add click listener here.
}
您可以将该按钮添加到您的 xml 中,也可以像
<yourpackagename.ButtonInternetAccess
height=""
width = ""
other properties to include
/>
希望这会有所帮助。