Is there a possibility that in the xml resource layout to have a base view and when inflate it to convert it to a specific view ?
For example having a custom view called MyCustomView that extends EditText, and some views that extends MyCustomView like MyCustomViewNumber or MyCustomViewPassword and a layout like this :
<com.example.MyCustomView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
.....>
</com.example.MyCustomView>
Is it possible that after I inflate this xml, MyCustomView to became one of MyCustomViewNumber or MyCustomViewPassword (inherit all attributes from those two). MyCustomViewNumber will be an EditText(better said a MyCustomView) that in the constructor method has setInputType to number.
View baseView = LayoutInflater.from(getContext()).inflate(R.id.my_layout, container, false);
baseView = new MyCustomViewNumber(getContext()). //with this line I want that my view from the layout to take all attributes from MyCustomViewNumber.
Recapitulating:
public class MyCustomView extends EditText
public class MyCustomViewNumber extends MyCustomView {
ctors > this.setInputType("number");
}
public class MyCustomViewPassword extends MyCustomView{ ctors > same as above }
Inflate MyCustomView. Set the inflated view to MyCustomViewNumber or MyCustomViewPassword. Is it possible ?
Basically I do this because I need the "layoutParams". I know that I could get the layout params from the inflated view, remove it and then add the new one with that parameters.
No, the class whose fully qualified name you use in your XML is instantiated by the system, and thus must be a concrete class.
Related
If I create two classes, a Parent class which extends FrameLayout, and a Child class that extends View, and then use XML to initialise them. Is it possible to get child elements from the Parent class constructor? If i use getChildAt() , I always get null, since the activity is still not created.
<com.example.Parent
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_centerInParent="true">
<com.example.Child
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.example.Child
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.example.Parent>
Parent and Child classes
public class Parent extends FrameLayout {
public Parent(#NonNull Context context) {
super(context);
this.getChildAt(0); // return null
}
...
}
public class Child extends View {
...
}
Since you are calling getChildAt at the construction of your FrameLayout you are getting null values (your children are still not fully attached to the view). One solution would be to overwrite onLayout() or onMeasure() to get your childs.
Before inflating you can not get child view form Parent.
But you can do it dynamically but is also work in same way like , you have to add views manually to Parent view.
And then you can get child views form Parent View.
I Have an android activity with a custom view set to it. The custom view is a java class. I need to infer some methods of view from it's activity. How can I do this?
1)Created CustomView class with extends of view(whatever you want)
2)Create a method within CustomView class like,
public void check(){
}
3)Use custom view in you xml or activity
4)Find the view from activity,
private CustomView obj;
obj = (CustomView)findViewById(R.id.view1);
5)Now if i want to access the check method
obj.check();
I usually create a custom view, for say,
public class MyView extends LinearLayout{
public MyView(Context context){
super(context);
//Inflating my custom layout
LayoutInflater inflater = getLayoutInflater();
inflater.inflate(R.layout.view_layout, this);
}
}
The problem with the above layout is, it will create a new LinearLayout and inflate R.layout.view_layout inside it, adding a new view hierarchy which is not preferred.
R.layout.view_layout contains RelativeLayout with many child elements, which I cannot add programatically by extending RelativeLayout (since positioning is difficult).
Having unnecessary hierarchies slow down my app.
What is the best way to create custom views/view group without an extra hierarchy level.
Solved as per the soln by CommonsWare:
XML Layout:
<merge>
<TextView ...
.../>
More items
</merge>
Since the XML layout had RelativeLayout as the parent view, I will extend RelativeLayout in the code instead of LinearLayout
public class MyView extends RelativeLayout{
public MyView(Context context){
super(context);
//Inflating my custom layout
LayoutInflater inflater = getLayoutInflater();
inflater.inflate(R.layout.view_layout, this);
}
}
Have res/layout/view_layout.xml start with a <merge> element instead of a LinearLayout.
<merge> is the solution but your layout is displayed incorrectly in Design mode in your IDE and this could be a pain. To fix this you need:
<merge
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout"
tools:layout_width="match_parent"
tools:layout_height="match_parent">
I have a main activity
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//HOW TO: dynamically add or remove <com.my.custom.MyCustomLayout>
}
}
The content of the above main Activity is:
main.xml
<FrameLayout ...>
<LinearLayout ...>
<com.my.custom.MyCustomLayout
android:id="#+id/custom">
<FrameLayout>
As you see above, I have a custom layout element, which is a Java class extends LinearLayout like following:
public class MyCustomLayout extends LinearLayout{
...
}
In my activity java code, I would like to dynamically add or remove the custom layout element<com.my.custom.MyCustomLayout> in main.xml layout.
How to do it in My activity Java code?
Create a different layout file with your custom view like:
difflayout.xml:
<com.my.custom.MyCustomLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/custom">
Take a reference of your container LinearLayout on your code section. Use LayoutInflater and addView() and removeAllViews() of the ViewGroup class(here your LinearLayout)
First consider if you really want to remove the view from the layout or just completely hide it. You need to have a very good reason to go for the latter.
To just hide the view you would do in your activity
findViewById(R.id.custom).setVisibility(View.GONE) // to hide
// or
findViewById(R.id.custom).setVisibility(View.VISIBLE) // to show
If you really want to completely remove the view from the layout, you can
View customView = findViewById(R.id.custom);
ViewGroup parentView = (ViewGroup) customView.getParent();
parentView.removeView(customView)
you must have defined , id for the custom layout. use this id in java code
example : customLayout = (LinearLayout)findViewById(id);
now with customLayout call the layout
I defined a layout like this:
<LinearLayout>
<ListView />
</LinearLayout>
and I want to use a wrapper class for it:
public class MyView extends LinearLayout {
ListView mListView;
public build() {
mListView = (ListView)findViewById(R.id.mylistview);
}
}
not sure how to inflate this from my layout file:
MyView v = LayoutInflater.from(this).inflate(R.layout.myview, null);
the inflater of course does not know what 'MyView' type is, and returns only View. What's a good way to reconcile this?
Why do you inflate LinearLayout in linear layout ?
What you probably need, define a layout for myView. Inflate it in some sort of initialize procedure ( for that view ).
And than you'll use your new view in xml layout.
More on that here
http://developer.android.com/guide/topics/ui/custom-components.html
You have to define the type of the Layout in xml.
Instead of your xml you need to declare it like that:
<your.package.MyView>
<ListView />
</MyView>