How to avoid setting inline onClickListner in getV

2019-05-26 01:02发布

I was asked to refactor the getView() code presented below.

I have got ListView with custom Adapter. Every row contains clickable buttons and texts.

At the moment onClickListeners are set in the body of getView(), this is quite insane idea, because this method is called very frequently. Inside of every onClick function I need access to the private data to call new activity with bundle.

How can i move onClick definition outside getView() routine?

When onClick will be called I need info about position of list element (to access private data) and which View was clicked (to start correct Activity) .

public View getView(int position, View convertView, ViewGroup parent) {
    if(convertview == null) {
        convertView = ((Activity) getContext()).getLayoutInflater().inflate(R.layout.photo_tweet_row, null);
    }

    TextView userTweet = (TextView) v.findViewById(R.id.feed_user_tweet_body);
    RepliesButton repliesBtn = (RepliesButton) v.findViewById(R.id.feed_replies_button);

    Status twitterDataItem = getItem(position);

    if (twitterDataItem != null) {

        if (userTweet != null) {
            userTweet.setText(twitterDataItem.getText());
        }
        if (repliesBtn != null) {
            repliesBtn.setText(" replies");
        }

        userTweet.setOnClickListener(new View.OnClickListener() {           
            @Override
            public void onClick(View v) {                    
              Intent intent = new Intent(getContext(), ProfileActivity.class); 
              intent.putExtra(getContext().getString(R.string.serializable_user), twitterDataItem.getUser());
              getContext().startActivity(intent);
            }
        });

        repliesBtn.setOnClickListener(new View.OnClickListener() {

            public void onClick(View view) {
                if (!twitterDataItem.getComments().contentEquals("0")) {
                    Intent myIntent = new Intent(getContext(), RepliesToFeedActivity.class);
                    myIntent.putExtra("photoTweet", twitterDataItem);
                    getContext().startActivity(myIntent);
                }
            }
        });
    }
    return convertView;
}

2条回答
我想做一个坏孩纸
2楼-- · 2019-05-26 01:21

Your activitiy has to implement the OnClickListener, and move the implemented method up to the activity level.

Based on the view parameter of the method you are able to detect from which UI object the event came from (button, textview).

As for how to detect for which record/row in a listview. You have to set a custom tag on the buttons and textviews in the getView method, that you will read in the event via getTag this tag can be a custom object too if string is not enough. Probably/recommended way is to be the position in the adapter.

查看更多
唯我独甜
3楼-- · 2019-05-26 01:27

I am afraid that Pentium10 answer is not correct. If the checkbox is to be clickable and checkable independently from the list item itself, (say it is defined in the list item xml layout), then it will intercept the click event, and the list item (the list's OnItemClickListener) will not receive the click at all. Therefore you must implement the onClickListener in the adapter itself - either in getView(), or have the adapter implement onClickListener - in this case the items must be tagged for the listener to know which item it is operating on.

查看更多
登录 后发表回答