ViewBinding - how to get binding for included layouts?

后端 未结 4 864
北恋
北恋 2020-12-08 04:15

While working with ViewBinding I come across few not documented cases.

First: How to get binding for included generic view layout parts, main binding see only items

相关标签:
4条回答
  • 2020-12-08 04:34

    Your first question, that is working with an included layout using ViewBinding can be solved so easily.

    Here is a sample main_fragment.xml file

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycler_view_main"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />
    
        <include
            android:id="@+id/toolbar"
            layout="@layout/toolbar" />
    
    </LinearLayout>
    

    And MainFragment.java can be like this

    public class MeaningFragment extends Fragment {
    
        private MainFragmentBinding binding;
        private ToolbarBinding toolbarBinding;
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
    
            binding = MainFragmentBinding.inflate(inflater, container, false);
            toolbarBinding = binding.toolbar;
    
            return binding.getRoot();
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
    
            toolbarBinding = null;
            binding = null;
        }
    }
    

    Now, you have two bindings. one of them is the default and the next one is from the included layout.

    0 讨论(0)
  • 2020-12-08 04:39

    The other simple way would be using the data binding library. Then wrap your XML layout with tag so that if you are using the library automatically generates the classes required to bind the views in the layout with your data objects. Honestly, I think it's the way to go. Follow the guide here

    0 讨论(0)
  • 2020-12-08 04:45

    In the include layout you must create a Container layout and put here the id.

    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/example"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toTopOf="parent">
        </androidx.constraintlayout.widget.ConstraintLayout>
    </androidx.constraintlayout.widget.ConstraintLayout>
    
    0 讨论(0)
  • 2020-12-08 04:49

    In case of:

    1. Include with generic layout (not merge node), we need to assign ID to included part, this way in binding we will have access to included sub part
    <include
        android:id="@+id/your_id"
        layout="@layout/some_layout" />
    

    This way in your activity code:

    private lateinit var exampleBinding: ActivityExampleBinding  //activity_example.xml layout
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        exampleBinding = ActivityExampleBinding.inflate(layoutInflater)
        setContentView(exampleBinding.root)
        //we will be able to access included layouts view like this
        val includedView: View = exampleBinding.yourId.idOfIncludedView
    //[...]
    }
    
    1. Include with merge block in external layout. We can't add ID to it because merge block is not a view. Let's say we have such eternal merge layout (merge_layout.xm):
    <?xml version="1.0" encoding="utf-8"?>
    <merge xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        tools:showIn="@layout/activity_example">
    
        <TextView
            android:id="@+id/some_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World" />
    </merge>
    

    To properly bind such merge layout we need to:

    In your activity code:

    private lateinit var exampleBinding: ActivityExampleBinding  //activity_example.xml layout
    private lateinit var mergeBinding: MergeLayoutBinding  //merge_layout.xml layout
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        exampleBinding = ActivityExampleBinding.inflate(layoutInflater)
        //we need to bind the root layout with our binder for external layout
        mergeBinding = MergeLayoutBinding.bind(exampleBinding.root)
        setContentView(exampleBinding.root)
        //we will be able to access included in merge layout views like this
        val mergedView: View = mergeBinding.someView
    //[...]
    }
    
    0 讨论(0)
提交回复
热议问题