RecyclerView onClickListener 适用于所有片段

Posted

技术标签:

【中文标题】RecyclerView onClickListener 适用于所有片段【英文标题】:RecylerView onClickListener works on all fragment 【发布时间】:2022-01-03 12:58:43 【问题描述】:

我在我的活动中实现了一个 recyclerview,并且我最近添加了一个 onclick 监听器。它工作正常,直到我切换到另一个片段并意识到点击也在那里工作,所以如果我随机按下屏幕上的某个地方,它会在回收站视图中给我带来项目点击。请让我知道如何才能使回收站视图只能在一个活动、主页上点击,而在另一个活动上不可点击。

HomePage.class

package com.example.movieapp;

import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;

import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewGroup;

import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.android.material.navigation.NavigationBarView;
import com.google.android.material.navigation.NavigationView;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;

public class HomePage extends AppCompatActivity implements NavigationBarView.OnItemSelectedListener 
    private DrawerLayout drawer;

    RecyclerView recylerView;
    MovieAdapter mainAdapter;

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

        recylerView = (RecyclerView) findViewById(R.id.rv);
        recylerView.setLayoutManager(new LinearLayoutManager(this));

        FirebaseRecyclerOptions<Model> options =
                new FirebaseRecyclerOptions.Builder<Model>()
                        .setQuery(FirebaseDatabase.getInstance().getReference().child("movie"), Model.class)
                        .build();

        mainAdapter = new MovieAdapter(options);
        recylerView.setAdapter(mainAdapter);

        drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this::onNavigationItemSelected);


        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.addDrawerListener(toggle);
        getSupportActionBar().setTitle(null);
        toggle.setDrawerIndicatorEnabled(true);


        toggle.syncState();
    

    public boolean onCreateOptionsMenu(Menu menu) 
        getMenuInflater().inflate(R.menu.toolbar_menu, menu);
        return super.onCreateOptionsMenu(menu);
    



    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) 
        switch(item.getItemId()) 
            case R.id.nav_home:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
                        new HomeFragment()).commit();
                break;
            case R.id.nav_profile:
               // Intent intent = new Intent (getApplicationContext(), UserProfile.class);
               // startActivity(intent);
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
                        new ProfileFragment()).commit();
                break;
            case R.id.nav_cart:

                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
                        new CartFragment()).commit();
                break;
        
        drawer.closeDrawer(GravityCompat.START);
        return true;
    

    @Override
    public void onBackPressed() 
        if (drawer.isDrawerOpen(GravityCompat.START)) 
            drawer.closeDrawer(GravityCompat.START);
         else 
            super.onBackPressed();
        
    




    @Override
    public void onStart() 
        super.onStart();
        mainAdapter.startListening();
    

    @Override
    public void onStop() 
        super.onStop();
        mainAdapter.stopListening();
    



MovieAdapter.class

public class MovieAdapter extends FirebaseRecyclerAdapter<Model,MovieAdapter.myViewHolder> 




    /**
     * Initialize a @link RecyclerView.Adapter that listens to a Firebase query. See
     * @link FirebaseRecyclerOptions for configuration options.
     *
     * @param options
     */
    public MovieAdapter(@NonNull FirebaseRecyclerOptions<Model> options) 
        super(options);
    

    @Override
    protected void onBindViewHolder(@NonNull myViewHolder myViewHolder, int i, @NonNull Model model) 
        myViewHolder.name.setText(model.getName());
        myViewHolder.shortDesc.setText(model.getShortDesc());
        myViewHolder.release.setText(model.getRelease());

        Glide.with(myViewHolder.img.getContext()).load(model.getImage()).placeholder(R.drawable.common_google_signin_btn_icon_dark)
                .error(R.drawable.common_google_signin_btn_icon_dark_normal)
                .into(myViewHolder.img);


        myViewHolder.itemView.setOnClickListener(new View.OnClickListener()
            @Override
            public void onClick(View view) 
                Intent intent = new Intent (view.getContext(), MovieDetails.class);
                Bundle bundle = new Bundle();

                String test =  model.getName() + " Selected";

                Toast toast = Toast.makeText(view.getContext(), test ,Toast.LENGTH_SHORT);
                toast.show();

                view.getContext().startActivity(intent);
            
        );
    

    @NonNull
    @Override
    public myViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.main_item, parent, false);
        return new myViewHolder(view);
    

    class myViewHolder extends RecyclerView.ViewHolder 

        ImageView img;
        TextView name,shortDesc,release;

        public myViewHolder(@NonNull View itemView) 
            super(itemView);

            img = (ImageView) itemView.findViewById(R.id.img1);
            name = (TextView) itemView.findViewById(R.id.nametext);
            shortDesc = (TextView) itemView.findViewById(R.id.shortDesctext);
            release = (TextView) itemView.findViewById(R.id.releasetext);
        
    

【问题讨论】:

【参考方案1】:

每次您使用此适配器时它都有效,因为 onclicklistener 始终在工作,要更改它,您可以创建自己的自定义侦听器接口, 所以你可以控制是否添加它

public interface OnModelClickListener 
    void onClick(Model model);

您需要在适配器中创建实例并为其设置方法

private OnModelClickListener onModelClickListener

public void setOnModelClickListener(OnModelClickListener listener) (
    this.onModelClickListener = listener;

在 onBindViewHolder 中,如果它不为空,您将运行此侦听器

@Override
protected void onBindViewHolder(@NonNull myViewHolder myViewHolder, int i, @NonNull Model model) 
    myViewHolder.name.setText(model.getName());
    myViewHolder.shortDesc.setText(model.getShortDesc());
    myViewHolder.release.setText(model.getRelease());

    Glide.with(myViewHolder.img.getContext()).load(model.getImage()).placeholder(R.drawable.common_google_signin_btn_icon_dark)
                .error(R.drawable.common_google_signin_btn_icon_dark_normal)
                .into(myViewHolder.img);

    if (onModelClickListener != null) 
        myViewHolder.itemView.setOnClickListener(v -> 
            onModelClickListener.onClick(model)
        );
    

在您希望侦听器对其进行处理的片段中,您将使用 setter

adapter.setOnModelClickListener(model -> 
    Intent intent = new Intent (view.getContext(), MovieDetails.class);
    Bundle bundle = new Bundle();

    String test =  model.getName() + " Selected";

    Toast toast = Toast.makeText(view.getContext(), test ,Toast.LENGTH_SHORT);
    toast.show();

    startActivity(intent);
);
``

【讨论】:

好的明白了,只是一个问题,我到底应该在哪里添加 onmodelclicklistener 方法,比如哪个类。 onmodelclicklistener 和 setter 将在适配器本身中,因此我们可以在 view.OnclickListener 工作时调用 onClick 嘿,对于最后一个代码,您希望侦听器在片段中工作的那个,我应该将代码添加到哪个函数?是onCreate方法吗 初始化适配器的时候添加,只要初始化然后调用setOnModelClickListener 感谢您的帮助,但我似乎无法正常工作。

以上是关于RecyclerView onClickListener 适用于所有片段的主要内容,如果未能解决你的问题,请参考以下文章

关于RecyclerView

recyclerview 内的 RecyclerView 只显示父 recyclerview 的最后一项

RecyclerView详解

RecyclerView

RecyclerView嵌套RecyclerView问题

RecyclerView小结