Обновить активность при нажатии в RecyclerView

У меня есть активность, состоящая из 2 основных элементов: RecyclerView и ListView. RecyclerView действует как фильтр, и выбор / отмена элементов в нем влияет на содержимое ListView. Все работает хорошо, пока я не попытался реализовать onClickListener в RecyclerView и понял, что это не вариант.

Я попытался спуститься по пути установки OnClickListener внутри ViewHolder, но ему нужно вызвать функцию внутри основного действия и обновить ее listView. Любое такое взаимодействие вызывает следующую ошибку:

java.lang.NullPointerException at android.support.v7.app.AppCompatDelegateImplBase.<init>(AppCompatDelegateImplBase.java:117) at android.support.v7.app.AppCompatDelegateImplV9.<init>(AppCompatDelegateImplV9.java:149) at android.support.v7.app.AppCompatDelegateImplV11.<init>(AppCompatDelegateImplV11.java:29) at android.support.v7.app.AppCompatDelegateImplV14.<init>(AppCompatDelegateImplV14.java:54) at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:202) at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:183) at android.support.v7.app.AppCompatActivity.getDelegate(AppCompatActivity.java:519) at android.support.v7.app.AppCompatActivity.findViewById(AppCompatActivity.java:190) at .newsScreen._$_findCachedViewById(newsScreen.kt) at .newsScreen.filterNews(newsScreen.kt:71) at Cells.NewsFeedList$NewsSource$1.onClick(News Lists.kt:84) 

Предположим, что это имеет смысл, поскольку я пытаюсь получить доступ к пользовательскому интерфейсу из-за пределов его класса, но я не мог найти альтернативы ему.

Адаптер RecyclerView:

 class NewsFeedList() : RecyclerView.Adapter<NewsFeedList.NewsSource>() { private var source: List<NewsFeed> = ArrayList() constructor(s: ArrayList<NewsFeed>) : this() { source = s } class NewsSource : RecyclerView.ViewHolder { private var mTextView: TextView? = null constructor(v: View): super(v) { mTextView = v.title } fun bindInfo(news: NewsFeed, view: View, int: Int) { mTextView!!.text = news.title view.tag = int view.setOnClickListener { newsScreen().filterNews(view.tag.toString().toInt()) } if (news.selected) view.background = ColorDrawable(Color.parseColor(news.color)) else view.background = ColorDrawable(Color.parseColor(design.backgroundColor)) } } override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): NewsFeedList.NewsSource { val view = LayoutInflater.from(parent!!.context).inflate(R.layout.newsfeed_list, parent, false) return NewsSource(view) } override fun onBindViewHolder(holder: NewsFeedList.NewsSource, position: Int) { holder.bindInfo(source[position], holder.itemView, position) } override fun getItemCount(): Int { return source.count() } } 

Затем внутри моего класса newsScreen мне нужно получить доступ к адаптеру RecyclerView с новыми данными

 fun filterNews(i: Int) { newsFeed[i].selected = !newsFeed[i].selected filter.adapter = NewsFeedList(newsFeed) } 

Если я удалю ссылки на фильтр (RecyclerView), все будет в порядке, но цель onClickListener – обновить содержимое Activities.

Есть ли способ достичь этого или я должен изменить RecyclerView на другой элемент пользовательского интерфейса?

Изменить: я попытался добавить OnClickListener в RecyclerView, но он, похоже, не срабатывает. Код:

 filter.adapter = NewsFeedList(newsFeed) filter.layoutManager = LinearLayoutManager(this@newsScreen, LinearLayoutManager.HORIZONTAL, false) filter.setOnClickListener { v: View? -> filterNews(v!!.tag.toString().toInt()) } 

    Хорошо, вот еще одно решение, которое вы можете попробовать:

    Добавьте этот интерфейс в свое приложение:

     interface ClickListener { void onItemClicked(int position); } 

    Внесите его в свою MainActivity (или любую другую работу, на которую вы нажимаете кнопки).

    Передайте ссылку интерфейса внутри вашего конструктора адаптера: ArrayList mList; Прослушиватель ClickListener;

     public MyAdapter(ArrayList<NewsFeed> mList, ClickListener listener) { this.listener = listener; } @Override public MyAdapter.NavViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.someL, parent, false); return new ViewHolder(v, listener); } public void getItemClicked(int position){ mList.get(position); } 

    Наконец, внутри класса ViewHolder:

     class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener { TextView textView; ImageView imageView; ClickListener listener; ViewHolder(View itemView, ClickListener listener) { super(itemView); this.listener = listener; textView = (TextView) itemView.findViewById(R.id.text_view); imageView = (ImageView) itemView.findViewById(R.id.image_view); textView.setOnClickListener(this) } @Override void onClick(View v) { listener.onItemClicked(getAdapterPosition()); } 

    И, наконец, внутри вашей деятельности (которая реализует интерфейс ClickListener) вам придется переопределить void onItemClicked(int position); внутри которого вы будете действовать.

    PS: Этот ответ был написан с большой помощью от пользователя: https://stackoverflow.com/users/2667883/chaynik

    Для вашего класса адаптера у вас будет класс ViewHolder (возможно, как внутренний класс), который реализует OnClickListener как таковой в этом коде:

     class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener { TextView textView; ImageView imageView; ViewHolder(View itemView) { super(itemView); textView = (TextView) itemView.findViewById(R.id.text_view); imageView = (ImageView) itemView.findViewById(R.id.image_view); } @Override void onClick(View v) { } } 

    Предполагая, что ваш адаптер не является внутренним классом вашего класса Activity, если вы хотите использовать onClick () для доступа к вашим методам / переменным класса Activity, вы ДОЛЖНЫ иметь ссылку.

    Предпочтительным способом является передача ссылки Context через конструктор вашего адаптера, учитывая, что ваш ViewHolder является внутренним классом вашего адаптера:

     class MyAdapter extends extends RecyclerView.Adapter<RecyclerView.ViewHolder> { Context context; MyAdapter(Context context) { this.context = context; } class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener { TextView textView; ImageView imageView; ViewHolder(View itemView) { super(itemView); textView = (TextView) itemView.findViewById(R.id.text_view); imageView = (ImageView) itemView.findViewById(R.id.image_view); } @Override void onClick(View v) { // Here we gain access to non-private methods/variables // of the Activity, which Context reference we are holding. ((MyActivity) context).someMethod(); } } } 

    Надеюсь это поможет.

    Intereting Posts
    Kotlin: Запуск kapt в командной строке для создания заглушек для DI Открытые поля для совместимости с Java Свободные методы для класса данных в котлине MutableLiveData с многократным укладом Kotlin Generic не работает Аннотации @JsonValue в классе ценности перечисления класса Kotlin Связывающий адаптер с несколькими аргументами в Котлине Я сейчас разрабатываю приложение для Android с Kotlin, но произошла ошибка: CompilationException: не удалось встроить метод в 'readText' Android предотвращает просмотр от успешных событий Добавление вторичного конструктора к родительскому объекту неожиданно влияет на дочерние классы Kotlin Bytecode – Как анализировать в IntelliJ IDEA? Котлин – вторичный конструктор, который отличается одним аргументом Как использовать «Функциональное определение компонента Kotlin DSL» с Spring Boot и Spring WebFlux? EditText теряет фокус наTextChange Расширение общего класса в Котлине Почему нельзя вводить параметр в Kotlin какие-либо другие границы, если он ограничен другим параметром типа?