Xamarin Android:在删除滑动前发出警报

问题描述 投票:0回答:1

大家好,我叫谷口

我实现了一个recyclerview,并在其中插入了滑动回调,这种情况下该滑动用于删除。

我想在删除之前插入警报以防止用户误删除

我已尝试实施警报,但出现以下错误:

Java.Lang.NullPointerException:'试图在空对象引用上调用虚拟方法'android.content.res.Resources $ Theme android.content.Context.getTheme()'

我的滑动回叫:

public class SwipeToDeleteCallback : ItemTouchHelper.SimpleCallback
{
    private View v;
    private List<Email> mEmails;
    private Context context;
    private RecyclerAdapter mdapter;
    private Android.Graphics.Drawables.Drawable deleteIcon;
    private int intrinsicWidth;
    private int intrinsicHeight;
    private Android.Graphics.Drawables.ColorDrawable background;
    private Color backgroundColor;
    private Paint clearPaint;

    public SwipeToDeleteCallback(int dragDirs, int swipeDirs, Context context, RecyclerAdapter mRecyclerView, List<Email> emails) : this(dragDirs, swipeDirs, context)
    {
        this.context = context;
        this.mdapter = mRecyclerView;
        deleteIcon = ContextCompat.GetDrawable(context, Resource.Drawable.alter_delete);
        intrinsicWidth = deleteIcon.IntrinsicWidth;
        intrinsicHeight = deleteIcon.IntrinsicHeight;
        background = new Android.Graphics.Drawables.ColorDrawable();
        backgroundColor = Color.ParseColor("#f44336");
        clearPaint = new Paint();
        emails = mEmails;
        clearPaint.SetXfermode(new PorterDuffXfermode(PorterDuff.Mode.Clear));
    }



    public SwipeToDeleteCallback(int dragDirs, int swipeDirs, Context context) : base(dragDirs, swipeDirs)
    {
        this.context = context;
    }

    public override int GetMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)
    {
        if (viewHolder.AdapterPosition == 10)
        {
            return 0;
        }

        return base.GetMovementFlags(recyclerView, viewHolder);
    }

    public override void OnChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, bool isCurrentlyActive)
    {
        base.OnChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
    }

    public override bool OnMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target)
    {
        //throw new NotImplementedException();
        return false;
    }

    public override void OnChildDrawOver(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, bool isCurrentlyActive)
    {
        var itemView = viewHolder.ItemView;
        var itemHeight = itemView.Bottom - itemView.Top;
        var isCanceled = dX == 0f && !isCurrentlyActive;

        if (isCanceled)
        {
            clearCanvas(c, itemView.Right + dX, (float)itemView.Top, (float)itemView.Right, (float)itemView.Bottom);
            base.OnChildDrawOver(c, recyclerView
                , viewHolder, dX, dY, actionState, isCurrentlyActive);
            return;
        }
        background.Color = backgroundColor;
        background.SetBounds(itemView.Right + (int)dX, itemView.Top, itemView.Right, itemView.Bottom);
        background.Draw(c);

        var deleteIconTop = itemView.Top + (itemHeight - intrinsicHeight) / 2;
        var deleteIconMargin = (itemHeight - intrinsicHeight) / 2;
        var deleteIconLeft = itemView.Right - deleteIconMargin - intrinsicWidth;
        var deleteIconRight = itemView.Right - deleteIconMargin;
        var deleteIconBottom = deleteIconTop + intrinsicHeight;

        deleteIcon.SetBounds(deleteIconLeft, deleteIconTop, deleteIconRight, deleteIconBottom);
        deleteIcon.Draw(c);

        base.OnChildDrawOver(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
    }

    private void clearCanvas(Canvas c, float v, float top, float right, float bottom)
    {
        c.DrawRect(v, top, right, bottom, clearPaint);
    }

    public override void OnSwiped(RecyclerView.ViewHolder viewHolder, int direction)
    {

        mdapter.RemoveItem(viewHolder.AdapterPosition);

    }

    public override void ClearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)
    {
        base.ClearView(recyclerView, viewHolder);
    }
}

我的recyclerview适配器:

 public class RecyclerAdapter : RecyclerView.Adapter
{

    private Activity mActivity;
    private List<Email> mEmails;
    private SwipeToDeleteCallback swipeToDeleteCallback;
    private Context context;

    public RecyclerAdapter(List<Email> emails, Context context)
    {
        mEmails = emails;
        this.context = context;
    }

    public RecyclerAdapter(List<Email> emails, Activity activity)
    {
        mEmails = emails;
        mActivity = activity;
    }

    public RecyclerAdapter(List<Email> mEmails, SwipeToDeleteCallback swipeToDeleteCallback)
    {

        this.mEmails = mEmails;
        this.swipeToDeleteCallback = swipeToDeleteCallback;

    }


    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 int ItemCount
    {
        get { return mEmails.Count; }
    }

    public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
    {

        View row = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.row, parent, false);
        RecyclerViewHolder view = new RecyclerViewHolder(row);
        return view;


    }
    public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
    {

        RecyclerViewHolder myHolder = holder as RecyclerViewHolder;
        myHolder.mDate.Text = ((Email)mEmails[position]).date;
        myHolder.mSubject.Text = ((Email)mEmails[position]).Subject;
        myHolder.mMessage.Text = ((Email)mEmails[position]).Message;

    }

    public void RemoveItem(int position)
    {
        Android.App.AlertDialog.Builder dialog = new AlertDialog.Builder(context);
        AlertDialog alert = dialog.Create();
        alert.SetTitle("Atenion");
        alert.SetMessage("About to delete a row permanently, do you want to proceed ?");
        alert.SetButton("OK", (c, ev) =>
        {
            mEmails.RemoveAt(position);
            NotifyDataSetChanged();
            NotifyItemChanged(position);
        });
        alert.SetButton2("CANCEL", (c, ev) => { });
        alert.Show();

    }

}   

我在哪里调用recyclerview并滑动:

 public class MainActivity : AppCompatActivity
{
    public static RecyclerView mRecyclerView;
    public static RecyclerView.LayoutManager mLayoutManager;
    public RecyclerView.ViewHolder holder;
    public static BottomNavigationView bottomnavigationview1;
    public static RecyclerView.Adapter mAdapter;
    public static List<Email> mEmails;

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        Xamarin.Essentials.Platform.Init(this, bundle);
        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.activity_main);

        mRecyclerView = FindViewById<RecyclerView>(Resource.Id.recyclerViwer);
        mRecyclerView.AddItemDecoration(new DividerItemDecoration(mRecyclerView.Context, DividerItemDecoration.Vertical));
        mRecyclerView.HasFixedSize = true;
        SetupList();

        //Create our layout Manager
        mLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.SetLayoutManager(mLayoutManager);
        RecyclerAdapter mAdapter = new RecyclerAdapter(mEmails, this);
        mRecyclerView.SetAdapter(mAdapter);

        var swipeHandler = new SwipeToDeleteCallback(0, ItemTouchHelper.Left, this, mAdapter, mEmails);
        var itemTouchHelper = new ItemTouchHelper(swipeHandler);
        itemTouchHelper.AttachToRecyclerView(mRecyclerView);

    }

    private void SetupList()
    {
        mEmails = new List<Email>();
        mEmails.Add(new Email() { date = "9/25/2019", Subject = "Wanna Hang Out?", Message = "I ' ll   be around  tomorrow!!" });
        mEmails.Add(new Email() { date = "9/25/2019", Subject = "Wanna Hang Out?", Message = "I ' ll   be around  tomorrow!!" });
        mEmails.Add(new Email() { date = "9/25/2019", Subject = "Wanna Hang Out?", Message = "I ' ll   be around  tomorrow!!" });
        mEmails.Add(new Email() { date = "9/24/2019", Subject = "Wanna Hang Out?", Message = "I ' ll   be around  tomorrow!!" });
        mEmails.Add(new Email() { date = "9/24/2019", Subject = "Wanna Hang Out?", Message = "I ' ll   be around  tomorrow!!" });
    }

该行中发生错误:

Android.App.AlertDialog.Builder dialog = new AlertDialog.Builder(context);
c# xamarin.android
1个回答
0
投票

[创建RecyclerAdapter时,实际上您没有传递Context类型的对象,而是Activity。因此context字段确实为空。

下面的这一行:

RecyclerAdapter mAdapter = new RecyclerAdapter(mEmails, this);

实际上称为此构造函数:

public RecyclerAdapter(List<Email> emails, Activity activity)
{
    mEmails = emails;
    mActivity = activity;
}

我建议您稍微清理一下RecyclerAdapter类,因为您甚至都没有使用mActivity字段,也许像下面这样:

public class RecyclerAdapter : RecyclerView.Adapter
{
    private List<Email> mEmails;
    private Context mContext;

    public RecyclerAdapter(List<Email> emails, Context context)
    {
        mEmails = emails;
        mContext = context;
    }

    public override int ItemCount => mEmails.Count;

    public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
    {

        View row = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.row, parent, false);
        RecyclerViewHolder view = new RecyclerViewHolder(row);
        return view;
    }
    public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
    {

        RecyclerViewHolder myHolder = holder as RecyclerViewHolder;
        myHolder.mDate.Text = ((Email)mEmails[position]).date;
        myHolder.mSubject.Text = ((Email)mEmails[position]).Subject;
        myHolder.mMessage.Text = ((Email)mEmails[position]).Message;

    }

    public void RemoveItem(int position)
    {
        //Pass mActivity as an argument here instead of the context field like before.
        Android.App.AlertDialog.Builder dialog = new AlertDialog.Builder(mActivity);
        AlertDialog alert = dialog.Create();
        alert.SetTitle("Atenion");
        alert.SetMessage("About to delete a row permanently, do you want to proceed ?");
        alert.SetButton("OK", (c, ev) =>
        {
            mEmails.RemoveAt(position);
            NotifyDataSetChanged();
            NotifyItemChanged(position);
        });
        alert.SetButton2("CANCEL", (c, ev) => { });
        alert.Show();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.