Takudzwa Mawarire Takudzwa Mawarire -3 years ago 179
C# Question

Xamarin.Android Recyclerview Item Click Listener not working

Recyclerview Item Click not working. Below is the code for my adaptor and ViewHolder.I followed the pattern from a tutorial on the xamarin documentation available here

public class MainMenuRecyclerAdapter : RecyclerView.Adapter
{
private readonly IList<ListMenuItem> items;



public MainMenuRecyclerAdapter(IList<ListMenuItem> data)
{
items = data;
}

public override int ItemCount => items.Count;
public event EventHandler<ClickEventArgs> ItemClick;
public event EventHandler<ClickEventArgs> ItemLongClick;

/// <summary>
/// Create new views (invoked by the layout manager)
/// </summary>
/// <param name="parent"></param>
/// <param name="viewType"></param>
/// <returns></returns>
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
//Setup your layout here
const int id = Resource.Layout.MenuList;

MainMenuRecyclerAdapterViewHolder vh;

View itemView;
using (itemView = LayoutInflater.From(parent.Context).Inflate(id, parent, false))
{
vh = new MainMenuRecyclerAdapterViewHolder(itemView, OnClick, OnLongClick);
}
return vh;
}


/// <summary>
/// Replace the contents of a view (invoked by the layout manager)
/// </summary>
/// <param name="viewHolder"></param>
/// <param name="position"></param>
public override void OnBindViewHolder(RecyclerView.ViewHolder viewHolder, int position)
{
var item = items[position];
// Replace the contents of the view with that element
var holder = viewHolder as MainMenuRecyclerAdapterViewHolder;
if (holder == null) return;
holder.mnuHeader.Text = item.MenuHeader;

holder.mnuDescription.Text = item.MenuDetails;

switch (item.MenuKey)
{
case "CreateNew":
holder.mnuIcon.SetImageResource(Resource.Drawable.createrecord);
break;
case "ViewRecords":
holder.mnuIcon.SetImageResource(Resource.Drawable.vieweditrecord);
break;
case "SNR":
holder.mnuIcon.SetImageResource(Resource.Drawable.keyinformantsubmissions);
break;
case "SNRLog":
holder.mnuIcon.SetImageResource(Resource.Drawable.taskchecklist);
break;
case "AnalysisView":
holder.mnuIcon.SetImageResource(Resource.Drawable.viewprogressreport);
break;
case "SendUpdates":
holder.mnuIcon.SetImageResource(Resource.Drawable.syncwithserver);
break;
case "DeviceStatus":
holder.mnuIcon.SetImageResource(Resource.Drawable.devicestatus);
break;
case "SystemSettings":
holder.mnuIcon.SetImageResource(Resource.Drawable.settings);
if (item.MenuDetails.Contains("Harare") && item.MenuKey == "SystemSettings")
{
holder.mnuDescription.SetTextColor(Color.Green);
holder.mnuDescription.Text += " - TRAINING MODE";
}
if (!item.MenuDetails.Contains("Harare"))
{
holder.mnuDescription.SetTextColor(Color.Red);
holder.mnuDescription.Text += " - VBCI MODE";
}
break;
case "DBSettings":
holder.mnuIcon.SetImageResource(Resource.Drawable.database);
break;
default:
holder.mnuIcon.SetImageResource(Resource.Drawable.addbutton);
break;
}

}

private void OnClick(ClickEventArgs args)
{
ItemClick?.Invoke(this, args);
}


private void OnLongClick(ClickEventArgs args)
{
ItemLongClick?.Invoke(this, args);
}
}

public class MainMenuRecyclerAdapterViewHolder : RecyclerView.ViewHolder
{
public TextView mnuDescription;
public TextView mnuHeader;
public ImageView mnuIcon;


public MainMenuRecyclerAdapterViewHolder(View itemView, Action<ClickEventArgs> clickListener,Action<ClickEventArgs> longClickListener) : base(itemView)
{
mnuHeader = itemView.FindViewById<TextView>(Resource.Id.txtMenuHeader);
mnuDescription = itemView.FindViewById<TextView>(Resource.Id.txtMenuDetail);
mnuIcon = itemView.FindViewById<ImageView>(Resource.Id.imgMenuIcon);

itemView.Click += (sender, e) => clickListener(
new ClickEventArgs { View = itemView, Position = AdapterPosition });

itemView.LongClick +=(sender, e) => longClickListener(
new ClickEventArgs { View = itemView, Position = AdapterPosition });
}

}

public class ClickEventArgs : EventArgs
{
public View View { get; set; }
public int Position { get; set; }
}


My Activity Code

private void InitRecyclerView() {
try
{
SetContentView(Resource.Layout.MainLayout);

LoadMenuItems();

dbPath = CheckDB();

var toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);

toolbar.SetPadding(0, GetStatusBarHeight(), 0, 0);

//Using the new recycler view
recyclerView = FindViewById<RecyclerView>(Resource.Id.recycleView);

recyclerView.SetLayoutManager(new LinearLayoutManager(this));

mainMenuRecyclerAdapter = new MainMenuRecyclerAdapter(lstMnu);

mainMenuRecyclerAdapter.ItemClick += RecyclerOnItemClick;

recyclerView.SetAdapter(mainMenuRecyclerAdapter);
}
catch (Exception ex)
{
new AlertDialog.Builder(this)
.SetTitle("Homescreen - InitRecyclerView()")
.SetMessage("Error Occurred: " + ex.Message)
.SetPositiveButton("Ok", delegate { })
.Show();
}}


My XAML Code

<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"><android.support.design.widget.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="180dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:fitsSystemWindows="true">

<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsingToolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:fitsSystemWindows="true"
app:contentScrim="@android:color/white"
app:expandedTitleMarginStart="48dp"
app:expandedTitleMarginEnd="64dp">
<ImageView
android:src="@drawable/RwimsHomeScreen"
android:id="@+id/imageView1"
android:layout_width="match_parent"
android:layout_height="180dp"
android:scaleType="fitCenter"
android:fitsSystemWindows="true"
app:layout_collapseMode="parallax"
android:background="@android:color/white"/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_collapseMode="pin" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>

<android.support.v7.widget.RecyclerView
android:layout_height="match_parent"
android:layout_width="match_parent"
android:id="@+id/recycleView"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
</android.support.v7.widget.RecyclerView>

<android.support.design.widget.FloatingActionButton
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_margin="@dimen/fab_margin"
android:src="@drawable/ic_date_range_white_48dp"
app:layout_anchor="@id/appBar"
app:layout_anchorGravity="bottom|end" />
</android.support.design.widget.CoordinatorLayout>


The
InitRecyclerView()
function is what i call on the Activity OnCreateView method. My Item Click method basically looks like this:

private void RecyclerOnItemClick(object sender, ClickEventArgs e)
{

var vibrator = (Vibrator)GetSystemService(VibratorService);
vibrator.Vibrate(60);

switch (lstMnu[e.Position].MenuKey)
{
case "CreateNew":
var intentCW = new Intent(this, typeof(ActFormSelectionMenu));
intentCW.PutExtra("CreateNew", "true");
StartActivity(intentCW);
break;
case "ViewRecords":
var intentVw = new Intent(this, typeof(ActFormSelectionMenu));
intentVw.PutExtra("CreateNew", "false");
StartActivity(intentVw);
break;
default:
Log.Debug("EmptyMenu", "---");
break;
}
}


MenuKey
is a property of the
ListMenuItem
object which basically contains other properties like description, header e.t.c.The
lstMnu
variable is initialized and loaded (by another method)before the recyclerview is initialized.
I can't figure out what's wrong with the code but somehow the recyclerview is not responding to the click event.If i change the recyclerview to use a list view, the menu is working perfectly. Help me out guys.

Answer Source

Recyclerview Item Click not working.

Actually it did, but it was happened in the RecyclerView.Adapter you have defined in OnResume method.

protected override void OnResume()
{
     base.OnResume();
     SetRecyclerAdaptor();
}

private void SetRecyclerAdaptor()
{
     mainMenuRecyclerAdapter = new MainMenuRecyclerAdapter(lstMenu);
     mainMenuRecyclerAdapter.ItemClick += (sender, e) =>
     {
          Toast.MakeText(this,"Click happened here!",ToastLength.Short).Show();
     };

     recyclerView.SetAdapter(mainMenuRecyclerAdapter);
}

Comment out the above code will solve your problem.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download