问题
I have my viewmodels contained in a "ViewModels" package. When setting one of them as a data variable type in my fragment layout xml file the generated ViewDataBinding class attempts to import the package as if it were a file. For example:
import com.xyz.myapp.ViewModels;
Rather than:
import com.xyz.myapp.ViewModels.*;
It then goes on to reference the viewmodel as ViewModels.MyFragmentViewModel
causing further errors. I found that a workaround for this is to put all my viewmodel files in my com.xyz.myapp directory. When doing this everything works fine.
This is the same as asked here. I don't have enough reputation to comment. Am I missing something? Is there some option I need to set? Or is this just a bug?
TestFragment.java
public class TestFragment extends Fragment {
@Inject
MyViewModelFactory viewModelFactory;
private MyFragmentViewModel vm;
public TestFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
vm = ViewModelProviders.of(this, viewModelFactory).get(MyFragmentViewModel.class);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
FragmentTestBinding binding = DataBindingUtil.inflate(inflater, R.layout.fragment_test, container, false);
View view = binding.getRoot();
binding.setVm(vm);
return view;
}
@Override
public void onAttach(Context context) {
AndroidSupportInjection.inject(this);
super.onAttach(context);
}
@Override
public void onDetach() {
super.onDetach();
}
}
fragment_test.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="vm"
type="com.xyz.myapp.ViewModels.MyFragmentViewModel"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:text="@{vm.TEMP}" />
</LinearLayout>
</layout>
MyFragmentViewModel.java
public class MyFragmentViewModel extends ViewModel {
public MyFragmentViewModel (){}
public String TEMP = "TEST STRING";
}
FragmentTestBinding.java
This is the generated class. Error lines are commented. 4 errors
import com.xyz.myapp.ViewModels; //Error
public abstract class FragmentTestBinding extends ViewDataBinding {
@NonNull
public final CheckBox checkBox;
@NonNull
public final EditText editText;
@Bindable
protected ViewModels.ProfileViewModel mVm; //Error
protected FragmentTestBinding(DataBindingComponent _bindingComponent, View _root,
int _localFieldCount, CheckBox checkBox, EditText editText) {
super(_bindingComponent, _root, _localFieldCount);
this.checkBox = checkBox;
this.editText = editText;
}
public abstract void setVm(@Nullable ViewModels.ProfileViewModel vm); //Error
@Nullable
public ViewModels.ProfileViewModel getVm() { //Error
return mVm;
}
@NonNull
public static FragmentTestBinding inflate(@NonNull LayoutInflater inflater,
@Nullable ViewGroup root, boolean attachToRoot) {
return inflate(inflater, root, attachToRoot, DataBindingUtil.getDefaultComponent());
}
@NonNull
public static FragmentTestBinding inflate(@NonNull LayoutInflater inflater,
@Nullable ViewGroup root, boolean attachToRoot, @Nullable DataBindingComponent component) {
return DataBindingUtil.<FragmentTestBinding>inflate(inflater, com.camapps.linkshare.R.layout.fragment_test, root, attachToRoot, component);
}
@NonNull
public static FragmentTestBinding inflate(@NonNull LayoutInflater inflater) {
return inflate(inflater, DataBindingUtil.getDefaultComponent());
}
@NonNull
public static FragmentTestBinding inflate(@NonNull LayoutInflater inflater,
@Nullable DataBindingComponent component) {
return DataBindingUtil.<FragmentTestBinding>inflate(inflater, com.camapps.linkshare.R.layout.fragment_test, null, false, component);
}
public static FragmentTestBinding bind(@NonNull View view) {
return bind(view, DataBindingUtil.getDefaultComponent());
}
public static FragmentTestBinding bind(@NonNull View view,
@Nullable DataBindingComponent component) {
return (FragmentTestBinding)bind(component, view, com.camapps.linkshare.R.layout.fragment_test);
}
}
Compiler Output
Java compiler: (4 errors)
C:/Users/user/AndroidStudioProjects/myapp
app/build/generated/data_binding_base_class_source_out/debug/dataBindingGenBaseClassesDebug/out
com/xyz/myapp/databinding/FragmentTestBinding.java
error: cannot find symbol class ViewModels
error: package ViewModels does not exist
error: package ViewModels does not exist
error: package ViewModels does not exist
回答1:
This is an interesting issue that shows the need to follow conventions. As stated in Android - Package Name convention,
Android follows normal java package conventions
and Oracle suggests that
Package names are written in all lower case to avoid conflict with the names of classes or interfaces.
Now the Android Data Binding Library or another dependent library tries to create clean code and considers the class name to be ViewModels.ProfileViewModel
, following and expecting the general Java naming conventions.
To fix your issue, start to follow the given conventions and rename your package to viewmodels
.
来源:https://stackoverflow.com/questions/52808934/generated-viewdatabinding-class-in-android-studio-3-2-1-has-an-error-when-view-l