嵌套RecyclerView的onClick事件未被触发

3

我有两个嵌套的RecyclerViews,基本上是一个水平RecyclerViews的列表,我很难让水平RecyclerViews中的项目可点击。

This is the main layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/overview_list"
        android:visibility="gone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <components.emptyView.EmptyView
        android:id="@+id/empty_state"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"/>
</LinearLayout>

然后RecyclerView具有以下项目布局:

<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView android:id="@+id/tables"
                                           xmlns:android="http://schemas.android.com/apk/res/android"
                                           android:layout_width="match_parent"
                                           android:layout_height="wrap_content"
                                           android:layout_marginBottom="8dp"
                                           android:layout_marginTop="8dp"
                                           android:clipToPadding="false"
                                           android:paddingEnd="18dp"
                                           android:paddingStart="18dp"/>

我正在尝试为内部RecyclerView设置适配器中的onclick,如下所示:

@Override
    public void onBindViewHolder(@NonNull LeagueTableViewHolder holder, int position) {
        Pair<Long, String> table = tables.get(position);
        holder.bindTable(table.first, table.second);
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // click event here
            }
        });
    }

我尝试过编程和XML让ViewHolder的itemview可点击,但似乎并没有什么区别。内部的RecyclerView也是一样的。
不知道我做错了什么?
编辑:添加了父级RecyclerView适配器。

public class OverviewListAdapter extends RecyclerView.Adapter<BaseViewHolder> {
    public final static int TEAM_PICTURE = 0;
    public final static int FIXTURES = 1;
    public final static int LEAGUE_TABLES = 2;
    public final static int LATEST_NEWS = 3;
    public final static int LATEST_EVENTS = 4;
    private final RecyclerView.RecycledViewPool viewPool;

    private List<BaseOverviewItemVM> viewModels = new ArrayList<>();
    private int tint;

    private OverviewLatestNewsVM newsVM;
    private OverviewLatestEventsVM eventsVM;
    private OverviewTablesVM tablesVM;
    private OverviewFixturesVM fixturesVM;
    private OverviewTeamPicVM teamPicVM;


    OverviewListAdapter(int tint) {
        this.tint = tint;
        viewPool = new RecyclerView.RecycledViewPool();
    }

    void addViewModel(OverviewLatestNewsVM viewModel){
        if(newsVM == null){
            newsVM = viewModel;
            viewModels.add(newsVM);
            sort();
            int viewModelIndex = viewModels.indexOf(newsVM);
            notifyItemInsertedIfValid(viewModelIndex);
        } else {
            int currentNewsIndex = viewModels.indexOf(newsVM);
            newsVM = viewModel;
            if(currentNewsIndex >= 0) {
                this.viewModels.set(currentNewsIndex, newsVM);
            }
            notifyItemChangedIfValid(currentNewsIndex);
        }
    }

    void addViewModel(OverviewLatestEventsVM viewModel){
        if(eventsVM == null){
            eventsVM = viewModel;
            viewModels.add(eventsVM);
            sort();
            int viewModelIndex = viewModels.indexOf(eventsVM);
            notifyItemChangedIfValid(viewModelIndex);
        } else {
            int currentIndex = viewModels.indexOf(eventsVM);
            eventsVM = viewModel;
            if(currentIndex >= 0) {
                this.viewModels.set(currentIndex, eventsVM);
            }
            notifyItemChangedIfValid(currentIndex);
        }
    }

    void addViewModel(OverviewFixturesVM viewModel){
        if(fixturesVM == null){
            fixturesVM = viewModel;
            viewModels.add(fixturesVM);
            sort();
            int viewModelIndex = viewModels.indexOf(fixturesVM);
            notifyItemChangedIfValid(viewModelIndex);
        } else {
            int currentIndex = viewModels.indexOf(fixturesVM);
            fixturesVM = viewModel;
            if(currentIndex >= 0) {
                this.viewModels.set(currentIndex, fixturesVM);
            }
            notifyItemChangedIfValid(currentIndex);
        }
    }

    void addViewModel(OverviewTablesVM viewModel){
        if(tablesVM == null){
            tablesVM = viewModel;
            viewModels.add(tablesVM);
            sort();
            int viewModelIndex = viewModels.indexOf(tablesVM);
            notifyItemChangedIfValid(viewModelIndex);
        } else {
            int currentIndex = viewModels.indexOf(tablesVM);
            tablesVM = viewModel;
            if(currentIndex >= 0) {
                this.viewModels.set(currentIndex, tablesVM);
            }
            notifyItemChangedIfValid(currentIndex);
        }
    }

    void addViewModel(OverviewTeamPicVM viewModel){
        if(teamPicVM == null){
            teamPicVM = viewModel;
            viewModels.add(teamPicVM);
            sort();
            int viewModelIndex = viewModels.indexOf(teamPicVM);
            notifyItemChangedIfValid(viewModelIndex);
        } else {
            int currentIndex = viewModels.indexOf(teamPicVM);
            teamPicVM = viewModel;
            if(currentIndex >= 0) {
                this.viewModels.set(currentIndex, teamPicVM);
            }
            notifyItemChangedIfValid(currentIndex);
        }
    }

    private void sort(){
        // sort by the item type defined at the top of this class
        Collections.sort(viewModels, (o1, o2) -> {
            if(o1.getType() > o2.getType()){
                return 1;
            } else if(o1.getType() < o2.getType()){
                return -1;
            }
            return 0;
        });
    }

    private void notifyItemInsertedIfValid(int index){
        if(index >= 0 && index < getItemCount()){
            notifyItemInserted(index);
        } else {
            notifyDataSetChanged();
        }
    }

    private void notifyItemChangedIfValid(int index){
        if(index >= 0 && index < getItemCount()){
            notifyItemChanged(index);
        } else {
            notifyDataSetChanged();
        }
    }

    @NonNull
    @Override
    public BaseViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        switch (viewType){
            case FIXTURES:
                View fixturesView = inflater.inflate(R.layout.row_overview_fixtures, parent, false);
                OverviewFixturesVH fixturesHolder = new OverviewFixturesVH(fixturesView);
                fixturesHolder.fixturesOverview.setRecycledViewPool(viewPool);
                return fixturesHolder;
            case LEAGUE_TABLES:
                View tablesView = inflater.inflate(R.layout.row_overview_league_tables, parent, false);
                OverviewTablesVH tablesHolder = new OverviewTablesVH(tablesView);
                tablesHolder.tablesList.setRecycledViewPool(viewPool);
                return tablesHolder;
            case LATEST_EVENTS:
                View upcomingEvents = inflater.inflate(R.layout.row_latest_list_view, parent, false);
                return new OverviewLatestEventsVH(upcomingEvents, tint);
            case TEAM_PICTURE:
                View teamPicView = inflater.inflate(R.layout.row_overview_team_pic, parent, false);
                return new OverviewTeamPicVH(teamPicView);
            default:
                View latestNewsView = inflater.inflate(R.layout.row_latest_list_view, parent, false);
                return new OverviewLatestNewsVH(latestNewsView, tint);
        }
    }

    @Override
    public void onBindViewHolder(@NonNull BaseViewHolder holder, int position) {
        if(holder instanceof  OverviewFixturesVH) {
            Optional<BaseOverviewItemVM> fixturesVM = getViewModelOfType(FIXTURES);
            fixturesVM.ifPresent(viewModel -> ((OverviewFixturesVH) holder).setFixtures(((OverviewFixturesVM)viewModel).getFixtures()));
        } else if (holder instanceof OverviewTablesVH) {
            Optional<BaseOverviewItemVM> tablesVM = getViewModelOfType(LEAGUE_TABLES);
            tablesVM.ifPresent(vm -> ((OverviewTablesVH) holder).setTableIds(((OverviewTablesVM) vm).getTableIds()));
        } else if (holder instanceof OverviewLatestEventsVH){
            Optional<BaseOverviewItemVM> eventsVM = getViewModelOfType(LATEST_EVENTS);
            eventsVM.ifPresent(vm -> ((OverviewLatestEventsVH) holder).setEvents(((OverviewLatestEventsVM) vm).getEvents()));
        } else if (holder instanceof OverviewLatestNewsVH){
            Optional<BaseOverviewItemVM> newsVM = getViewModelOfType(LATEST_NEWS);
            newsVM.ifPresent(vm -> ((OverviewLatestNewsVH) holder).setNews(((OverviewLatestNewsVM) vm).getNews()));
        } else if (holder instanceof OverviewTeamPicVH){
            Optional<BaseOverviewItemVM> teamPicVM = getViewModelOfType(TEAM_PICTURE);
            teamPicVM.ifPresent(vm -> ((OverviewTeamPicVH) holder).setPictureUrl(((OverviewTeamPicVM) vm).getTeamPicUrl()));
        }
    }

    @Override
    public int getItemViewType(int position) {
        return viewModels.get(position).getType();
    }

    @Override
    public int getItemCount() {
        return viewModels.size();
    }

    private Optional<BaseOverviewItemVM> getViewModelOfType(int type){
        if(viewModels != null ) {
            for (BaseOverviewItemVM viewModel : viewModels) {
                if(viewModel.getType() == type){
                    return Optional.of(viewModel);
                }
            }
        }
        return Optional.empty();
    }
}


尝试将主要布局放置在嵌套的ScrollView中。 - Vivek Mishra
你能包含你的父recyclerview的adapter代码吗? - MD Naseem Ashraf
使用NestedScrollView没有起作用 :( - Tudor S.
@MDNaseemAshraf已添加,谢谢。 - Tudor S.
@TudorS. 请查看这个链接 - Maddy
1个回答

0

我认为你能够处理它,只需创建一个监听器并通过它处理调用即可:

public interface clickListenerItem {
        void onItemClick(Item element);
    } 

在你的适配器主要代码中添加这个接口。

将此函数添加到你的*nameclass*ViewHolder extends RecyclerView.ViewHolder中:

 public void bind(final ItemName item, final clickListenerItem listener) {
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override public void onClick(View v) {
                    listener.onItemClick(item);
                }
            });
        }

然后在您的适配器变量中添加:private final clickListenerItem clickItem;

在您的构造函数中:this.clickItem = clickItem;

并且在您的适配器的onBindViewHolder中调用:

public void onBindViewHolder(final @NonNull ItemViewHolder holder, int position) {
holder.bind(list.get(position), clickItem);
}

现在,在主函数中初始化适配器时,只需通过以下调用添加侦听器:

adapter = new ItemAdapter(this, list, (new ItemAdapter.clickListenerItem(){
            @Override public void onItemClick(Item thisItem) {
                Toast.makeText(getApplicationContext(), "Loading Item...", Toast.LENGTH_LONG).show();
                Intent viewElem = new Intent(getApplicationContext(), ViewItem.class);
                startActivityForResult(viewElem ,codeForResult);
  }
        }));

我希望这可以帮到你,显然你可以更改最后一部分,不必调用新的活动,而是根据你想要查看或处理的项目进行更改。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接