c# - CardView中的Xamarin Recyclerview按钮,无法获取位置
问题描述
我有一个大问题(对我来说,我希望你在 Xamarin 中做得更好;))
我有一个 Recyclerview 和一个像 Xamarin 示例一样的适配器,所以现在在新的 Projekt 中我需要 CardView 的 2. 一个用于 + 和另一个 - 的按钮,我让这两个按钮工作但不是很好,因为很多次+ 没有对错误的 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);
但那不起作用我不不知道它是如何工作的。
解决方案
RecyclerView.ViewHolder
有两个有趣的属性:
LayoutPosition
: 为您提供布局中的位置。如果您正在执行诸如拖放之类的操作,或者您正在对屏幕上的行进行重新排序,这很有用。AdapterPosition
: 为您提供适配器中的位置。这通常会反映您在适配器中使用的数据源中的位置。
由于该sender
对象可能只会为您提供具有单击事件的按钮,因此您需要以某种方式获取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...
}
}
推荐阅读
- python - 除轮廓外如何去除骨架线?
- html - R包rvest()工作,但没有给出填写HTML表单的结果
- node.js - 部署的 Heroku API 服务器显示与验证码相关的错误
- javascript - Chrome 扩展 - 在 chrome 页面上显示弹出窗口并在其他页面上注入 js
- node.js - 无法获取 /api
- ssl - 当我将 CloudFlare 用于我的 SSL 时,视频背景出现问题
- android - 我们可以创建在 Android TV、平板电脑和 Android 手机上运行的应用程序吗?
- terminal - 在 Jupyterlab 的终端中呈现的大字符间距
- python - 无法从 JSON 正确加载我的正则表达式
- javascript - 向每个屏幕 socket.io 显示不同的值