У меня есть два вложенных 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"/>И я пытаюсь получить настройку onclick в адаптере для внутреннего RecyclerView следующим образом:
@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
}
});
}Я попытался сделать представление элемента ViewHolder программно и в XML доступным для кликов, и, похоже, это не имеет значения. То же самое для внутреннего 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();
}
}Можете ли вы включить код адаптера вашего родительского recyclerview?
Использование NestedScrollView не сработало :(
@MDNaseemAhraf добавил это, спасибо
@ТюдорС. проверить это
Я думаю, вы сможете справиться с этим, создав слушателя и обработав с ним вызов:
public interface clickListenerItem {
void onItemClick(Item element);
}
добавьте этот интерфейс в свой adapter и в свой main.
Добавление этой функции в ваш *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);
}
}));
Я надеюсь, что это поможет вам, очевидно, вы можете изменить последнюю часть, чтобы не вызывать новое действие, а изменить его с тем, что вы хотите видеть или делать с вашим элементом.
попробуйте поместить свой основной макет во вложенный прокрутку