私は公式のGoogleドキュメントからのデータバインディングの例に従うことを試みています https://developer.Android.com/tools/data-binding/guide.html
ただし、アクティビティではなくフラグメントにデータビッディングを適用しようとしている点が異なります。
コンパイル時に現在発生しているエラー
Error:(37, 27) No resource type specified (at 'text' with value '@{marsdata.martianSols}.
フラグメントのonCreate
は、次のようになります。
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MartianDataBinding binding = MartianDataBinding.inflate(getActivity().getLayoutInflater());
binding.setMarsdata(this);
}
フラグメントのonCreateView
は、次のようになります。
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.martian_data, container, false);
}
そして私のフラグメントのレイアウトファイルの一部はこのようになります:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:Android="http://schemas.Android.com/apk/res/Android">
<data>
<variable
name="marsdata"
type="uk.co.darkruby.app.myapp.MarsDataProvider" />
</data>
...
<TextView
Android:layout_height="wrap_content"
Android:layout_width="wrap_content"
Android:text="@{marsdata.martianSols}"
/>
</RelativeLayout>
</layout>
私の疑いは、MartianDataBinding
がどのレイアウトファイルにバインドされることになっているのかわからないということです - それゆえエラーです。助言がありますか?
データバインディングの実装は、フラグメントのonCreateView
メソッドに含まれている必要があります。OnCreate
メソッドに存在するすべてのデータバインディングを削除します。onCreateView
は、次のようになります。
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
MartianDataBinding binding = DataBindingUtil.inflate(
inflater, R.layout.martian_data, container, false);
View view = binding.getRoot();
//here data must be an instance of the class MarsDataProvider
binding.setMarsdata(data);
return view;
}
DataBindingUtilではなく、生成されたBindingのinflate
メソッドを使用することをお勧めします。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
MainFragmentBinding binding = MainFragmentBinding.inflate(inflater, container, false);
//set variables in Binding
return binding.getRoot();
}
DataBindingUtil.inflate()のドキュメント :
このバージョンは、layoutIdが事前に不明な場合にのみ使用してください。それ以外の場合は、生成されたBindingのinflateメソッドを使用して、タイプセーフなインフレーションを確保します。
Android DataBindingでこれを試してください
FragmentMainBinding binding;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_main, container, false);
View rootView = binding.getRoot();
initInstances(savedInstanceState);
return rootView;
}
下記のようにビューオブジェクトを取得するだけです。
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = DataBindingUtil.inflate(inflater, R.layout.layout_file, container, false).getRoot();
return view;
}
他の答えでもうまくいくかもしれませんが、私は最善のアプローチを教えてほしいのです。
Binding class's inflate
を使用してください。1つのオプションはDataBindingUtil
で展開することですが、あなただけがバインディングクラスを生成したことがわからないとき。
- binding class
を自動生成した場合は、DataBindingUtil
を使用する代わりにそのクラスを使用します。
Javaでは
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
HomeFragmentBinding binding = HomeFragmentBinding.inflate(inflater, container, false);
//set binding variables here
return binding.getRoot();
}
コトリン
lateinit var binding: HomeFragmentBinding
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
binding = HomeFragmentBinding.inflate(inflater, container, false)
return binding.root
}
DataBindingUtilクラスドキュメントでご覧になれます。
膨らませる
T inflate (LayoutInflater inflater, int layoutId, ViewGroup parent, boolean attachToParent)
このバージョンは、layoutIdが事前にわからない場合にのみ使用してください。それ以外の場合は、生成されたBindingのinflateメソッドを使用して、タイプセーフなインフレーションを確保します。
あなたのレイアウトビニングクラスが生成されていない場合@Seeこの答え。
私のコードで作業しています。
private FragmentSampleBinding dataBiding;
private SampleListAdapter mAdapter;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
dataBiding = DataBindingUtil.inflate(inflater, R.layout.fragment_sample, null, false);
return mView = dataBiding.getRoot();
}
データバインディングフラグメントの完全な例
FragmentMyProgramsBindingは、res/layout/fragment_my_programsに対して生成されたバインディングクラスです。
public class MyPrograms extends Fragment {
FragmentMyProgramsBinding fragmentMyProgramsBinding;
public MyPrograms() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
FragmentMyProgramsBinding fragmentMyProgramsBinding = DataBindingUtil.inflate(inflater, R
.layout.fragment_my_programs, container, false);
return fragmentMyProgramsBinding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
}
ViewModelおよびLiveDataを使用している場合これで十分な構文です。
コトリンの構文:
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return MartianDataBinding.inflate(
inflater,
container,
false
).apply {
setLifecycleOwner(this@MartianData)
vm = viewModel // Attach your view model here
}.root
}
コトリンの構文:
lateinit var binding: MartianDataBinding
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
binding = DataBindingUtil.inflate(inflater, R.layout.martian_data, container, false)
return binding.root
}
ほとんどの人が言ったように、LifeCycleOwnerを設定することを忘れないでください
Javaのサンプルつまり
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
BindingClass binding = DataBindingUtil.inflate(inflater, R.layout.fragment_layout, container, false);
ModelClass model = ViewModelProviders.of(getActivity()).get(ViewModelClass.class);
binding.setLifecycleOwner(getActivity());
binding.setViewmodelclass(model);
//Your codes here
return binding.getRoot();
}
コトリンのもう一つの例:
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val binding = DataBindingUtil
.inflate< MartianDataBinding >(
inflater,
R.layout.bla,
container,
false
)
binding.modelName = // ..
return binding.root
}
"MartianDataBinding"という名前は、レイアウトファイルの名前によって異なります。ファイルの名前が "martian_data"の場合、正しい名前はMartianDataBindingになります。
誰もがinflate()
について言っていますが、onViewCreated()
でそれを使用したいとしたらどうでしょうか。
ViewDataBinding
のview
インスタンスを取得するには、具象バインディングクラスのbind(view)
メソッドを使用できます。
通常、私たちはBaseFragmentを次のように書きます(単純化されています)。
// BaseFragment.kt
abstract fun layoutId(): Int
override fun onCreateView(inflater, container, savedInstanceState) =
inflater.inflate(layoutId(), container, false)
そして子フラグメントでそれを使用してください。
// ConcreteFragment.kt
override fun layoutId() = R.layout.fragment_concrete
override fun onViewCreated(view, savedInstanceState) {
val binding = FragmentConcreteBinding.bind(view)
// or
val binding = DataBindingUtil.bind<FragmentConcreteBinding>(view)
}
すべてのフラグメントがデータバインディングを使用している場合は、typeパラメータを使用して簡単にすることもできます。
abstract class BaseFragment<B: ViewDataBinding> : Fragment() {
abstract fun onViewCreated(binding: B, savedInstanceState: Bundle?)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
onViewCreated(DataBindingUtil.bind<B>(view)!!, savedInstanceState)
}
}
私はそれがnull以外を主張しても大丈夫かどうかわかりませんが、..あなたはアイデアを得ます。それをNULL可能にしたい場合は、それを実行できます。