【问题标题】:How to prevent Recycler view item from executing the same task twice如何防止 Recycler 视图项执行两次相同的任务
【发布时间】:2017-02-26 05:32:32
【问题描述】:

我已经在 Holder 类中实现了一个 Recycler 视图,它的项目单击。每次单击项目都会打开一个新活动。问题是当用户快速点击一个项目两次(非常快,时间跨度非常短)时,它会打开两次活动。

我无法尝试以下解决方案:

  1. android:launchMode="singleInstance" 我正在使用 startActivityForResult() 调用新活动。
  2. android:launchMode="singleTask" 也不起作用。

如何阻止它发生?请提出建议。

下面是我的适配器类:

        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

            RecyclerView.ViewHolder viewHolder = null;

            LayoutInflater inflater = LayoutInflater.from(parent.getContext());

            switch (viewType) {

                case MY_VIEW_TYPE:

                    View v1 = inflater.inflate(R.layout.created_by_me_item, parent, false);

                    viewHolder = new ViewHolderCreatedByMe(v1);

                    break;    

            }
            return viewHolder;
        }

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

       if (holder instanceof ViewHolderCreatedByMe) {
            // The data setting method is inside the Holder class
            ((ViewHolderCreatedByMe) holder).setDataCreatedByMe(mFeedRecordListData.get(position));

        } else {

            ((ViewHolderFooter) holder).setFooterView();
        }
    }

下面是我的持有者类:

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

    // ... some class members are declared here


    public ViewHolderCreatedByMe(View itemView) {

        super(itemView);
        // a few more UI components are initialized here

        rl_reaction_item_main_layout = (RelativeLayout) itemView.findViewById(R.id.rl_reaction_item_main_layout);

        rl_reaction_item_main_layout.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {

        switch (v.getId()) {

            case R.id.rl_reaction_item_main_layout:

                Intent intent = new Intent(mActivity, NewActivity.class);

                intent.putExtra(NewActivity.KEY_EVENT_ID, UIModel.getEventID());

                intent.putExtra(NewActivity.KEY_EVENT_TIME_STAMP, UIModel.getEventLocalTimeStamp());

                intent.putExtra(NewActivity.KEY_EVENT_POSITION, getAdapterPosition());

                mFragment.startActivityForResult(intent, Constants.REQUEST_CODE);

                break;
        }
    }

【问题讨论】:

  • 共享代码,您将在其中与适配器代码一起开始新活动。
  • 向我们展示您的适配器代码。
  • @AlokOmkar 请查看添加的代码。谢谢。

标签: android android-activity android-recyclerview multi-touch


【解决方案1】:

您应该使用布尔标志来检查天气行项目是否被点击。

boolean isItemClicked = false;

private void onRecyclerViewItemClick()
{
    if(!isItemClicked)
    {
        isItemClicked = true;
        startActivity(new Intent(this, MyActivity.class));
    }
}

@Override
protected void onResume() {
    // TODO Auto-generated method stub
    super.onResume();
    isItemClicked = false;
}

*注意-我在这里使用了名称 onRecyclerViewItemClick() ,它将被替换为您的 listView 的 onItemClick

【讨论】:

  • 这种布尔方式肯定会起作用,但我目前正在寻找其他方法来做到这一点。如果我没有得到其他解决方案,那么我会走你的路。谢谢:)
  • 在你开始你的活动时添加这一行intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);它肯定会工作。
【解决方案2】:

创建一个界面来拦截点击你的recyclerview项目的视图。

例如:

public interface CustomClickListener {
   void onClick(UIModel uiModel, int position);
}

在您的适配器类中创建一个方法来设置定义的接口:

private CustomClickListener mCustomClickListener;
public void setClickListener( CustomClickListener customClickListener ) {
    this.mCustomClickListener = customClickListener;
}

将您的视图持有者类修改为:

public class ViewHolderCreatedByMe extends RecyclerView.ViewHolder implements View.OnClickListener {
    // ... some class members are declared here
    public ViewHolderCreatedByMe(View itemView) {
        super(itemView);
        // a few more UI components are initialized here
        rl_reaction_item_main_layout = (RelativeLayout) itemView.findViewById(R.id.rl_reaction_item_main_layout);
        rl_reaction_item_main_layout.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        int position = getAdapterPosition();
        if( position != RecyclerView.NO_POSITION && mCustomClickListener != null ) {
            mCustomClickListener.onClick(UIModel, position);
        }
   }

在您的片段类中,您将定义您的适配器,在此处设置点击侦听器:

CustomClickListener customClickListener = new CustomClickListener() {
    @Override
    void onClick(UIModel uiModel, int position) {

         Intent intent = new Intent(getActivity(), NewActivity.class);
         intent.putExtra(NewActivity.KEY_EVENT_ID, uiModel.getEventID());
         intent.putExtra(NewActivity.KEY_EVENT_TIME_STAMP, uiModel.getEventLocalTimeStamp());
         intent.putExtra(NewActivity.KEY_EVENT_POSITION, position);
         getActivity().startActivityForResult(intent, Constants.REQUEST_CODE);
         adapter.setCustomClickListener(null); //To prevent the event being triggered twice

    }
}
adapter.setCustomClickListener( customClickListener );

在您覆盖 onActivityResult 的片段中,执行以下操作:

@Override
public void onActivityResult( int requestCode, int resultCode, Intent intent ) {
     if( requestCode == Constants.REQUEST_CODE ) {
         //Do something with the result 
         adapter.setCustomClickListener(customClickListener); // Make customClickListener a global variable
     }
}

希望这会有所帮助。如果这不适合您的需求,请告诉我您是否找到了解决问题的更好方法。基于布尔值的答案将起作用,但是当您打开和关闭应用程序时跟踪布尔值会很麻烦。

【讨论】:

    【解决方案3】:

    添加这些标志Intent.FLAG_ACTIVITY_SINGLE_TOPFLAG_ACTIVITY_NEW_TASKFLAG_ACTIVITY_RESET_TASK_IF_NEEDEDFLAG_ACTIVITY_CLEAR_TOP

    你的点击事件应该是这样的

    case R.id.rl_reaction_item_main_layout:
    
                        Intent intent = new Intent(mActivity, NewActivity.class);
    
                        intent.putExtra(NewActivity.KEY_EVENT_ID, UIModel.getEventID());
    
                        intent.putExtra(NewActivity.KEY_EVENT_TIME_STAMP, UIModel.getEventLocalTimeStamp());
    
                        intent.putExtra(NewActivity.KEY_EVENT_POSITION, getAdapterPosition());
                        //add these following line 
                        intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
                        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    
                        mFragment.startActivityForResult(intent, Constants.REQUEST_CODE);
    
                        break;
    

    【讨论】:

    • @SKP 奇怪,一旦我遇到同样的问题,就以这种方式解决了。顺便说一句,我已经编辑了我的答案。没有什么特别的,只是添加了一些额外的标志。试试看告诉我
    • 你可能没有调用 startActivity(intent) 而不是 startActivityForResult() 我的问题是我必须调用 startActivityForResult() .
    • 更正了上述评论的错字 - 您可能调用的是 startActivity(intent) 而不是 startActivityForResult() 我的问题是我必须调用 startActivityForResult() .
    猜你喜欢
    • 2015-12-29
    • 2016-08-29
    • 1970-01-01
    • 2014-03-01
    • 2015-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多