简体   繁体   English

Recycler View onClick被多次调用?

[英]Recycler View onClick being called multiple times?

I have a RecyclerView that launches a new Activity when it is clicked (both long press and short). 我有一个RecyclerView,它在点击时启动一个新的Activity(长按和短按)。 When I click it the corresponding action is being done 3 times (sometimes 2) in any case it is being done multiple times when I only want it done once. 当我点击它时,相应的动作正在进行3次(有时是2次),无论如何,当我只想完成一次时,它会被多次完成。 There is a thread that handles these actions but that thread is only executed once. 有一个线程可以处理这些操作,但该线程只执行一次。

A quick run thru of the sequence is: 快速运行顺序是:

  1. recyclerview is loaded, user can long press or quick click an item on the list. recyclelerview已加载,用户可以长按或快速单击列表中的项目。
  2. A quick click calls a openConversation() method which will launch a new activity(in the current version it launches the activity many times because the activity stack has 2-3 instances of the launched activity) 快速单击会调用openConversation()方法,该方法将启动一个新活动(在当前版本中,它会多次启动活动,因为活动堆栈有2-3个已启动活动的实例)
  3. Or if the boolean condition to launch the activity in openConversation() is false a toast message is sent (in this bug the toast is displayed 3 times from my tests) 或者,如果在openConversation()启动活动的布尔条件为false,则发送toast消息(在此错误中,toast将从我的测试中显示3次)
  4. Like wise on a long press the launched activity is launched 2-3 times when it should only be launched once, because there is more than one instance on the activity stack 就像在长按时那样明智的是,启动的活动只启动2-3次,因为活动堆栈上有多个实例

public class EventListActivity extends AppCompatActivity implements 
NavigationView.OnNavigationItemSelectedListener {

    private static final int VIBRATE_MILLISECONDS = 50;
    private static final int REFRESH_ANI_MILLIS = 2500;
    final Handler handler = new Handler();
    private Context applicationContext;
    private List<ParseObject> eventList;
    final Runnable updateEventsHard = new Runnable() {
        @Override
        public void run() {
            updateEventCards(true);
        }
    };

    final Runnable updateEventsSoft = new Runnable() {
        @Override
        public void run() {
            updateEventCards(false);
        }
    };

    final Runnable initSwipeRefresh = new Runnable() {
        @Override
        public void run() {
            initSwipeRefresh();
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_event_list);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        applicationContext = getApplicationContext();

        handler.post(updateEventsHard);

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.setDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);
        View headerLayout = navigationView.inflateHeaderView(R.layout.nav_header_event_list);
        TextView headerUsername = (TextView) headerLayout.findViewById(R.id.drawer_username);
        headerUsername.setText(CurrentActiveUser.getInstance().getUsername());

        handler.post(initSwipeRefresh);
    }

    private void initSwipeRefresh() {
        final SwipeRefreshLayout swipeView = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
        swipeView.setColorSchemeResources(android.R.color.holo_blue_dark, android.R.color.holo_blue_light, android.R.color.holo_green_light, android.R.color.holo_green_light);
        swipeView.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                swipeView.setRefreshing(true);
                (new Handler()).postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        updateEventCards(true);
                        swipeView.setRefreshing(false);
                    }
                }, REFRESH_ANI_MILLIS);
            }
        });
    }

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();
        switch (id) {
            case (R.id.nav_my_profile):
                Dialog.makeDialog(EventListActivity.this, getString(R.string.upcoming),
                        getString(R.string.profile_upcoming));
                break;
            case (R.id.nav_logout):
                CurrentActiveUser.getInstance().logout();
                Intent intent = new Intent(applicationContext, LoginActivity.class);
                startActivity(intent);
                finish();
                break;
            case (R.id.nav_share):
                Intent share = new Intent(Intent.ACTION_SEND);
                share.setType(StringResources.PLAIN_CONTENT_TYPE);
                share.putExtra(Intent.EXTRA_TEXT, R.string.app_share);
                startActivity(Intent.createChooser(share, getString(R.string.app_share_title)));
                break;
            case (R.id.nav_about):
                Intent aboutIntent = new Intent(applicationContext, AboutActivity.class);
                startActivity(aboutIntent);
                break;
            case (R.id.nav_legal):
                Intent legalIntent = new Intent(applicationContext, LegalActivity.class);
                startActivity(legalIntent);
                break;
        }

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }

    //display clickable a list of all users
    @SuppressWarnings("unchecked")
    private void updateEventCards(Boolean hard) {
        ArrayList<EventObject> eventObjects = new ArrayList<>();
        if (NetworkState.isConnected(applicationContext)) {
            Query<ParseObject> query = new Query<>(Events.class);
            query.orderByASC(Events.START_TIME);
            if (hard) {
                eventList = query.executeHard();
            } else {
                eventList = query.execute();
            }
            ParseObject current;
            if (eventList != null) {
                if (eventList.size() > 0) {
                    for (int i = 0; i < eventList.size(); i++) {
                        current = eventList.get(i);
                        eventObjects.add(
                                new EventObject(
                                        current.getString(Events.NAME),
                                        current.getString(Events.LOCATION),
                                        current.getLong(Events.START_TIME),
                                        current.getLong(Events.END_TIME),
                                        current.getString(Events.IMAGE)
                                )
                        );
                    }
                } else {
                    Dialog.makeToast(applicationContext, getString(R.string.no_events));
                }
            } else {
                Dialog.makeToast(applicationContext, getString(R.string.error_loading_events));
            }
        } else {
            Dialog.makeToast(applicationContext, getString(R.string.no_network));
        }
        attachToEventListAdapter(eventObjects);
    }

    private void attachToEventListAdapter(ArrayList<EventObject> eventObjects) {
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(applicationContext));
        eventListClickListener(recyclerView);
        EventListAdapter mAdapter = new EventListAdapter(eventObjects, applicationContext);
        recyclerView.setAdapter(mAdapter);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
    }

    private synchronized void eventListClickListener(RecyclerView recyclerView) {
        recyclerView.addOnItemTouchListener(
                new RecyclerItemClickListener(
                        EventListActivity.this, recyclerView,
                        new RecyclerItemClickListener.OnItemClickListener() {
                            @Override
                            public void onItemClick(View view, int position) {
                                Log.d("Click", "Quick");
                                openConversation(eventList.get(position));
                            }

                            @Override
                            public void onItemLongClick(View view, int position) {
                                Vibrator vibe = (Vibrator) applicationContext.getSystemService(Context.VIBRATOR_SERVICE);
                                vibe.vibrate(VIBRATE_MILLISECONDS);
                                openEventInfo(eventList.get(position));
                            }
                        }));
    }

    private void openConversation(ParseObject event) {
        Live status = DateVerifier.goLive(event.getLong(Events.START_TIME), event.getLong(Events.END_TIME));
        if (status.goLive()) {
            Intent intent = new Intent(applicationContext, MessagingActivity.class);
            intent.putExtra(IntentKeys.EVENT_ID, event.getObjectId());
            intent.putExtra(IntentKeys.EVENT_NAME, event.getString(Events.NAME));
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(intent);
        } else {
            Dialog.makeToast(applicationContext, String.valueOf(System.currentTimeMillis() % 1000));
        }
    }

    private void openEventInfo(ParseObject event) {
        Intent intent = new Intent(applicationContext, EventInfoActivity.class);
        intent.putExtra(IntentKeys.EVENT_NAME, event.getString(Events.NAME));
        intent.putExtra(IntentKeys.EVENT_INFO, event.getString(Events.INFO));
        intent.putExtra(IntentKeys.EVENT_CARD, event.getString(Events.MATCH_CARD));
        intent.putExtra(IntentKeys.EVENT_IMAGE, event.getString(Events.IMAGE));
        intent.putExtra(IntentKeys.EVENT_START_TIME, event.getLong(Events.START_TIME));
        intent.putExtra(IntentKeys.EVENT_LOCATION, event.getString(Events.LOCATION));
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
    }

    public void onStart(){
        super.onStart();
        handler.post(updateEventsSoft);
    }

    public void onResume() {
        super.onResume();
        handler.post(updateEventsSoft);
    }
}

I think your events are being fired 3 times because every time on your RecyclerView you are calling .addOnItemTouchListener() which will add a new listener every time. 我认为你的事件被解雇了3次,因为你每次在RecyclerView上调用.addOnItemTouchListener() ,它每次都会添加一个新的监听器。

Your method eventListClickListener() should only be called once in your onCreate() , not every time in your updateEventsHard() or updateEventsSoft() . 您的方法eventListClickListener()只应在onCreate()调用一次,而不是每次都在updateEventsHard()updateEventsSoft()调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM