Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Finding the View

A6c0dcba5f373b33df2c2c55540faab1?s=47 Hadi Tok
November 24, 2019
85

Finding the View

On Android, there are many ways to interact with the views created with the XML files. This presentation reviews how things work in the background.

A6c0dcba5f373b33df2c2c55540faab1?s=128

Hadi Tok

November 24, 2019
Tweet

Transcript

  1. Finding the view Hadi Tok CitizenMe @hadi_tok

  2. findViewById(int id)

  3. View.findViewById(int id) /** * Finds the first descendant view with

    the given ID, the view itself if * the ID matches getId(), or null if the ID is invalid */
  4. View.findViewById(int id) Generally used to access views generated with LayoutInflater

  5. LayoutInflater

  6. LayoutInflater /** * Instantiates a layout XML file into its

    corresponding View */
  7. @Override public void setContentView(@LayoutRes int layoutResID ) { getDelegate().setContentView( layoutResID

    ); }
  8. LayoutInflater.from(mContext).inflate( layoutResID , contentParent);

  9. final XmlResourceParser parser = res.getLayout( layoutResID );

  10. final String name = parser .getName();

  11. clazz = mContext.getClassLoader().loadClass( prefix != null ? (prefix + name)

    : name ).asSubclass(View.class);
  12. constructor = clazz .getConstructor(mConstructorSignature);

  13. final View view = constructor .newInstance(args);

  14. root.addView( view , params);

  15. findViewById(int id)

  16. @Override public <T extends View> T findViewById(@IdRes int id) {

    return getDelegate().findViewById( id ); }
  17. return (T) mWindow.findViewById( id );

  18. return getDecorView().findViewById( id );

  19. if ( id == mID) { return (T) this; }

  20. for (int i = 0; i < len; i++) {

    View v = mChildren[i]; v = v.findViewById( id ); if (v != null) { return (T) v; } } return null;
  21. Data Binding

  22. Data Binding Allows you to bind UI components in your

    layouts to data sources in your app using a declarative format rather than programmatically
  23. Data Binding Allows you to bind UI components in your

    layouts to data sources in your app using a declarative format rather than programmatically
  24. Data Binding Allows you to bind UI components in your

    layouts to data sources in your app using a declarative format rather than programmatically
  25. <?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <data> <variable name="viewModel" type="com.example.main.MainViewModel"

    /> </data> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="@{ viewModel.text }" /> </layout> https://viblo.asia/p/understanding-data-bindings-generated-code-and-how-does-android-data-binding-compiler-work-Ljy5Vd1yZra
  26. public class MainActivity extends AppCompatActivity { @Inject MainViewModel viewModel; @Override

    protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActivityMainBinding bind = DataBindingUtil.setContentView(this, R.layout.activity_main); bind.setViewModel(viewModel); } }
  27. public class MainViewModel extends ViewModel { public final ObservableField<String> text

    = new ObservableField<>(); }
  28. <?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <data> <variable name="viewModel" type="com.example.main.MainViewModel"

    /> </data> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="@{ viewModel.text }" /> </layout> https://viblo.asia/p/understanding-data-bindings-generated-code-and-how-does-android-data-binding-compiler-work-Ljy5Vd1yZra
  29. <TextView xmlns:android="http://schemas.android.com/apk/res/ android" android:layout_width="match_parent" android:layout_height="match_parent" android:tag="layout/activity_main_0" />

  30. <?xml version="1.0" encoding="utf-8" standalone="yes"?> <Layout layout="activity_main" absoluteFilePath="/home/framgia/Projects/harpa-crista/harpacrista/ android/app/src/main/res/layout/activity_main.xml" directory="layout" isMerge="false"

    modulePackage="com.harpacrista"> <Variables declared="true" name="viewModel" type="com.example.main.MainViewModel"> <location endLine="8" endOffset="51" startLine="6" startOffset="8" /> </Variables> <Imports name="View" type="android.view.View"> <location endLine="10" endOffset="42" startLine="10" startOffset="8" /> </Imports> <Targets> <Target tag="layout/activity_main_0" view="TextView"> <Expressions> <Expression attribute="android:text" text=" viewModel.text "> <Location endLine="16" endOffset="41" startLine="16" startOffset="8" /> <TwoWay>false</TwoWay> <ValueLocation endLine="16" endOffset="39" startLine="16" startOffset="24" /> </Expression> </Expressions> <location endLine="16" endOffset="44" startLine="14" startOffset="4" /> </Target> </Targets> </Layout>
  31. public class ActivityMainBinding extends android.databinding.ViewDataBinding { … /** * Where

    the magic happens */ }
  32. Kotlin Android Extensions(Synthetics)

  33. Kotlin Android Extensions plugin Allows us to obtain the same

    experience we have with some of these libraries, without having to add any extra code.
  34. apply plugin: 'kotlin-android-extensions'

  35. androidExtensions { experimental = true }

  36. res/layout/activity_free.xml

  37. res/layout/activity_free.xml import kotlinx.android.synthetic.activity_free.*

  38. res/layout/activity_free.xml import kotlinx.android.synthetic.activity_free.* textView.text = “DevFest"

  39. import kotlinx.android.synthetic.main.activity_splash.* class PresentationActivity: BaseActivity() { override fun onCreate(savedInstanceState: Bundle?,

    persistentState: PersistableBundle?) { super.onCreate(savedInstanceState, persistentState) setContentView(R.layout.activity_splash) logoIv.visibility = View.VISIBLE } }
  40. public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { super.onCreate(savedInstanceState,

    persistentState); this.setContentView(-1300174); ImageView var10000 = (ImageView)this._$_findCachedViewById(id.logoIv); Intrinsics.checkExpressionValueIsNotNull(var10000, "logoIv"); var10000.setVisibility(0); }
  41. private HashMap _$_findViewCache; public View _$_findCachedViewById(int var1) { if (this._$_findViewCache

    == null) { this._$_findViewCache = new HashMap(); } View var2 = (View)this._$_findViewCache.get(var1); if (var2 == null) { var2 = this.findViewById(var1); this._$_findViewCache.put(var1, var2); } return var2; }
  42. View Binding

  43. View Binding Is a feature that allows you to more

    easily write code that interacts with views. Once view binding is enabled in a module, it generates a binding class for each XML layout file present in that module.
  44. android { ... viewBinding { enabled = true } }

  45. <LinearLayout ... > <TextView android:id="@+id/name" /> <ImageView android:cropToPadding="true" /> <Button

    android:id="@+id/button" android:background="@drawable/rounded_button" /> </LinearLayout>
  46. private lateinit var binding: ResultProfileBinding @Override fun onCreate(savedInstanceState: Bundle) {

    super.onCreate(savedInstanceState) binding = ResultProfileBinding.inflate(layoutInflater) setContentView(binding.root) }
  47. binding.name.text = viewModel.name binding.button.setOnClickListener { viewModel.userClicked() }

  48. Jetpack Compose

  49. Jetpack Compose Android’s modern toolkit for building native UI

  50. class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) setContent { Greeting("Android") } } } @Composable fun Greeting(name: String) { Text(text = "Hello $name!") }
  51. Questions?

  52. Hadi Tok, CitizenMe @hadi_tok Thank you!