如何使用数据绑定从 Xml 调用接口方法?
How to Call Interface method from Xml using Data Binding?
这是我的片段:
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 Item 时,应用程序必须显示一个 DialogFragment,该 DialogFragment 应由 Fragment 调用。所以,我试图通过 XML 触发 RecyclerView 布局的 onClick,点击时应该发生的动作是 -> 被点击项目的信息应该被发送到带有模型对象作为参数的 Fragment。
而当我点击 Recyclerview 项目时,没有任何动作发生。没有崩溃,logcat 中没有信息,App UI 中没有更新。
由于 DataBinding 显示编译时错误,我看到以下错误:
对了,我看到了问题的代码细节(如下附件):
为此,在 onBindViewHolder() 中设置用于布局的侦听器界面。
@Override
public void onBindViewHolder(Adapter_Cities.MyViewHolder holder, int position) {
holder.rowCityBinding.setCallback(citiesListener);
holder.rowCityBinding.setModel(cityListFiltered.get(position));
holder.rowCityBinding.executePendingBindings();
}
这是我的片段:
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 Item 时,应用程序必须显示一个 DialogFragment,该 DialogFragment 应由 Fragment 调用。所以,我试图通过 XML 触发 RecyclerView 布局的 onClick,点击时应该发生的动作是 -> 被点击项目的信息应该被发送到带有模型对象作为参数的 Fragment。
而当我点击 Recyclerview 项目时,没有任何动作发生。没有崩溃,logcat 中没有信息,App UI 中没有更新。
由于 DataBinding 显示编译时错误,我看到以下错误:
对了,我看到了问题的代码细节(如下附件):
为此,在 onBindViewHolder() 中设置用于布局的侦听器界面。
@Override
public void onBindViewHolder(Adapter_Cities.MyViewHolder holder, int position) {
holder.rowCityBinding.setCallback(citiesListener);
holder.rowCityBinding.setModel(cityListFiltered.get(position));
holder.rowCityBinding.executePendingBindings();
}