Android ViewBinding
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
}
}
public class MyFragment extends Fragment {
private FragmentMyBinding binding;
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentMyBinding.inflate(inflater, container, false);
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
Kotlin
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
}
}
class MyFragment : Fragment() {
private var _binding: FragmentMyBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentMyBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
利用委托配合 ::inflate
inline fun <T : ViewBinding> ComponentActivity.viewBinding(
crossinline bindingInflater: (LayoutInflater) -> T
) = lazy(LazyThreadSafetyMode.NONE) {
bindingInflater(layoutInflater)
}
class MainActivity : ComponentActivity() {
private val binding by viewBinding(ActivityMainBinding::inflate)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
}
}
class FragmentViewBindingDelegate<T : ViewBinding>(
private val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> T,
private val fragment: Fragment
) : ReadOnlyProperty<Fragment, T> {
private var binding: T? = null
fun createView(inflater: LayoutInflater, container: ViewGroup?): View {
binding = bindingInflater(inflater, container, false)
fragment.viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onDestroy(owner: LifecycleOwner) {
binding = null
}
})
return binding!!.root
}
override fun getValue(thisRef: Fragment, property: KProperty<*>): T {
return binding ?: throw IllegalStateException(
"Binding only valid between onCreateView and onDestroyView"
)
}
}
fun <T : ViewBinding> Fragment.viewBindingDelegate(
bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> T
) = FragmentViewBindingDelegate(bindingInflater, this)
class MyFragment : Fragment() {
private val bindingDelegate = viewBindingDelegate(FragmentMyBinding::inflate)
private val binding by bindingDelegate
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = bindingDelegate.createView(inflater, container)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
}
利用委托配合 ::bind
inline fun <T : ViewBinding> Fragment.viewBinding(
crossinline bindingBinder: (View) -> T
) = object : ReadOnlyProperty<Fragment, T> {
private var binding: T? = null
override fun getValue(thisRef: Fragment, property: KProperty<*>): T {
if (binding == null) {
val view = thisRef.view ?: throw IllegalStateException(
"Binding only valid between onCreateView and onDestroyView"
)
binding = bindingBinder(view)
thisRef.viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onDestroy(owner: LifecycleOwner) {
binding = null
}
})
}
return binding!!
}
}
class MyFragment : Fragment() {
private val binding by viewBinding(FragmentMyBinding::bind)
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return inflater.inflate(R.layout.fragment_my, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
}