java - Recycler View onClick 被多次调用?

标签 java android mobile

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

序列的快速运行是:

  1. recyclerview 已加载,用户可以长按或快速单击列表中的项目。
  2. 快速单击会调用 openConversation() 方法,该方法将启动一个新 Activity (在当前版本中它会多次启动该 Activity ,因为 Activity 堆栈有 2-3 个已启动 Activity 的实例)
  3. 或者,如果在 openConversation() 中启动 Activity 的 boolean 条件为 false,则发送 toast 消息(在这个错误中,toast 在我的测试中显示了 3 次)
  4. 明智的做法是长按启动的 Activity 会启动 2-3 次,而它应该只启动一次,因为 Activity 堆栈中有多个实例

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);
    }
}

最佳答案

我认为您的事件被触发了 3 次,因为每次在您的 RecyclerView 上您都在调用 .addOnItemTouchListener(),它每次都会添加一个新的监听器。

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

关于java - Recycler View onClick 被多次调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35462407/

相关文章:

java - 使用 Java 8 的整数列表的总和

java - 向左/向右滚动到新页面

android - Xamarin.Android 中的 rootView 高度和宽度

ios - 对 React Native App 的离线支持

java - 在 Jenkins 中找不到 Spark-version-info.properties

java - WSO2 IoT无法运行IoT Analytics服务器

java - Android 应用程序在尝试签署 apk 时出现 Menu Lint 错误

android - 更新抽屉导航 ListView

apache-flex - 服务器和手机之间发送数据

javascript - jQuery ".on( ' click' ,....)"不适用于 LET 变量声明。但适用于 VAR