ButterKnife @OnClick查看自定义视图持有者类中的视图

时间:2017-11-05 15:28:10

标签: android android-fragments android-activity android-view butterknife

我在android activity / fragment 中的一个常见做法是在每个只包含视图引用的片段/活动中创建自定义视图持有者静态类。我绑定片段/活动使用ButterKnife查看此自定义视图持有者作为目标。在这种情况下,ButterKnife @OnClick注释不起作用,因为视图引用在视图持有者类中。请查看我的代码。

有没有办法克服这个问题而不破坏我的观察者类?

public class BookDetailFragment extends Fragment {

    private ViewHolder mViewHolder;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View mFragmentView = inflater.inflate(R.layout.book_detail_view, container, false);

        // Binding view holder
        mViewHolder = new ViewHolder(mFragmentView);

        return mFragmentView;
    }

    @OnClick (R.id.book_title)
    public void onBookTitleClicked(TextView v) {
        // This won't work. Is it possible to make it work with view holder class ?
        // If I move this method into ViewHolder class I can't access fragment variables. 
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        mViewHolder.unbind();
    }

    static class ViewHolder {
        @BindView(R.id.book_title) TextView bookTitle;
        @BindView(R.id.book_authors) TextView bookAuthors;

        private Unbinder mButterKnifeUnbinder;

        public ViewHolder(View view) {
            mButterKnifeUnbinder = ButterKnife.bind(this, view);
        }

        public void unbind() {
            mButterKnifeUnbinder.unbind();
        }
    }
}

3 个答案:

答案 0 :(得分:1)

不确定为什么要这样做,但现在是:

class ViewHolder {
    @BindView(R.id.book_title) TextView bookTitle;
    @BindView(R.id.book_authors) TextView bookAuthors;

    private Unbinder mButterKnifeUnbinder;

    public ViewHolder(View view) {
        mButterKnifeUnbinder = ButterKnife.bind(this, view);
    }

    @OnClick (R.id.book_title)
    public void onBookTitleClicked(TextView v) {
        // this should work
    }

    public void unbind() {
        if(mButterKnifeUnbinder != null) {
            mButterKnifeUnbinder.unbind();
        }
    }
}

注意:您不应在unbind()方法上致电onDestroy()。对于Fragmentunbind()应调用onDestroyView()

@Override
public void onDestroyView() {
    super.onDestroyView();

    if(mViewHolder != null) {
        mViewHolder.unbind();
    }
}

答案 1 :(得分:0)

根据我的问题,ViewHolder的目的只是保存视图引用,而不是访问片段变量。所以我猜onClick事件应该以某种方式重定向到片段。这可以通过以下方式完成:

public class BookDetailFragment extends Fragment {

    private ViewHolder mViewHolder;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View mFragmentView = inflater.inflate(R.layout.book_detail_view, container, false);

        // Binding view holder
        mViewHolder = new ViewHolder(this, mFragmentView);

        return mFragmentView;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        mViewHolder.unbind();
    }

    public void onEditButtonClicked(TextView v) {
        // On click event comes into here
    }

    public void onDeleteButtonClicked(TextView v) {
        // On click event comes into here
    }

    static class ViewHolder {
        @BindView(R.id.book_title) TextView bookTitle;
        @BindView(R.id.book_authors) TextView bookAuthors;

        private Unbinder mButterKnifeUnbinder;

        private BookDetailFragment mFragment;

        public ViewHolder(BookDetailFragment fragment, View view) {
            mFragment = fragment;
            mButterKnifeUnbinder = ButterKnife.bind(this, view);
        }

        public void unbind() {
            mButterKnifeUnbinder.unbind();
        }

        @OnClick (R.id.edit_button)
        public void onEditButtonClicked(TextView v) {
            mFragment.onEditButtonClicked(v);
        }

        @OnClick (R.id.delete_button)
        public void onDeleteButtonClicked(TextView v) {
            mFragment.onDeleteButtonClicked(v);
        }
    }
}

答案 2 :(得分:0)

尝试保留这样的方法,删除公共参数(ButterKnife&#34中的方法OnClick;不喜欢"参数:) ):

#send our spreadsheet
from __future__ import print_function
import httplib2
import os

from apiclient import discovery
from apiclient import errors
from googleapiclient import http
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage
from apiclient.http import MediaIoBaseDownload
import io

import mimetypes 
from email import encoders
from email.message import Message
from email.mime.audio import MIMEAudio
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import base64

def create_message_with_attachment(
    sender, to, subject, message_text, file):
  """Create a message for an email.

  Args:
    sender: Email address of the sender.
    to: Email address of the receiver.
    subject: The subject of the email message.
    message_text: The text of the email message.
    file: The path to the file to be attached.

  Returns:
    An object containing a base64url encoded email object.
  """
  message = MIMEMultipart()
  message['to'] = to
  message['from'] = sender
  message['subject'] = subject

  msg = MIMEText(message_text)
  message.attach(msg)

  content_type, encoding = mimetypes.guess_type(file)

  if content_type is None or encoding is not None:
    content_type = 'application/octet-stream'
  main_type, sub_type = content_type.split('/', 1)
  fp = open(file, 'rb')
  msg = MIMEBase(main_type, sub_type)
  msg.set_payload(fp.read())
  fp.close()
  filename = os.path.basename(file)
  msg.add_header('Content-Disposition', 'attachment', filename=filename)
  message.attach(msg)

  return {'raw': base64.urlsafe_b64encode(message.as_string())}
  #return {'raw': base64.urlsafe_b64encode(message.as_bytes())}


def send_message(service, user_id, message):
  """Send an email message.

  Args:
    service: Authorized Gmail API service instance.
    user_id: User's email address. The special value "me"
    can be used to indicate the authenticated user.
    message: Message to be sent.

  Returns:
    Sent Message.
  """
  try:
    message = (service.users().messages().send(userId=user_id, body=message)
               .execute())
    print('Message Id: %s' % message['id'])
    return message
  except errors.HttpError as error:
    print('An error occurred: %s' % error)

def main(mail_service,spreadsheetId,new_invoice_filename):
    print('We are emailing the spreadsheet.')
    sender = 'me'
    to = 'me'
    subject = 'test '+new_filename
    message_text = 'Hi sdf \n P '
    attachment = 'D:/My Documents/file.pdf'
    msg = create_message_with_attachment(sender, to, subject, message_text, attachment)

    send_message(mail_service, sender, msg)