NextFocus editText in include layout - android

I create a simple layout containing my label and my editText. This layout is included several time to create a form.
But with this method the "nextFocus" function doesn't work properly and I can't find a solution. I need to give the id of the next editText but because it's inside a include layout, the id is the same as the current editText.
Is their a way to achieve this by using only xml solution? I particulary think of databinding.
This is my layout's :
The include layout :
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewModel"
type="viewModels.StringDataTypeViewModel"/>
<variable
name="nextFocus"
type="Integer"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="horizontal"
android:gravity="center_vertical">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
tools:text="Nom de famille : "
android:text="#{viewModel.label}"
android:singleLine="true"
android:ellipsize="end"/>
<EditText android:id="#+id/value"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="#dimen/patient_detail_edittext_text_size"
android:inputType="textPersonName"
android:ellipsize="end"
tools:text="Dupont"
android:text="#={viewModel.value}"
android:textColor="#android:color/widget_edittext_dark"
android:clickable="#{viewModel.editable}"
android:cursorVisible="#{viewModel.editable}"
android:focusable="#{viewModel.editable}"
android:focusableInTouchMode="#{viewModel.editable}"
android:background="#{viewModel.editable ? #android:drawable/edit_text : #drawable/empty_drawable}"
android:nextFocusForward="#id/value"/>
</LinearLayout>
The form layout :
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="#{viewModel.editable ? View.VISIBLE: View.GONE}">
<include layout="#layout/string_data_type_layout"
app:viewModel="#{viewModel.familyNameViewModel}" />
<include layout="#layout/string_data_type_layout"
app:viewModel="#{viewModel.givenNameViewModel}" />
<include layout="#layout/string_data_type_layout"
app:viewModel="#{viewModel.patientCodeViewModel}" />
<include layout="#layout/string_data_type_layout"
app:viewModel="#{viewModel.addressViewModel}" />
</LinearLayout>

Step 1: Give unique ids to all your include elements
<include android:id="#+id/edit_text_1"
... />
<include android:id="#+id/edit_text_2"
... />
Step 2: Add these attributes to the root of your included layout xml (LinearLayout in your case)
<LinearLayout
android:descendantFocusability="afterDescendants"
android:focusableInTouchMode="true"
... />
Step 3: Use the ids defined in step 1 in all your include elements (as per required navigation)
<include android:id="#+id/edit_text_1"
app:nextFocus="#{#id/edit_text_2}"
... />
Cheers!

Can you try to change the id of EditText?
This is work for me:
1.The include Layout:
<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
...
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
...>
...
<EditText android:id="#+id/et_common"
.../>
</LinearLayout>
2.Create an id in ids.xml
<item name="next_focus_et" type="id"/>
3.Set next focus on another view
<Button
android:id="#+id/btn"
android:nextFocusUp="#id/next_focus_et"
.../>
4.Change the id of EidtText to "next_focus_et" in the code.
private void initComplexNextFocus(){
mBinding.includeStaticDns2Edit.et_common.setId(R.id.next_focus_et);
}

Related

Android: no view IDs are available inside a ScrollView for ViewBinding. How to access?

I am trying to convert an existing project with findViewByIds over to ViewBinding. All of the view IDs outside of the ScrollView are available in Android Studio for use with "binding.viewId..." The problem is none of the views with IDs that are within the ScrollView are available for use with "binding.viewID..." So I am not able to access ImageViews that are within two <include layouts that are within a ViewFlipper in the layout. The simple ViewFlipper toggles between an up arrow ImageView and a down arrow ImageView. The ViewFlipper has an <include layout for the up ImageView and a second <include layout for the down ImageView. The ViewFlipper is inside a LinearLayout and the LinearLayout is inside the ScrollView.
//Activity
private ActivityEditBinding binding;
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityEditBinding.inflate(getLayoutInflater());
View view = binding.getRoot();
setContentView(view);
// activity_edit.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:focusableInTouchMode="true"
tools:context=".AddorUpdateCardActivity">
...
<RelativeLayout
android:id="#+id/secondLinearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/toolbar" >
<ScrollView
android:id="#+id/ScrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/secondLinearLayout"
... >
<LinearLayout
android:id="#+id/lowerVFRow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingRight="5dp"
android:paddingEnd="5dp"
android:orientation="horizontal" >
<ViewFlipper
android:id="#+id/expandVF"
android:layout_width="wrap_content"
android:layout_height="44dp"
android:layout_marginBottom="5dp" >
<include layout="#layout/expand_more_act_edit"
android:id="#+id/expandMore" />
<include layout="#layout/expand_less_act_edit"
android:id="#+id/expandLess" />
</ViewFlipper>
</LinearLayout>
</ScrollView>
</RelativeLayout>
// expand_more_act_edit.xml
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/downArrow"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:contentDescription="sd"
android:clickable="true"
android:focusable="true"
android:src="#drawable/ic_expand_more" />
<!-- the down arrow -->
I confirmed that the autogenerated ViewBinding classes have been created. Below is where I am trying to attach a ClickListener to the downArrow but I can't access the downArrow reference. What am I missing here?
***Android Studio says "Cannot resolve symbol 'expandMore'***
binding.expandMore.downArrow.setOnClickListener(v -> {
// change the down arrow to the up arrow and show the 1-20 EditText lines.
expandVF.setDisplayedChild(expandVF.indexOfChild(findViewById(R.id.expandLess)));
moreViewStub.setVisibility(View.VISIBLE);
});
Does ViewBinding not work within a ScrollView? What am I missing here?
View binding will generate camelCase id from id that you have provided in your layout.If your view id is already in camelCase(expandVF) in your layout,sometimes android studio won't recognize that because layout view id and binding class view id are same.that may produce 'Cannot resolve symbol error'.
so instead of expandVF,expandMore,expandLess use expand_vf,expand_more,expand_less.Rebuild and run,may work.
You need to use binding.expandVF instead of directly using expandVF
and to use id of layout which have been included, you need to use binding.expandLess.ID_YOU_WANT_TO_USE
In your case, I don't see the problem in the code so I'm guessing maybe the Android build tool version is quite old - ViewBinding doesn't work very well
Try to update the build tools to the latest version 4.2.0 in build.gradle of project
dependencies {
// At least it should be from 4.0.0
classpath 'com.android.tools.build:gradle:4.2.0'
}
And distributionUrl in gradle-wrapper.properties
# tools.build 4.2.0 requruired gradle distribution at least 6.7.1+
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip
Change the viewBinding declaration if it is different from the code below:
buildFeatures{
viewBinding = true
}
Then Clean-Rebuild your project.
Check out Compatibility Android Gradle plugin - Release Notes
convert your activity_edit.xml, expand_less_act_edit.xml, and expand_more_act_edit.xml layout into data binding by wrapping into layout tag.
your activity_edit.xml will look like
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:focusableInTouchMode="true"
tools:context=".AddorUpdateCardActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<LinearLayout
android:id="#+id/lowerVFRow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingRight="5dp"
android:paddingEnd="5dp"
android:orientation="horizontal" >
<ViewFlipper
android:id="#+id/expandVF"
android:layout_width="wrap_content"
android:layout_height="44dp"
android:layout_marginBottom="5dp" >
<include layout="#layout/expand_more_act_edit"
android:id="#+id/expandMore" />
<include layout="#layout/expand_less_act_edit"
android:id="#+id/expandLess" />
</LinearLayout>
</ScrollView>
</RelativeLayout>
</layout>
your expand_more_act_edit.xml will look like
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:id="#+id/downArrow"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:contentDescription="sd"
android:clickable="true"
android:focusable="true"
android:src="#drawable/ic_expand_more" />
</layout>
your main class to access the ImageView will be.
private ActivityEditBinding binding;
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding= DataBindingUtil.setContentView(this, R.layout.activity_edit);
//binding.expandMore.downArrow this is how you will gonna access the view. now do what ever you want with this.
}
It looks like you have missed ViewFlipper closing tag and there are other layout issues in xml. Check if that is the issue.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:focusableInTouchMode="true"
tools:context=".AddorUpdateCardActivity">
<RelativeLayout
android:id="#+id/secondLinearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/toolbar" >
<ScrollView
android:id="#+id/ScrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/secondLinearLayout">
<LinearLayout
android:id="#+id/lowerVFRow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingRight="5dp"
android:paddingEnd="5dp"
android:orientation="horizontal" >
<ViewFlipper
android:id="#+id/expandVF"
android:layout_width="wrap_content"
android:layout_height="44dp"
android:layout_marginBottom="5dp" >
<include layout="#layout/expand_more_act_edit"
android:id="#+id/expandMore" />
<include layout="#layout/expand_less_act_edit"
android:id="#+id/expandLess" />
</ViewFlipper>
</LinearLayout>
</ScrollView>
I've corrected some but not sure since I don't know the whole layout. Since there are some ellipses in the layout you have provided. Other than that ViewBinding has no issues with ScrollView AFAIK.
for databinding
in activity.java
private ActivityEditBinding binding;
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding= DataBindingUtil.setContentView(this, R.layout.activity_edit);
}
in activity_edit.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:focusableInTouchMode="true"
tools:context=".AddorUpdateCardActivity">//...
<ScrollView
<LinearLayout
android:id="#+id/lowerVFRow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingRight="5dp"
android:paddingEnd="5dp"
android:orientation="horizontal" >
<ViewFlipper
android:id="#+id/expandVF"
android:layout_width="wrap_content"
android:layout_height="44dp"
android:layout_marginBottom="5dp" >
<include layout="#layout/expand_more_act_edit"
android:id="#+id/expandMore" />
<include layout="#layout/expand_less_act_edit"
android:id="#+id/expandLess" />
</LinearLayout>
</ScrollView>
</RelativeLayout>
</layout>
now
binding.expandMore.downArrow.setOnClickListener(v -> {
});
for ViewBinding here

Pass data to <include> layout using Databinding

I've been searching this a lot today and only found some unclear answers regarding this question.
I'm having multiple TextView and EditText in a form, all of them being customised by my theme and i'd like to reuse the same included layout each time, but having parameters to it like the text inside the TextView or hint inside the EditText.
My form.xml right now:
<LinearLayout android: orientation="horizontal">
<TextView android:text="Username"/>
<EditText android:id="edittext_username"
android:hint="Enter username..."
android:inputType="text"/>
</LinearLayout>
<LinearLayout android: orientation="horizontal">
<TextView android:text="Password"/>
<EditText android:id="edittext_password"
android:hint="Enter password..."
android:inputType="password"/>
</LinearLayout>
... other fields ...
What i'd like in the main form.xml:
<LinearLayout android:orientation="vertical" ...>
<include layout="form_edittext"
app:textview_text="#{`Username`}"
app:edittext_hint="#{`Enter username...`}"
... other parameters ...
/>
<include layout="form_edittext"
app:textview_text="#{`Password`}"
app:edittext_hint="#{`Enter password...`}"
... other parameters ...
/>
</LinearLayout>
also the form_edittext.xml:
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="textview_text" type="java.lang.String"/>
<variable name="edittext_id" type="java.lang.String"/>
<variable name="edittext_inputType" type="java.lang.String"/>
<variable name="edittext_hint" type="java.lang.String"/>
</data>
<TextView android:text="#{textview_text}"/>
<EditText android:id="#{edittext_id}"
android:hint="#{edittext_hint}"
android:inputType="#{edittext_inputType}"/>
</layout>
I'm still a beginner and i do not know if this is possible.
On this post, the guy replied he used data binding (as in example shown by me)
How to Re-using Layouts with <include/> with parameters? (you may see the first answer).
However, using this method give me the error of XML not recognizing identifiers like "textview_text" (the variables that i'm accessing via #{...}. If you got other solutions i'd appreciate if you share them. Cheers!
UPDATE on iCantC's answer: (but the textview's text and the hint remain empty).
Main layout:
<?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"
xmlns:tools="http://schemas.android.com/tools">
...
<include layout="#layout/activity_login_layout_input"
android:id="#+id/activity_login_layout_input_emailAddress"
app:textviewt="#{#string/email}" //the string is "Email Address"
app:edittexth="#{#string/emailhint}" /> //the string is "Your email address..."
...
</layout>
Included layout:
<layout>
<data>
<variable
name="textviewt"
type="String"/>
<variable
name="edittexth"
type="String"/>
</data>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:showDividers="middle">
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{textviewt}"
android:textColor="#color/c1"
android:textSize="12sp"/>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="26dp">
<androidx.appcompat.widget.AppCompatEditText
android:id="#+id/edittext"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="center|start"
android:layout_marginStart="26dp"
android:background="#drawable/activity_login_background"
android:hint="#{edittexth}"
android:padding="6dp"
android:textAlignment="center"
android:textColor="#color/c2"
android:textColorHint="#color/grey"
android:textSize="14sp"/>
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_gravity="start"
android:adjustViewBounds="true"
android:src="#drawable/activity_login_edittext_drawable" />
</FrameLayout>
</LinearLayout>
</layout>
It seems like you want to include a common layout and then pass dynamic parameters from the main layout to included layout, here are the steps,
Step 1: Enable DataBinding in your project
//In the build.gradle file in the app module, add this
android {
...
dataBinding {
enabled = true
}
}
Step 2: Create your common_layout_included.xml
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="username"
type="String"/>
</data>
<LinearLayout
..
>
<TextView
android:id="#+id/tv_username"
android:text="#{username}"/>
</LinearLayout>
</layout>
Step 3: Include common_layout_included.xml in your main_layout.xml
<?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">
<LinearLayout
..
>
<include
android:id="#+id/includedLayout"
layout="#layout/common_layout_included"
app:username="#{#string/username}" // here we pass any String
/>
</LinearLayout>
</layout>
Step 4: Make sure you inflate the layout using DataBinding way
//In the onCreate of your Activity
val binding = DataBindingUtil.setContentView(this,R.layout.main_layout)
That's it, you are good to go. If still some error appears just do File -> Invalidate Caches/Restart
One last thing, I saw that you are assigning the id's to the view's dynamically android:id="#{edittext_id}", in all of my experience, I never really encountered a use case where I would be motivated to do this. I don't even know if it's possible and even if possible I doubt it's a good practice.

Inflating view taking too much time in onCreateView in fragment

I've using the Fragment inside the Navigation Drawer.
In Drawer there are 7 more option menus are presents and all other working fine.
Only this fragment tasking 3sec time to show the views.
I've find using debug mode, below this only line taking that much time to execute.
final View view=inflater.inflate(R.layout.fragment_vehicle_inspection,container,false);
Moreover I've using 4 include layout in XML part.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/lat_inspection_vendor_name_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="#dimen/margin_05dp"
android:orientation="horizontal">
<TextView
android:id="#+id/txt_inspection_vendor_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:drawableEnd="#drawable/ic_action_edit"
android:gravity="center"
android:maxLines="1"
android:textColor="#color/colorAccent"
android:textSize="#dimen/margin_15sp"
android:textStyle="bold" />
</LinearLayout>
<include
android:id="#+id/include_inspection_function_layout"
layout="#layout/fragment_inspection_function_layout_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/lat_inspection_vendor_name_layout"
android:layout_marginTop="#dimen/margin_05dp"
android:visibility="gone" />
<ScrollView
android:id="#+id/scroll_inspection"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/include_inspection_function_layout"
android:layout_marginTop="#dimen/margin_10dp"
android:focusableInTouchMode="true"
android:focusable="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include layout="#layout/fragment_inspection_vendor_details_card" />
<LinearLayout
android:id="#+id/lat_inspection_form"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone">
<include layout="#layout/fragment_inspection_vehicle_form_row_card" />
<include layout="#layout/fragment_inspection_vehicle_features_row_card" />
<include layout="#layout/fragment_inspection_vehicle_form_penalty_row_card" />
</LinearLayout>
</LinearLayout>
</ScrollView>
</RelativeLayout>
I hope include part is not affect inflate view.
I've using 26- EditText, 26-checkbox and 30-TextViews inside the include layout.
My concern is Inflating too much number of views only taking time.
Please assist me to encounter this problem.
Thanks in advance.
It's because too much view's in your layout file and yes include part affect your inflation process. Try to reduce number of view.
Share you layout design image so i can give you a suggestion.
It's because you are showing some high resolution image or any other background resource so it may happen to take some time to draw view in your fragment

How can I have one unique button in multiple components of a layout in android?

So I have an xml that consists of a linear layout containing a Button and a TextView like this:
<?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="100dp"
android:orientation="vertical">
<Button
android:id="#+id/btnCell"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:paddingLeft="40dp"
android:text="Button"
android:textColor="#color/blueText" />
<View
android:height="wrap_content"
android:width="wrap_content"
android:background="#drawable/Test"/>
</LinearLayout>
And I want to use this same layout inside other layouts in a different xml. I need the same button at every time, so I reuse it by including it in the two layouts (both layouts are in the same xml, but ones is hidden):
First one
<?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">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/image"
/>
<include layout="#layout/buttonLayout"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Second One:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/image"
/>
<include layout="#layout/buttonLayout"/>
<CheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
So I show the first layout and hide the second one at the beginning of the app , as the user moves within the interface, the layouts exchange so that the other one is shown and the first one hidden.
The thing is that I declare the Button in my java activity class like this:
btnCell = (Button) thirdView.findViewById(R.id.btnCell);
btnCell.setOnClickListener(this);
And implemented the listener.
#Override
public void onClick(View v) {
if (v == btnCell) {
System.out.println("entered if");
}
System.out.println("entered function");
}
The problem is that when I click the button when the first view is shown and the second hidden, the button works just fine, but when I unhide the second layout, hide the first one, and proceed to click the button, that should be the same as the first one but in a different layout, nothing happens. I searched and find out, that this happens because the id is assigned only to the button shown in the first layout because of view hierarchy, but not the one in the second layout. How can I make both buttons react to the same action, without declaring a new button in each layout but instead reusing it?
I have used this type of layout. you can create Id different for both and inflate that view and give different name so You can differentiate both thing.
<?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">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/image"
/>
<include android:id="+id/firstOne" layout="#layout/buttonLayout"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
android second one is
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/image"
/>
<include android:id="+id/secondTwo" layout="#layout/buttonLayout"/>
<CheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
The Problem is both the layout are include in same layout file and the id of that
button are same so whenever you click on any of the button at the same time event will fire on both button like both are clicked.
So, you have to give the different id for both the button I hope it works fine..
You can add a different Id for each included layout:
<include android:id="+id/layout_a" layout="#layout/buttonLayout"/>
and
<include android:id="+id/layout_b" layout="#layout/buttonLayout"/>
and then use two findViewById to reach them:
btnCellA = (Button)thirdView.findViewById(R.id.layout_a).findViewById(R.id.btnCell);
btnCellB = (Button)thirdView.findViewById(R.id.layout_b).findViewById(R.id.btnCell);

import xml into another xml

I have lots of control repeated in my xml (a Button for instance). Is there any possibility to write the Button once in a xml and then import it in all the layout I need it?
You can use
<include layout="#layout/commonlayout" android:id="#+id/id" />
commonlayout.xml should be defined in res/layout where you can add the repeated parts.
As Labeeb P rightly said, it works.
Just want to add that you can also override parameters too:
<include
layout="#layout/commonlayout"
android:id="#+id/id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="2sp"
android:layout_marginRight="2sp"
/>
In addition to those great answers, you can also avoid code duplication by using the <merge> tag, like so:
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/add"/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/delete"/>
</merge>
The <merge> part gets stripped when you include it into other xml. This might help including more than a single Button at a time. See the official documentation.
You can use the default include XML tag to include an external layout:
<include layout="#layout/somelayout" />
This layout should have an outside ViewGroup that encapsulates the content or a merge tag to avoid having to use an unnecessary layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_world" />
</LinearLayout>
<!-- OR -->
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_world" />
</merge>
Also, if you need a better way to include pieces of layout that acts like a container (a custom ViewGroup), you can use this custom ViewGroup. Note that this does not import an XML into another XML file, it inflates the content from the external layout and replaces into the view. It's similar to ViewStub, a "ViewGroupStub" like.
This lib acts as if the ViewStub could be used as following (note that this example does not work! ViewStub isn't a ViewGroup subclass!):
<ViewStub layout="#layout/somecontainerlayout"
inflate_inside="#+id/somecontainerid">
<TextView android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_world" />
</ViewStub>

Categories

Resources