0

我正在尝试将不同的按钮链接到不同的活动。所以实际上创建了一个导航菜单。

我正在尝试使用更少的代码,因此我正在尝试创建一个可以传递值的函数,以便动态识别按钮 ID 并为其提供指向活动的链接。

这是我的xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@+id/nav1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:text="@string/nav1" />

    <Button
        android:id="@+id/nav2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/nav1"
        android:text="@string/nav2" />

</RelativeLayout>

这是我的Java:

package com.example.myfirstapp;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class Nav extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_nav);

        String nav1 = "nav1";
        String nav2 = "nav2";

        String MainActivity = "MainActivity";
        String SQLite = "SQLite";

        navButton(nav1, MainActivity);
        navButton(nav2, SQLite);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_nav, menu);
        return true;
    }

    private void navButton(String buttonId, String activityName){
        String bId = buttonId;
        final Class<?> aName = Class.forName(activityName);
        int resId = getResources().getIdentifier(bId, "id", getPackageName());
        Button b = (Button) findViewById(resId);
        OnClickListener onClickListener = new OnClickListener(){
            @Override
            public void onClick(View v) {
                Intent i = new Intent(Nav.this, aName);
                startActivity(i);
            }};
        b.setOnClickListener(onClickListener);
    }
}

我在网上收到一个错误:

final Class<?> aName = Class.forName(activityName);

它说:

Unhandled exception type ClassNotFoundException

或者很简单,最好的方法是什么

4

3 回答 3

3

每当我使用 Class.forName 时,我都会传入一个限定名称,例如“mypackage.myclass”。我不确定它是否适用于不合格的名称。

无论如何,为什么要传入字符串然后执行forName?为什么不更改签名以获取 Class 对象并传入 MainActivity.class 等?然后你会在编译时而不是运行时捕获任何丢失的类或拼写错误。

更新以回应评论

public class Nav extends Activity { 

  @Override 
  public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_nav); 

    navButton("nav1", MainActivity.class); 
    navButton("nav2", SQLite.class); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.activity_nav, menu); 
    return true; 
} 

private void navButton(String buttonId, Class aName){ 
    String bId = buttonId; 
    // aName now passed in so doesn't need to be looked up
    ... etc ...
} 
} 

我认为上面应该编译并运行。我没有尝试过,但我做过类似的事情。根据你的包的设置方式,你可能需要导入 MainActivity 和 SQLite,或者完全质量它们,以便获取 .class。

于 2012-07-31T16:01:58.417 回答
0

您是否在应用程序中定义了活动AndroidManifest.xml

于 2012-07-31T15:57:31.283 回答
0

您没有捕获已检查的异常ClassNotFoundException。您需要将相关代码包装在 try/catch 块中,例如

try {
    final Class<?> aName = Class.forName(activityName);
    //etc...
} catch (ClassNotFoundException e) {
    //Do whatever cleanup you have to do in case this situation occurs.
}

不过,这似乎是一种设置点击侦听器的异常尴尬的方式。为什么您不能只将类本身传递给您的 navButton 方法而不是进行反射(如果有替代方法,这应该始终是最后的手段)?

于 2012-07-31T16:02:57.493 回答