Recycler View onClick被多次调用?

时间:2016-02-17 16:30:19

标签: java android mobile

我有一个RecyclerView,当它被点击时(长按和短按)都会启动一个新的Activity。当我点击它时,相应的动作正在进行3次(有时是2次),无论如何,当我只想完成一次时,它会被多次完成。有一个线程可以处理这些操作,但该线程只执行一次。

序列的快速运行是:

  1. 加载了recyclerview,用户可以长按或快速单击列表中的项目。
  2. 快速点击会调用openConversation()方法,该方法将启动新活动(在当前版本中,它会多次启动活动,因为活动堆栈有2-3个已启动活动的实例)
  3. 或者,如果在openConversation()中启动活动的布尔条件为false,则会发送Toast消息(在此错误中,吐司会在我的测试中显示3次)
  4. 同样明智的是,长时间按下启动的活动只会启动一次,因为活动堆栈上有多个实例
  5. 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);
        }
    }
    

1 个答案:

答案 0 :(得分:6)

我认为您的活动被解雇了3次,因为您RecyclerView每次都在呼叫.addOnItemTouchListener(),每次都会添加新的听众。

您的方法eventListClickListener()只应在onCreate()中调用一次,而不是每次都在updateEventsHard()updateEventsSoft()中调用。