未触发嵌套的RecyclerView onClick

时间:2019-04-02 10:02:28

标签: android android-layout android-recyclerview recyclerview-layout nestedrecyclerview

我有两个嵌套的RecyclerViews-基本上是水平RecyclerViews的列表,我正在努力使水平RecyclerView中的项目可单击。

这是主要布局

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

1 个答案:

答案 0 :(得分:0)

我认为您将能够处理它以创建一个侦听器并使用它来处理呼叫:

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

将此界面添加到您的adaptermain中。

将此功能添加到您的*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);
  }
        }));

我希望这对您有所帮助,很明显,您可以更改不调用新活动的最后一部分,而是根据您要查看或处理的项目进行更改。