Xamarin从OnClick事件传递上下文

时间:2016-02-21 02:57:50

标签: c# android xamarin xamarin.android

我是android dev的初学者,我正在努力将字符串Clicked_Message从Recycle Adapter Class中的Click事件传递到另一个活动。这是使用Intent的好方法吗?如果是这样,我如何将上下文传递给click事件?感谢

public class RecyclerAdapter : RecyclerView.Adapter
         {
            private RecyclerView mRecyclerView;
            private List<NotificationClass> mEmails;

            public RecyclerAdapter(List<NotificationClass> emails, RecyclerView recyclerView)
            {
                mEmails = emails;
                mRecyclerView = recyclerView;
            }
            public class MyView : RecyclerView.ViewHolder
            {
                public View mMainView { get; set; }
                public TextView mName { get; set; }
                public TextView mSubject { get; set; }
                public TextView mMessage { get; set; }
                public MyView(View view) : base(view)
                {
                    mMainView = view;
                }
            }
            public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
            {
                View row = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.row, parent, false);
                TextView txtName = row.FindViewById<TextView>(Resource.Id.txtName);
                TextView txtSubject = row.FindViewById<TextView>(Resource.Id.txtSubject);
                TextView txtMessage = row.FindViewById<TextView>(Resource.Id.txtMessage);
                MyView view = new MyView(row) { mName = txtName, mSubject = txtSubject, mMessage = txtMessage };
                return view;
            }
            public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
            {

                MyView myHolder = holder as MyView;
                int indexPosition = (mEmails.Count - 1) - position;
                myHolder.mMainView.Click += mMainView_Click;
                myHolder.mName.Text = mEmails[position].Name;
                myHolder.mSubject.Text = mEmails[position].Subject;
                myHolder.mMessage.Text = mEmails[position].Message;
            }
            public override int ItemCount
            {
                get { return mEmails.Count; }
            }
            public void OnClick(int position)
            {
                if (ItemClick != null)
                    ItemClick(this, position);
            }
            public void mMainView_Click(object sender, EventArgs e,Context context)
            {
                int position = mRecyclerView.GetChildPosition((View)sender);
                int indexPosition = (mEmails.Count - 1) - position;
                Console.WriteLine(mEmails[indexPosition].Message);
                string Clicked_Message = (mEmails[indexPosition].Message);

                var activity2 = new Intent(context, typeof(ContactActivity));
                activity2.PutExtra("MyData", Clicked_Message);
                context.StartActivity(activity2);
            }
        }

2 个答案:

答案 0 :(得分:0)

您无需传递上下文。只需使用intent并将您想要传递的信息作为额外内容放入intent中。

如果您的适配器需要上下文,请通过构造函数传递它并将其存储为字段成员。

答案 1 :(得分:0)

这是我带有视图持有者的RecyclerView.Adapter的典型实现......

public class ContactsAdapter : V7.RecyclerView.Adapter
{
    private List<Contact> _contacts;

    public event EventHandler ItemClick;
    public void OnItemClick(ContactViewHolder holder)
    {
        if (ItemClick != null)
        {
            ItemClick(holder, EventArgs.Empty);
        }
    }

    public ContactsAdapter(List<Contact> contacts)
        : base()
    {
        _contacts = contacts;
    }

    public override void OnBindViewHolder(V7.RecyclerView.ViewHolder holder, int position)
    {
        var contactHolder = (ContactViewHolder)holder;
        contactHolder.BindUI(_contacts[position]);
    }

    public override V7.RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
    {
        var view = LayoutInflater.FromContext(parent.Context).Inflate(Resource.Layout.ContactsListItem, parent, false);
        return new ContactViewHolder(view)
        {
            Adapter = this
        };
    }

    public override int ItemCount
    {
        get
        {
            return _contacts.Count;
        }
    }
}

查看持有人(通常与适配器位于同一文件中)

public class ContactViewHolder : V7.RecyclerView.ViewHolder, View.IOnClickListener
{
    public TextView ContactNameTextView { get; set; }
    public TextView ContactPhoneTextView { get; set; }
    public TextView ContactIntialsTextView { get; set; }

    public Contact Contact { get; set; }

    private WeakReference _adapter;
    public ContactsAdapter Adapter
    {
        get { return (ContactsAdapter)_adapter.Target; }
        set { _adapter = new WeakReference(value); }
    }

    public ContactViewHolder(View view)
        : base(view)
    {
        GetUI(view);
        view.SetOnClickListener(this);
    }

    private void GetUI(View view)
    {
        ContactNameTextView = view.FindViewById<TextView>(Resource.Id.ContactName);
        ContactPhoneTextView = view.FindViewById<TextView>(Resource.Id.ContactPhone);
        ContactIntialsTextView = view.FindViewById<TextView>(Resource.Id.ContactInitialsTextView);
    }

    public void BindUI(Contact contact)
    {
        Contact = contact;

        ContactNameTextView.Text = contact.ContactName;
        ContactPhoneTextView.Text = contact.Phone1;
        ContactIntialsTextView.Text = contact.Initials;
    }

    public void OnClick(View v)
    {
        Adapter.OnItemClick(this);
    }
}

这将功能封装到视图持有者。我还将适配器的实例作为WeakReference提供给视图持有者。这允许我调用OnItemClick,传递视图持有者的实例。如果您将注意到视图持有者也有一个它所代表的对象的实例。这意味着我不必担心所选的索引。我已经有了对象数据。

所以Activity / Fragment中的实现是这样的......

public override void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);

    _contacts = Contact.GetAllContacts();

    _adapter = new ContactsAdapter(_contacts);
    _adapter.ItemClick += ContactSelected;
}

public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    var view = inflater.Inflate(Resource.Layout.ContactsFragment, container, false);

    var layoutManager = new V7.LinearLayoutManager(this.Activity) { Orientation = V7.LinearLayoutManager.Vertical };

    _contactsView = view.FindViewById<V7.RecyclerView>(Resource.Id.ContactList);
    _contactsView.SetAdapter(_adapter);
    _contactsView.HasFixedSize = true;
    _contactsView.SetLayoutManager(layoutManager);

    return view;
}

private void ContactSelected (object sender, EventArgs e)
{
    var holder = (ContactViewHolder)sender;
    var detailFragment = new ContactDetailsFragment(holder.Contact);
    MainActivity.ShowFragment(detailFragment);
}

我将联系人提供给片段,但您可以使用意图为活动执行类似操作。

现在,我不知道这是否是处理RecyclerView中一行点击的最有效方法。但是这个实现对我来说很有用。