Как вызвать метод интерфейса из Xml с помощью привязки данных?

avatar
Nikhil Reddy
1 июля 2021 в 17:17
108
1
0

Вот мой фрагмент:

 public class Fragment_Cities extends Fragment implements Adapter_Cities.CitiesListener {
    
        private Adapter_Cities adapterCities;
        private FragmentCitiesBinding binding;
    
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            binding = FragmentCitiesBinding.inflate(inflater, container, false);
            return binding.getRoot();
        }
    
        @Override
        public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            binding.recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
            adapterCities = new Adapter_Cities(this);
            binding.recyclerView.setAdapter(adapterCities);

            ViewModel_Cities viewModelCities = new ViewModelProvider(this).get(ViewModel_Cities.class);
            viewModelCities.getLiveDataCities().observe(getViewLifecycleOwner(), model_cities ->
                    adapterCities.setAdapterData(model_cities));
        }
    
        @Override
        public void onCitySelected(Model_Cities city) {
            if (!alertDialog.isShowing()) alertDialog.show();
            new DialogFragment_Map().newInstance(city.getName(), city.getLatLon(), this).
                    show(requireActivity().getSupportFragmentManager(), null);
        }
    
    }

**

Вот мой адаптер:

**

public class Adapter_Cities extends RecyclerView.Adapter<Adapter_Cities.MyViewHolder> implements Filterable {

    private List<Model_Cities> cityList, cityListFiltered;
    public CitiesListener citiesListener;

    public class MyViewHolder extends RecyclerView.ViewHolder {
        private final RowCityBinding rowCityBinding;

        public MyViewHolder(View itemView) {
            super(itemView);
            rowCityBinding = RowCityBinding.bind(itemView);
//            itemView.setOnClickListener(v -> recyclerViewItemClickListener.onCitySelected(cityListFiltered.get(getBindingAdapterPosition())));
        }
    }

    public Adapter_Cities(CitiesListener citiesListener) {
        this.citiesListener = citiesListener;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_city, parent, false);
        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(Adapter_Cities.MyViewHolder holder, int position) {
        holder.rowCityBinding.setModel(cityListFiltered.get(position));
        holder.rowCityBinding.executePendingBindings();
    }

    public void setAdapterData(List<Model_Cities> cityList) {
        this.cityList = cityList;
        this.cityListFiltered = cityList;
        notifyDataSetChanged();
    }

    @Override
    public int getItemCount() {
        return cityListFiltered == null ? 0 : cityListFiltered.size();
    }

    public interface CitiesListener {
        void onCitySelected(Model_Cities city);
    }

}

**

Вот мой макет XML:

**

<data>

    <variable
        name="callback"
        type="com.base.assignment.adapters.Adapter_Cities.CitiesListener" />

    <variable
        name="model"
        type="com.base.assignment.models.Model_Cities" />
</data>

<androidx.cardview.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginStart="15dp"
    android:layout_marginTop="8dp"
    android:layout_marginEnd="15dp"
    android:background="@color/white"
    android:onClick="@{()->callback.onCitySelected(model)}">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="10dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{model.title}"
            android:textColor="@color/black"
            android:textSize="15sp"
            android:textStyle="bold" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{model.subTitle}"
            android:textColor="@color/black"
            android:textSize="12sp" />

    </LinearLayout>
</androidx.cardview.widget.CardView>

**

Вот результат, который я получил:

**

Мое фактическое требование заключается в том, что когда пользователь щелкает элемент RecyclerView, приложение должно отображать DialogFragment, который должен вызываться фрагментом. Итак, я пытаюсь вызвать onClick макета RecyclerView через XML, и действие, которое должно произойти при нажатии, -> Информация о выбранном элементе должна быть отправлена ​​во фрагмент с объектом модели в качестве параметра.

Принимая во внимание, что когда я нажимал на элемент Recyclerview, никаких действий не происходило. Нет сбоев, нет информации в logcat, нет обновлений в пользовательском интерфейсе приложения.

Поскольку DataBinding показывает ошибки времени компиляции, я вижу следующие ошибки: enter image description here

И прямо к этому, я вижу детали кода проблемы (прикрепленные ниже): enter image description here

Источник

Ответы (1)

avatar
androidLearner
1 июля 2021 в 18:13
1

Для этого установите интерфейс прослушивателя для макета в onBindViewHolder().

 @Override
public void onBindViewHolder(Adapter_Cities.MyViewHolder holder, int position) {
    holder.rowCityBinding.setCallback(citiesListener);
    holder.rowCityBinding.setModel(cityListFiltered.get(position));
    holder.rowCityBinding.executePendingBindings();
}
Nikhil Reddy
2 июля 2021 в 04:10
1

Спасибо! Потратил день, пытаясь понять это, Вы решили это всего с 1 строкой кода.