Android - getAdapterPosition() 在删除项目后返回 -1

2024-01-07

标题说明了一切,我有一个RecyclerView它用于动态存储值,但一次只能存储一项。该项目包含 3TextViews

当我正常添加所有项目时,它可以工作,但是当我添加 x 项目,然后删除最后一项,然后单击“提交”时,应用程序崩溃。

I do removeAt(getAdapterPosition()在视图持有者中,其中 `removeAt(int) 是:

private void removeAt(int removePosition){
    grosirList.product_grosir_list.remove(removePosition);
    notifyItemRemoved(removePosition);
}

并提交按钮:

promoConfirmBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Gson gson = new Gson();
                if (postProductPromoAdapter.getGrosirList() == null){

                } else {
                    String grosirAddJson = gson.toJson(postProductPromoAdapter.getGrosirList());

                    Intent intent = new Intent();
                    intent.putExtra("grosirPromoPrice", grosirAddJson);
                    intent.putExtra("promoPrice", promoPriceET.getText().toString());
                    setResult(RESULT_OK, intent);
                    finish();
                }
            }
        });

getGrosirList() is

    public GrosirAddList getGrosirList(){
        if (mAwesomeValidation.validate()){
            return this.grosirList;
        } else {
            return null;
        }
    }

基本上提交按钮验证TextViews如果通过验证,则返回 true。

这是错误发生的地方:

    minRangeET.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                }

                @Override
                public void afterTextChanged(Editable s) {
                    if(!s.toString().equals("")){
                        grosirList.product_grosir_list.get(getAdapterPosition()).grosir_min = String.valueOf(s);
                    } else {
                        grosirList.product_grosir_list.get(getAdapterPosition()).grosir_min = null; // Error happens here
                    }
                }
            });

我将用户的输入保存到适配器内的对象中,以便稍后通过TextWatcher

这是错误日志:

java.lang.ArrayIndexOutOfBoundsException: length=12; index=-1
at java.util.ArrayList.get(ArrayList.java:310)
at xx.PostProductPromoAdapter$FiturPromoHolder$1.afterTextChanged(PostProductPromoAdapter.java:236)
at android.widget.TextView.sendAfterTextChanged(TextView.java:7563)
at android.widget.TextView.setText(TextView.java:3920)
at android.widget.TextView.setText(TextView.java:3769)
at android.widget.EditText.setText(EditText.java:84)
at android.widget.TextView.setText(TextView.java:3744)
at com.basgeekball.awesomevalidation.helper.SpanHelper.setColor(SpanHelper.java:22)
at com.basgeekball.awesomevalidation.validators.ColorationValidator$1.execute(ColorationValidator.java:34)
at com.basgeekball.awesomevalidation.validators.Validator.checkFields(Validator.java:76)
at com.basgeekball.awesomevalidation.validators.ColorationValidator.trigger(ColorationValidator.java:25)
at com.basgeekball.awesomevalidation.AwesomeValidation.validate(AwesomeValidation.java:81)
at xx.getGrosirList(PostProductPromoAdapter.java:76)
at xx$3.onClick(PostProductPromoActivityRecycler.java:164)

更新 :

我用它来检查这些项目是否有效:

public boolean filledCheck(int itemNumber){
    return this.grosirList.product_grosir_list.size() > 0
            && this.grosirList.product_grosir_list.get(itemNumber - 1).grosir_price != null
            && this.grosirList.product_grosir_list.get(itemNumber - 1).grosir_max != null
            && this.grosirList.product_grosir_list.get(itemNumber - 1).grosir_min != null;
}

这将值添加到EditText。值是从用户输入中获取的TextWatcher

    if(grosirList.product_grosir_list.get(position).grosir_min == null) {
        ((FiturPromoHolder)holder).minRangeET.setText("");
    } else {
        ((FiturPromoHolder)holder).minRangeET.setText(grosirList.product_grosir_list.get(position).grosir_min);
    }

    if(grosirList.product_grosir_list.get(position).grosir_max == null) {
        ((FiturPromoHolder)holder).maxRangeET.setText("");
    } else {
        ((FiturPromoHolder)holder).maxRangeET.setText(grosirList.product_grosir_list.get(position).grosir_max);
    }

    if(grosirList.product_grosir_list.get(position).grosir_price == null) {
        ((FiturPromoHolder)holder).grossPriceET.setText("");
    } else {
        ((FiturPromoHolder)holder).grossPriceET.setText(grosirList.product_grosir_list.get(position).grosir_price);
    }

更新,这是整个适配器代码:

public boolean uploadProductLoading = true;

    private Context context;
    private AwesomeValidation mAwesomeValidation;

    public GrosirAddList grosirList = new GrosirAddList();

    private SharedPreferencesList sharedPreferencesList;
    private SharedPreferenceUtilities sharedPreferenceUtilities;
    private Utilities utilities;
    private UtilityUriHelper utilityUriHelper;

    // Allows to remember the last item shown on screen
    private int lastPosition = -1;


    // User information
    private String userIdString;
    private String userAliasString;
    private String userEmailString;
    private String loginSharedPrefsString;

    private String userId;
    private String userAlias;

    public PostProductPromoAdapter(Context context) {

        this.sharedPreferencesList = new SharedPreferencesList();
        this.sharedPreferenceUtilities = new SharedPreferenceUtilities();
        this.context = context;
        this.userIdString = sharedPreferencesList.userIDString;
        this.userAliasString = sharedPreferencesList.userAliasString;
        this.loginSharedPrefsString = sharedPreferencesList.loginSharedPreference;
        this.utilities = new Utilities();
        this.utilityUriHelper = new UtilityUriHelper();

        this.userId = sharedPreferenceUtilities.getValue(context, loginSharedPrefsString, userIdString);
        this.userAlias = sharedPreferenceUtilities.getValue(context, loginSharedPrefsString, userAliasString);
        this.mAwesomeValidation = new AwesomeValidation(ValidationStyle.COLORATION);
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View productView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.activity_marketplace_upload_produk_fitur_promo_card, parent, false);
        return new FiturPromoHolder(productView);
    }

    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {

        // Animation, disabled for now
//        setAnimation(holder.itemView, position);

        /*((FiturPromoHolder)holder).grossPriceDeleteBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                notifyItemRangeChanged(position, grosirList.product_grosir_list.size());
//                notifyDataSetChanged();
//                notifyItemRemoved(position);
//                notifyItemRangeChanged(position, grosirList.product_grosir_list.size());
            }
        });*/



        /*((FiturPromoHolder)holder).minRangeET.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                if(!s.toString().equals("")){
                    if (grosirList.product_grosir_list.size() != 0){
                        grosirList.product_grosir_list.get(position).grosir_min = String.valueOf(s);
                    }
                } else {
                    if (grosirList.product_grosir_list.size() != 0){
                        grosirList.product_grosir_list.get(position).grosir_min = null;
                    }
                }
            }
        });

        ((FiturPromoHolder)holder).maxRangeET.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                if (!s.toString().equals("")) {
                    if (grosirList.product_grosir_list.size() != 0){
                        grosirList.product_grosir_list.get(position).grosir_max = String.valueOf(s);
                    }
                } else {
                    if (grosirList.product_grosir_list.size() != 0){
                        grosirList.product_grosir_list.get(position).grosir_max = null;
                    }
                }
            }
        });

        ((FiturPromoHolder)holder).grossPriceET.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                if (!s.toString().equals("")) {
                    if (grosirList.product_grosir_list.size() != 0){
                        grosirList.product_grosir_list.get(position).grosir_price = String.valueOf(s);
                    }
                } else {
                    if (grosirList.product_grosir_list.size() != 0){
                        grosirList.product_grosir_list.get(position).grosir_price = null;
                    }
                }
            }
        });*/

        int x = holder.getLayoutPosition();

        if(grosirList.product_grosir_list.get(x).grosir_min != null) {
            ((FiturPromoHolder)holder).minRangeET.setText(grosirList.product_grosir_list.get(x).grosir_min);
        } else {
            ((FiturPromoHolder)holder).minRangeET.setText(null);
        }

        if(grosirList.product_grosir_list.get(x).grosir_max != null) {
            ((FiturPromoHolder)holder).maxRangeET.setText(grosirList.product_grosir_list.get(x).grosir_max);
        } else {
            ((FiturPromoHolder)holder).maxRangeET.setText(null);
        }

        if(grosirList.product_grosir_list.get(x).grosir_price != null) {
            ((FiturPromoHolder)holder).grossPriceET.setText(grosirList.product_grosir_list.get(x).grosir_price);
        } else {
            ((FiturPromoHolder)holder).grossPriceET.setText(null);
        }
    }

    /**
     * Here is the key method to apply the animation
     */
    private void setAnimation(View viewToAnimate, int position)
    {
        // If the bound view wasn't previously displayed on screen, it's animated
        if (position > lastPosition)
        {
            viewToAnimate.clearAnimation();
//            Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left);
            Animation animation = AnimationUtils.loadAnimation(context, R.anim.fade_in);
            viewToAnimate.startAnimation(animation);
            lastPosition = position;
        }
    }

    public boolean filledCheck(int itemNumber){
        return this.grosirList.product_grosir_list.size() > 0
                && this.grosirList.product_grosir_list.get(itemNumber - 1).grosir_price.trim().length() > 0
                && this.grosirList.product_grosir_list.get(itemNumber - 1).grosir_max.trim().length() > 0
                && this.grosirList.product_grosir_list.get(itemNumber - 1).grosir_min.trim().length() > 0;
    }

    private void removeAt(int removePosition){
        grosirList.product_grosir_list.remove(removePosition);
//        notifyItemRemoved(removePosition);
//        notifyItemRangeChanged(removePosition, grosirList.product_grosir_list.size());
//        notifyDataSetChanged();
        notifyItemRemoved(removePosition);
        notifyDataSetChanged();
//        notifyItemRangeRemoved(removePosition, grosirList.product_grosir_list.size());

//        notifyItemRangeChanged(removePosition, grosirList.product_grosir_list.size());
    }

    private void removeRange(int removePosition){
        int tempSize = grosirList.product_grosir_list.size();
        for (int i = removePosition; i < tempSize; i++){
            grosirList.product_grosir_list.remove(removePosition);
//            notifyItemRemoved(i);
        }
        notifyDataSetChanged();
//        notifyItemRangeRemoved(removePosition, grosirList.product_grosir_list.size());
//        notifyItemRangeChanged(0, this.grosirList.product_grosir_list.size());
    }

    private void clearAnimation(View viewToAnimate, int position)
    {
        // If the bound view wasn't previously displayed on screen, it's animated
        viewToAnimate.clearAnimation();
    }

    public void addGrosirList(GrosirAddList dataset){
        this.grosirList.product_grosir_list.addAll(dataset.product_grosir_list);
        notifyDataSetChanged();
//        notifyItemInserted(grosirList.product_grosir_list.size() - 1);
//        this.grosirList.add(grosirList.size(), dataset.product_grosir_list.get());
//        notifyItemInserted(grosirList.size() - 1);
    }

    public GrosirAddList getGrosirList(){
        if (mAwesomeValidation.validate()){
            return this.grosirList;
        } else {
            return null;
        }
//        return this.grosirList;
    }

    @Override
    public int getItemCount() {
        return grosirList.product_grosir_list.size();
    }

    public class FiturPromoHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

        Handler handler;
        RelativeLayout minRangeWrapper;
        OpenSansEditText minRangeET;
        RelativeLayout maxRangeWrapper;
        OpenSansEditText maxRangeET;
        RelativeLayout grossPriceWrapper;
        OpenSansEditText grossPriceET;
        OpenSansButton grossPriceDeleteBtn;

        public FiturPromoHolder(View promoView) {
            super(promoView);
            minRangeWrapper = (RelativeLayout)promoView.findViewById(R.id.fragment_marketplace_upload_produk_fitur_promo_card_minRangeWrapper);
            minRangeWrapper.setOnClickListener(this);
            minRangeET = (OpenSansEditText)promoView.findViewById(R.id.fragment_marketplace_upload_produk_fitur_promo_card_minRangeET);
            maxRangeWrapper = (RelativeLayout)promoView.findViewById(R.id.fragment_marketplace_upload_produk_fitur_promo_card_maxRangeWrapper);
            maxRangeWrapper.setOnClickListener(this);
            maxRangeET = (OpenSansEditText)promoView.findViewById(R.id.fragment_marketplace_upload_produk_fitur_promo_card_maxRangeET);
            grossPriceWrapper = (RelativeLayout)promoView.findViewById(R.id.fragment_marketplace_upload_produk_fitur_promo_card_grossPriceWrapper);
            grossPriceWrapper.setOnClickListener(this);
            grossPriceET = (OpenSansEditText)promoView.findViewById(R.id.fragment_marketplace_upload_produk_fitur_promo_card_grossPriceET);
            grossPriceDeleteBtn = (OpenSansButton)promoView.findViewById(R.id.fragment_marketplace_upload_produk_fitur_promo_card_grossPriceDeleteBtn);
            grossPriceDeleteBtn.setOnClickListener(this);
            this.setIsRecyclable(false);
            handler = new Handler();
            minRangeET.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                }

                @Override
                public void onTextChanged(final CharSequence s, int start, int before, int count) {
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            grosirList.product_grosir_list.get(getLayoutPosition()).grosir_min = String.valueOf(s);
                        }
                    }, 200);
                }

                @Override
                public void afterTextChanged(Editable s) {
                }
            });

            maxRangeET.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                }

                @Override
                public void onTextChanged(final CharSequence s, int start, int before, int count) {
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            grosirList.product_grosir_list.get(getLayoutPosition()).grosir_max = String.valueOf(s);
                        }
                    }, 200);
                }

                @Override
                public void afterTextChanged(Editable s) {
                }
            });

            grossPriceET.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                }

                @Override
                public void onTextChanged(final CharSequence s, int start, int before, int count) {
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            grosirList.product_grosir_list.get(getLayoutPosition()).grosir_price = String.valueOf(s);
                        }
                    }, 200);
                }

                @Override
                public void afterTextChanged(Editable s) {
                }
            });

            grossPriceET.addTextChangedListener(new NumberTextWatcher(grossPriceET));

            mAwesomeValidation.addValidation(minRangeET, RegexTemplate.NOT_EMPTY, "Jumlah minimum tidak boleh kosong");
            mAwesomeValidation.addValidation(maxRangeET, RegexTemplate.NOT_EMPTY, "Jumlah maximum tidak boleh kosong");
            mAwesomeValidation.addValidation(grossPriceET, RegexTemplate.NOT_EMPTY, "Harga tidak boleh kosong");
        }

        @Override
        public void onClick(View v) {
            if (v.equals(grossPriceDeleteBtn)) {
                int removePosition = getAdapterPosition();
                try {
                    grosirList.product_grosir_list.remove(removePosition);
                    notifyItemRemoved(removePosition);
                    notifyDataSetChanged();
                    minRangeET.setError(null);
                    maxRangeET.setError(null);
                    grossPriceET.setError(null);
//
                    mAwesomeValidation.addValidation(minRangeET, RegexTemplate.NOT_EMPTY, "Jumlah minimum tidak boleh kosong");
                    mAwesomeValidation.addValidation(maxRangeET, RegexTemplate.NOT_EMPTY, "Jumlah maximum tidak boleh kosong");
                    mAwesomeValidation.addValidation(grossPriceET, RegexTemplate.NOT_EMPTY, "Harga tidak boleh kosong");
                }catch (ArrayIndexOutOfBoundsException e){e.printStackTrace();}
            } else if(v.equals(minRangeWrapper)) {
                minRangeET.requestFocusFromTouch();
            } else if(v.equals(maxRangeWrapper)) {
                maxRangeET.requestFocusFromTouch();
            } else if(v.equals(grossPriceWrapper)) {
                grossPriceET.requestFocusFromTouch();
            }
        }
    }

希望这个错误不会那么愚蠢......


可能是由于我们使用时的动画notifyItemRemoved()。所以在动画延迟期间,如果我们立即调用getAdapterPosition()方法,然后它会返回-1。当我立即重复删除多个项目时,我遇到了同样的问题,我得到了这个例外。

可能的解决方案: 您可以先检查位置,如下代码:

private void removeAt(int removePosition){
    if(removePosition == -1)    
        return;
    grosirList.product_grosir_list.remove(removePosition);
    notifyItemRemoved(removePosition);
}

这是一个迟到的答案,但希望有帮助! :)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android - getAdapterPosition() 在删除项目后返回 -1 的相关文章

随机推荐

  • MYSQL 中的单个等于

    我想知道为什么 MYSQL 在条件语句中使用单个等号而不是更典型的两个等号 这有技术 历史原因吗 谢谢 你好 我想知道为什么 MYSQL 在条件语句中使用单个等号而不是更典型的两个等号 这有技术 历史原因吗 谢谢 比较更常见于SQL比作业
  • Cordova 文件传输:上传到 aws s3 后无法查看图像

    我正在使用 cordova 文件传输将图像上传到我的 s3 存储桶 我设法上传文件 没有任何错误 甚至在 s3 中作为文件可见 但是当我尝试从 s3 下载图像时 我无法查看它 图像已损坏 当做file image png我得到的结果是它是一
  • 根据子值合并数组中的对象

    我有一个填充有对象的数组 当对象具有匹配的特定子值时 如何合并此数组内的对象 我的数组如下所示 var data prod name test1 type 1 color white product id 5 prod name test2
  • Laravel date 不允许我使用 diffForHumans

    我的表设置了时间戳字段 用于在字段中创建和更新 在我的模型中 我这样做 protected dates created at updated at 但是当调用日期时 p gt created at gt diffForHumans I ge
  • TypeScript 泛型在柯里化时不适用于先前的函数,如何处理?

    我有一个咖喱版本map处理承诺 它需要两个参数 一次一个 它需要两个类型参数来让调用者提供无法推断的部分 然而 实际上 调用者总是必须提供它们 因为在它们传入的转换函数中不会推断类型 该函数如下所示 description Like ram
  • Celery工人挂起,没有任何错误

    我有一个用于运行 celery 工作人员的生产设置 用于向远程服务发出 POST GET 请求并存储结果 它每 15 分钟处理大约 20k 任务的负载 问题是工人们无缘无故地变得麻木 没有错误 没有警告 我也尝试过添加多处理 结果相同 在日
  • 通过 getRealPath() 将上传的文件写入磁盘时出现 java.io.FileNotFoundException

    Glassfish 似乎在我也想保存图像文件的路径中添加了额外的内容 是否有某种方法可以仅使用我的 servlet 获得的绝对路径 String appPath request getServletContext getRealPath 我
  • CouchDB 查询性能

    如果文档数量越多 CouchDB 中数据查询是否会变慢 示例场景 我有一个用于客户名称表单的组合框 当用户输入客户名称时 我必须进行自动填充 CouchDB 中将有大约 10k 个客户文档 我知道我必须创建一个视图才能执行相同的操作 Cou
  • DacPac 错误太大 - 但我的文件只有 406kb

    我正在尝试将我的数据库上传到 SQL Azure 我已创建 DCA 包并开始上传过程 但是 我立即收到以下错误 指定的 DacPac 太大 允许的最大 DacPac 大小为 5242880 字节 我不明白为什么上传文件为 406KB 时会出
  • iOS:删除 UINavigationBar 动画

    我们的应用程序有一个 UINavigationBar 上面有图像 当我们转到 推送 到另一个屏幕然后单击后退按钮时 导航栏上的图像在重新出现时似乎会从左到右进行动画处理 这有点让人分心 如何删除这个后退按钮动画 我们尝试更改 segue A
  • 抽屉导航在 Windows Phone 8.1 中有时无法工作[RT] [已关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我正在使用抽屉布局找到代码msdn https code msdn microsoft com windowsapps Windows
  • .NET Core 2.0 中 IServiceCollection 缺少扩展方法 AddJwtBearerAuthentication()

    我已使用以下说明将我的项目从 Core 1 1 更新到 Core 2 0https blogs msdn microsoft com webdev 2017 08 14 announcing asp net core 2 0 https b
  • 如何使用 AWS AppSync 进行无服务器开发?

    我有一个关于开发无服务器应用程序的一般性问题AWS 应用程序同步 https aws amazon com appsync 尤其 我们正在考虑为一个小项目采用无服务器 我想知道人们在创建 无服务器 应用程序时通常如何设置他们的开发环境 我已
  • 调整

    我有一个包含子菜单的菜单 它的 HTML 源代码如下所示 ul li a href Menu 1 a ul li a href Item 1 a a a li li a href Subitem 1 a ul li a href Subsu
  • 是否可以在 Typescript 中定义非空数组类型?

    我有一个数字列表 我知道这些数字永远不会为空 是否可以在 Typescript 中定义一个永远不为空的数组 我知道像这样的元组是可能的 number number 但这不起作用 因为我的数组可以是任何大小 我想我正在寻找的是NonEmpty
  • 无法计算 Vim 中的匹配数

    如何计算 Vim 中的匹配数 例如 对于文本
  • 谷歌大查询中行之间的差异

    我目前正在尝试计算谷歌大查询中行之间的差异 我实际上有一个有效的查询 SELECT id record time level lag level lag as diff FROM SELECT id record time level LA
  • Java 8 使用 Lambda 过滤数组

    我有一个double 我想在一行中过滤掉 创建一个没有的新数组 负值而不添加for循环 使用 Java 8 lambda 表达式可以实现这一点吗 在 python 中 使用生成器将是这样的 i for i in x if i gt 0 在
  • 为什么不能在类声明中使用“is_base_of”(不完整类型)?

    我完全明白为什么会这样cannot work class Base class A static assert std is base of
  • Android - getAdapterPosition() 在删除项目后返回 -1

    标题说明了一切 我有一个RecyclerView它用于动态存储值 但一次只能存储一项 该项目包含 3TextViews 当我正常添加所有项目时 它可以工作 但是当我添加 x 项目 然后删除最后一项 然后单击 提交 时 应用程序崩溃 I do