Android动作监听器调用另一个类中的方法

发布于 2024-11-09 05:46:28 字数 4303 浏览 0 评论 0原文

我有一个列表视图,每行都有一个按钮。我创建了一个自定义 Adapter 类和一个 ItemModel 类来保存每行的数据。在 ItemModel 类中,我为按钮定义了一个 ActionListener。如何从按钮的操作侦听器内部调用另一个类中的方法?

现在如果我说 Classname clsName = new Classname();并在actionlistener内部执行clsName.methodName(variableToPass); <--- 这一切都编译了,但当我单击按钮时崩溃了..有人知道如何让它工作吗?

MyListModel 类

public class MyListItemModel{ //that's our book
private String title; // the book's title
private String description; //the book's description
int id; //book owner id
String key; //book key
private Context context;
Shelf shelf = new Shelf();  //shelf class


public MyListItemModel(Context c){
    this.context=c;

 }


public String getTitle() {
    return title;
}
public void setTitle(String title) {
    this.title = title;
}
public String getDescription() {
    return description;
}
public void setDescription(String description) {
    this.description = description;
}

public String getKey() {
    return key;
}

public void setKey(String key){
    this.key = key;
}


OnClickListener listener = new OnClickListener(){ // the book's action
    @Override
    public void onClick(View v) {
        //code for the button action
        //THIS DOESN'T WORK PROPERLY AND CRASHES ON CLICK. However if i use a Toast to print the key on each click - it will print the right key to screen.

        shelf.downloadBook(new String(key));

    }
};
int getBookId(){

    return title.hashCode();
}
}

MyListAdapter 类 - getView 的方法

public class MyListAdapter extends BaseAdapter {

View renderer;
List<MyListItemModel> items;
ArrayList<HashMap<String, String>> mylist;
private LayoutInflater mInflater;
private Context context;


public MyListAdapter(Context c){
    this.context=c;
    mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

}

....

 @Override
public View getView(int position, View convertView, ViewGroup parent) {

    if(convertView==null){
        //convertView = renderer;
        convertView = mInflater.inflate(R.layout.shelfrow, null);

    }
    MyListItemModel item = items.get(position);
    TextView label = (TextView)convertView.findViewById(R.id.item_title);
    label.setText(item.getTitle());
    TextView label2 = (TextView)convertView.findViewById(R.id.item_subtitle);
    label2.setText(item.getDescription());
    Button button = (Button)convertView.findViewById(R.id.btn_download);
    button.setOnClickListener(item.listener);


    return convertView;
}

我的 Shelf 类有一个名为 downloadBook(String bookKey) 的方法 <-- 这是我想要在每次单击按钮时调用的方法,并向该方法传递适当的书籍密钥。我还有 2 个 xml 文件(shelfrow.xml 和 shelflist.xml)。一个包含文本字段和按钮,另一个包含列表视图。

的一些代码

List<MyListItemModel> myListModel = new ArrayList<MyListItemModel>();

            try{

                JSONArray entries = json.getJSONArray("entries");

                for(int i=0;i<entries.length();i++){                        

                    MyListItemModel item = new MyListItemModel(this);
                    JSONObject e = entries.getJSONObject(i);
                    item.id = i;        //user ID
                    bookKey = (e.getString("key"));
                    item.setTitle(e.getString("title"));
                    item.setDescription(e.getString("description"));

                                    myListModel.add(item);  
                        }

                    }catch(JSONException e) {
                        Log.e("log_tag", "Error parsing data "+e.toString());
                    }


                    MyListAdapter adapter = new MyListAdapter(this);
                    adapter.setModel(myListModel);
                    setListAdapter(adapter);
                    lv = getListView();
                    lv.setTextFilterEnabled(true); 

….

 public void downloadBook(String theKey) {
      //take theKey and append it to a url address to d/l
  }

来自 Logcat 的 Shelf.java 类 Stacktrace

05-23 02:34:59.439: INFO/wpa_supplicant(14819): Reset vh_switch_counter due to receive LINKSPEED cmd 05-23 02:34:59.439: DEBUG/ConnectivityService(1346): getMobileDataEnabled returning true 05-23 02:36:39.269: DEBUG/StatusBarPolicy(6068): onSignalStrengthsChange

也出现了 zygoteinit methodandargscaller.run

I have a listview with a button in each row. I have made a custom Adapter class and a ItemModel class to hold the data for each row. Inside the ItemModel class I have defined an ActionListener for the button. How can I call a method in another class from inside my button's action listener?

Right now if i say Classname clsName = new Classname(); and inside the actionlistener do clsName.methodName(variableToPass); <--- this all compiles but crashes when I click the button..Anyone know how to get this to work?

MyListModel Class

public class MyListItemModel{ //that's our book
private String title; // the book's title
private String description; //the book's description
int id; //book owner id
String key; //book key
private Context context;
Shelf shelf = new Shelf();  //shelf class


public MyListItemModel(Context c){
    this.context=c;

 }


public String getTitle() {
    return title;
}
public void setTitle(String title) {
    this.title = title;
}
public String getDescription() {
    return description;
}
public void setDescription(String description) {
    this.description = description;
}

public String getKey() {
    return key;
}

public void setKey(String key){
    this.key = key;
}


OnClickListener listener = new OnClickListener(){ // the book's action
    @Override
    public void onClick(View v) {
        //code for the button action
        //THIS DOESN'T WORK PROPERLY AND CRASHES ON CLICK. However if i use a Toast to print the key on each click - it will print the right key to screen.

        shelf.downloadBook(new String(key));

    }
};
int getBookId(){

    return title.hashCode();
}
}

MyListAdapter class - method for getView

public class MyListAdapter extends BaseAdapter {

View renderer;
List<MyListItemModel> items;
ArrayList<HashMap<String, String>> mylist;
private LayoutInflater mInflater;
private Context context;


public MyListAdapter(Context c){
    this.context=c;
    mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

}

....

 @Override
public View getView(int position, View convertView, ViewGroup parent) {

    if(convertView==null){
        //convertView = renderer;
        convertView = mInflater.inflate(R.layout.shelfrow, null);

    }
    MyListItemModel item = items.get(position);
    TextView label = (TextView)convertView.findViewById(R.id.item_title);
    label.setText(item.getTitle());
    TextView label2 = (TextView)convertView.findViewById(R.id.item_subtitle);
    label2.setText(item.getDescription());
    Button button = (Button)convertView.findViewById(R.id.btn_download);
    button.setOnClickListener(item.listener);


    return convertView;
}

My Shelf class has a method called downloadBook(String bookKey) <-- this is what I want to call with each button click and pass this method the appropriate book key. I also have 2 xml files (shelfrow.xml and shelflist.xml). One contains the textfields and button and the other contains the listview.

Some of the code from Shelf.java class

List<MyListItemModel> myListModel = new ArrayList<MyListItemModel>();

            try{

                JSONArray entries = json.getJSONArray("entries");

                for(int i=0;i<entries.length();i++){                        

                    MyListItemModel item = new MyListItemModel(this);
                    JSONObject e = entries.getJSONObject(i);
                    item.id = i;        //user ID
                    bookKey = (e.getString("key"));
                    item.setTitle(e.getString("title"));
                    item.setDescription(e.getString("description"));

                                    myListModel.add(item);  
                        }

                    }catch(JSONException e) {
                        Log.e("log_tag", "Error parsing data "+e.toString());
                    }


                    MyListAdapter adapter = new MyListAdapter(this);
                    adapter.setModel(myListModel);
                    setListAdapter(adapter);
                    lv = getListView();
                    lv.setTextFilterEnabled(true); 

….

 public void downloadBook(String theKey) {
      //take theKey and append it to a url address to d/l
  }

Stacktrace from logcat

05-23 02:34:59.439: INFO/wpa_supplicant(14819): Reset vh_switch_counter due to receive LINKSPEED cmd 05-23 02:34:59.439: DEBUG/ConnectivityService(1346): getMobileDataEnabled returning true 05-23 02:36:39.269: DEBUG/StatusBarPolicy(6068): onSignalStrengthsChange

also this came up zygoteinit methodandargscaller.run

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

只是在用心讲痛 2024-11-16 05:46:28

我将在这里冒险,但我想我知道问题是什么。

在最后一段代码中,您没有设置 MyListItemModel 上的 key 字段。相反,您设置了一些名为“bookKey”的变量(我看不到它的定义位置)。

我敢打赌,如果你改变这句话:

bookKey = (e.getString("key"));

变成这样:

item.setKey(e.getString("key"));
//or item.key = e.getString("key"));

一切都会为你工作得很好。如果将 null 字符串传递给 String(String) 构造函数,您将得到 NullPointerException,因为该构造函数需要非 null 字符串。

我要提到的是,您没有必要使用 String(String) 构造函数,您只需在第一个片段中执行此操作就可以了:

shelf.downloadBook(key);

I am going to go out on a limb here, but I think I know what the issue is.

In the last snippet of code, you are not setting the key field on the MyListItemModel. You are instead setting some variable called 'bookKey' (I do not see where it is defined).

I bet if you change this line:

bookKey = (e.getString("key"));

to be this:

item.setKey(e.getString("key"));
//or item.key = e.getString("key"));

everything will work just fine for you. If you pass in a null String to the String(String) constructor, you will get a NullPointerException, as that constructor expects a non-null String.

I will mention that it is not necessary for you use the String(String) constructor, you should be fine just doing this in the fist snippet:

shelf.downloadBook(key);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文