Кнопки Xamarin Recyclerview В CardView не могут получить позицию - PullRequest
0 голосов
/ 13 июня 2018

У меня есть большая проблема (для меня, я надеюсь, что вы лучше в Xamarin;))

У меня есть Recyclerview и адаптер Как в примере с Xamarin, так что теперь в новом Projekt мне нужно в2. Кнопки CardView, одна для +, а другая -, я заставлял обе кнопки работать, но не очень хорошо, потому что много раз + не делает правильного действия с неправильным CardView.

Спросите меняесли вам нужно больше ввода, я просто запутался: /

Это мой код:

BelPOSAdapter.cs:

public ArtikelDaten(string BELidxRAW, string Mandant)
    {
        BELIdx = BELidxRAW;

        List<.....> WWSVCconnections = Utils.Init(Mandant);

        foreach (..... in WWSVCconnections)
        {
            ..../hier is something that gives me the Json.

            string WWbelPosResp = getRes.Content;

            //JSON in Foreach
            mBuiltInPOS.Clear();
            dynamic dynPOSJson = JsonConvert.DeserializeObject(WWbelPosResp);
            foreach (var POSitem in dynPOSJson["POSITIONSLISTE"]["POSITION"])
            {
                mBuiltInPOS.Add(new Artikel
                {
                    //Info, KEINE anzeige
                    mARTBELart = POSitem["POS_2_1"].ToString(),
                    mARTBELnr = POSitem["POS_3_8"].ToString(),

                    //Anzeige
                    mARTBELlfdnr = POSitem["POS_11_6"].ToString(),

                    mARTnr = POSitem["POS_18_25"].ToString(),
                    mARTbezeichnung = POSitem["POS_45_60"].ToString(),
                    mARTretourMenge = "0",
                    mARTmenge = POSitem["POS_164_8"].ToString(),
                    mARTeinheit = " " + POSitem["POS_689_5"].ToString()
                });
            }
        }

        mArtikel = mBuiltInPOS.ToArray();

ScanPositionenActivity.cs:

 public class POSViewHolder : RecyclerView.ViewHolder
    {
        //1public ImageView Image { get; private set; }
        public TextView ARTnr { get; private set; }
        public TextView ARTbezeichnung { get; private set; }
        public TextView ARTmenge { get; private set; }
        public TextView ARTretourMenge { get; private set; }

        public TextView ARTBELnr { get; private set; }
        public TextView ARTBELart { get; private set; }
        public ImageButton ARTminus { get; set; }
        public ImageButton ARTplus { get; set; }
        public TextView ARTBELlfdnr { get; private set; }

        // Get references to the views defined in the CardView layout.
        //public POSViewHolder(View itemView, Action<int> listener) : base(itemView)
        public POSViewHolder(View itemView, Action<int> listener) : base(itemView)
        {


            // Locate and cache view references:
            //1Image = itemView.FindViewById<ImageView>(Resource.Id.imageView);
            ARTnr = itemView.FindViewById<TextView>(Resource.Id.LBLartNr);
            ARTbezeichnung = itemView.FindViewById<TextView>(Resource.Id.LBLartBezeichnung);
            ARTmenge = itemView.FindViewById<TextView>(Resource.Id.LBLartMenge);
            ARTretourMenge = itemView.FindViewById<TextView>(Resource.Id.LBLretourMenge);


            ARTBELnr = itemView.FindViewById<TextView>(Resource.Id.LBL_kommission_belnr);
            ARTBELart = itemView.FindViewById<TextView>(Resource.Id.LBL_kommission_belart);
            ARTBELlfdnr = itemView.FindViewById<TextView>(Resource.Id.LBL_kommission_POSlfdnr);

            // Detect user clicks on the item view and report which item
            // was clicked (by layout position) to the listener:
            itemView.Click += (sender, e) => listener(base.LayoutPosition);
        }
    }

    //----------------------------------------------------------------------
    // ADAPTER

    // Adapter to connect the data set (photo album) to the RecyclerView: 
    public class PhotoAlbumAdapter : RecyclerView.Adapter
    {
        // Event handler for item clicks:
        public event EventHandler<int> ItemClick;

        // Underlying data set (a photo album):
        public ArtikelDaten mPOSdaten;

        // Load the adapter with the data set (photo album) at construction time:
        public PhotoAlbumAdapter(ArtikelDaten photoAlbum)
        {
            mPOSdaten = photoAlbum;
        }

        // Create a new photo CardView (invoked by the layout manager): 
        public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
        {
            // Inflate the CardView for the photo:
            View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.BelPOSview, parent, false);


            ImageButton BTNminus = itemView.FindViewById<ImageButton>(Resource.Id.BTNminus);
            ImageButton BTNplus = itemView.FindViewById<ImageButton>(Resource.Id.BTNplus);
            // Create a ViewHolder to find and hold these view references, and 
            // register OnClick with the view holder:

            //POSViewHolder vh = new POSViewHolder(itemView, OnClick);

            POSViewHolder vh = new POSViewHolder(itemView, OnClick) { ARTminus = BTNminus, ARTplus = BTNplus};

            return vh;
        }

        // Fill in the contents of the photo card (invoked by the layout manager):
        public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
        {
            POSViewHolder vh = holder as POSViewHolder;

            // Set the ImageView and TextView in this ViewHolder's CardView 
            // from this position in the photo album:
            //1vh.Image.SetImageResource(mPOSdaten[position].PhotoID);
            vh.ARTnr.Text = mPOSdaten[position].mARTnr;
            vh.ARTbezeichnung.Text = mPOSdaten[position].mARTbezeichnung;
            vh.ARTmenge.Text = mPOSdaten[position].mARTmenge;
            vh.ARTretourMenge.Text = mPOSdaten[position].mARTretourMenge;

            vh.ARTBELnr.Text = mPOSdaten[position].mARTBELnr;
            vh.ARTBELart.Text = mPOSdaten[position].mARTBELart;
            vh.ARTBELlfdnr.Text = mPOSdaten[position].mARTBELlfdnr;

            //RECYCLEVIEW Buttons
            vh.ARTplus.Click -= BTNplus_Click;
            vh.ARTplus.Click += BTNplus_Click;

            vh.ARTminus.Click -= BTNminus_Click;
            vh.ARTminus.Click += BTNminus_Click;
        }

        private void BTNplus_Click(object sender, EventArgs e)
        {
            //int position = this.RecyclerView.GetChildAdapterPosition((View)sender);
            //Toast.MakeText(mContext, vh.ARTretourMenge.Text, ToastLength.Short).Show();
            mPOSdaten[position].mARTretourMenge = (Convert.ToInt32(mPOSdaten[position].mARTretourMenge) + 1).ToString();
            NotifyItemChanged(position);
        }

        private void BTNminus_Click(object sender, EventArgs e)
        {
            if (mPOSdaten[position].mARTretourMenge != "0")
            {
                //Toast.MakeText(mContext, vh.ARTretourMenge.Text, ToastLength.Short).Show();
                mPOSdaten[position].mARTretourMenge = (Convert.ToInt32(mPOSdaten[position].mARTretourMenge) - 1).ToString();
                NotifyItemChanged(position);
            }
        }

Итак, в OnBindViewHolder у меня есть мои кнопки, которые выполняют функцию, когда они нажимаются, и это работает неплохо, но мне нужно положение CardView / Data, я читал, что могу выяснить это с помощью int position = this.RecyclerView.GetChildAdapterPosition((View)sender);но это не работает, я не знаю, как это работает.

1 Ответ

0 голосов
/ 13 июня 2018

RecyclerView.ViewHolder имеет два интересных свойства:

  • LayoutPosition: дает вам позицию в макете.Полезно, если вы делаете такие вещи, как перетаскивание, или вы переупорядочиваете строки на экране.
  • AdapterPosition: дает вам положение в адаптере.Обычно это отражает позицию в источнике данных, который вы используете в своем адаптере.

Поскольку объект sender, вероятно, просто даст вам кнопку с событием click, тогда вам как-то нужнополучить ViewHolder.

Одним из способов может быть добавление экземпляра RecyclerView.ViewHolder к свойству Tag View.Альтернативным способом было бы то, что сам RecyclerView.ViewHolder имел события для кнопок минус и плюс.Я лично предпочел бы последнее.

public class POSViewHolder : RecyclerView.ViewHolder
{
    public event EventHandler MinusClick;
    public event EventHandler PlusClick;

    public TextView ARTnr { get; private set; }
    public TextView ARTbezeichnung { get; private set; }
    public TextView ARTmenge { get; private set; }
    public TextView ARTretourMenge { get; private set; }

    public TextView ARTBELnr { get; private set; }
    public TextView ARTBELart { get; private set; }
    public ImageButton ARTminus { get; set; }
    public ImageButton ARTplus { get; set; }
    public TextView ARTBELlfdnr { get; private set; }

    public POSViewHolder(View itemView) : base(itemView)
    {
        ...

        ARTminus.Click += OnMinusClick;
        Artplus.Click += OnPlusClick;
    }

    private void OnMinusClick(object s, EventArgs e)
    {
        MinusClick?.Invoke(this, EventArgs.Empty);
    }

    private void OnPlusClick(object s, EventArgs e)
    {
        PlusClick?.Invoke(this, EventArgs.Empty);
    }
}

Затем в вашем адаптере, когда вы связываете ViewHolder:

var vh = holder as POSViewHolder;
vh.MinusClick += MinusClick;
vh.PlusClick += PlusClick;

private void MinusClick(object sender, EventArgs e)
{
    if (sender is RecyclerView.ViewHolder holder)
    {
        var position = holder.AdapterPosition;
        // do other stuff...
    }
}
...