I have a UI, I build it dynamically. I should want to put some component in a xml resource file. So I do :
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+android:id/titreItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
... in a file res/layout/titreitem.xml as I see anywhere. But I don't understand how get it to put inside my UI. So, inside activity.onCreate, I want to do something like :
RelativeLayout myBigOne = new RelativeLayout(this);
TextView thingFromXML = [what here ? ];
myBigOne.addView(thingFromXML);
setContentView(myBigOne);
Use a LayoutInflater....The Entire Layout can be inflated, without dynamically creating it....
LayoutInflater li = LayoutInflater.from(context);
View theview = li.inflate(R.layout.whatever, null);
Approach seems to be little incorrect. You should put RelativeLayout to the xml as your TextView made, and inflate the whole xml. Afterwards, you will be free to add views to your layout. So, do this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="#+androi:id/relLayout>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+android:id/titreItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</RelativeLayout>
In your activity:
setContentView(R.layout.titreitem);
RelativeLayout layout = (RelativeLayout)findViewByid(R.id.relLayout);
layout.addView(...);
Related
I have a layout as indicated below:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible">
<LinearLayout
android:layout_height="match_parent"
...
The associated activity is like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_login);// here is the layout
}
I'm trying to make it visible in the following way:
LinearLayout layoutActLogin = (LinearLayout) findViewById(R.layout.act_login);
layoutActLogin.setVisibility(View.VISIBLE);
But Android Studio told me that there is an error about R.layout.act_login
findViewById is for views, not layouts.
You should put an ID in your view like:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/my_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible">
<LinearLayout
android:layout_height="match_parent"
...
Then get the view reference and make it visible
View viewActLogin = findViewById(R.id.my_view);
viewActLogin.setVisibility(View.VISIBLE);
You can not change visibility of Layout. you can only change visibility of Views inside.
You can assign id to you view by using android:id tag in you layout. You can read more about this here.
In your case. Just give some Id to your View/ViewGroup, and reference that View from your Activity and using findViewById method and change its visibility.
You're misunderstanding how layouts and views work. Layouts define what is shown on-screen to a user during an activity, set by calling setContentView() within the Activity's onCreate() method. Views are individual elements within the layout, which are accessed with the R.id prefix using findViewById().
In your example you'll need to apply an ID to the root ConstraintLayout (using android:id) to be able to access it:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/parent_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible">
Then you can access it with:
ConstraintLayout layoutActLogin = (ConstraintLayout) findViewById(R.id.parent_layout);
layoutActLogin.setVisibility(View.VISIBLE);
EDIT Looking at your code I now realise you want to control the root ConstraintLayout, which makes my answer almost identical to Eduardo Herzer's. Leaving my answer up due to the added explanation at the beginning.
I want to create a custom layout to reduce redundancy in the code. Currently every layoutfile has about 30 Lines of code which are identical.
My goal was to create a custom layout/view which can hold in itself children.
<BaseLayout xmlns:...>
<!-- Normal Content -->
<Button />
<Label />
</BaseLayout>
While the above xml holds most of the content, the BaseLayout is in itself an xml containing other views and functionality:
<FrameLayout xmlns:...>
<LinearLayout><!-- contains the Header--></LinearLayout>
<LinearLayout><!-- INDIVIDUAL CONTENT HERE--></LinearLayout>
<FrameLayout><!-- contains the loading screen overlay --></FrameLayout>
</FrameLayout>
So all children from the above xml should be inserted into second linear-layout. I have already succeeded into doing so. But am confronted with layout problems (match parents does not match parents and only wraps)
My approach was extending the LinearLayout with following logic:
/**
* extracting all children and adding them to the inflated base-layout
*/
#Override
protected void onFinishInflate() {
super.onFinishInflate();
View view = LayoutInflater.from(getContext()).inflate(R.layout.base_layout, null);
LinearLayout linearLayout = (LinearLayout) view.findViewById(R.id.base_layout_children);
while(0 < getChildCount())
{
View child = getChildAt(0);
LinearLayout.MarginLayoutParams layoutParams = (MarginLayoutParams) child.getLayoutParams();
removeViewAt(0);
linearLayout.addView(child, layoutParams);
}
this.addView(view);
}
Is there a better, cleaner approach to capsule the xml and reuse a basis layout? How do I fix the match_parent issue?
While writing this post and thinking hard how to explain best, the solution for the match_parent issue became clear. Though the question remains if there is a better approach for the whole problem.
//Solution:
this.addView(view, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
//wrong:
this.addView(view);
Suppose you have two layout files. common_views.xml and layout_main.xml. You can include content of one layout file into another like this.
<?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"
>
<include
android:id="#+id/common"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
layout="#layout/common_views" />
<WebView
android:id="#+id/webView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="#+id/common"
>
</WebView>
</RelativeLayout>
I'm creating childview for viewflipper at runtime based on the no of records in database,
inflating a view and adding to viewflipper. While Clicking each childview of viewflipper, should have newviewflipper with some childs. How to achieve this?
ViewFlipper.xml
<?xml version="1.0" encoding="utf-8"?>
<ViewFlipper
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/flipper"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
CustomViewSample.xml
<?xml version="1.0" encoding="utf-8"?>
<com.sample.MjpegView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fullscreen_video"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Java Code
ViewFlipper viewflipper = (ViewFlipper)findViewById(R.id.flipper);
- **livevideocount** is an integer contains no of records from table.
for(int i=0;i<livevideocount;i++)
{
MjpegView mv = (MjpegView)inflater.inflate(R.layout.CustomViewSample,null);
mv.setVisibility(MjpegView.VISIBLE);
viewflipper.addView(mv);
}
Clicking this MjpegView object should generate another viewflipper with 3 childviews.
can anyone help me?
You should not directly inflate dynamic content into ViewFliper.
You should add dyna_layout as <LinearLayout /> or <RelativeLayout /> into your ViewFlipper.xml, consider dyna_layout as a ViewGroup:
ViewGroup parent = (ViewGroup)(viewflipper.findViewById(R.id.dyna_view));
MjpegView mv = (MjpegView)inflater.inflate(R.layout.CustomViewSample, parent);
mv.setVisibility(MjpegView.VISIBLE); //may use or not
parent.addView(mv);
I have made a custom view that I'm setting inside the onCreate() method in the Main Activity.
Like this:
compassView = new CompassView(this);
setContentView(compassView);
My question is. How do I reference the view in xml, so I can put it inside a linearlayout together with other controls?
Assuming your CompassView is a class which is placed in the Package called ,
com.android.sample
Create a XML like this,
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<com.android.sample.CompassView
android:id="#+id/compassview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
And now as usual, setContentView(R.layout.xmlname); in your onCreate().
And compassView = (CompassView)findViewbyId(R.id.compassview);
setContentView("here put your xml layout")
In .xml layout just simple add ur View:
<com.example.widget.CompassView
android:id="#+id/..."
style="#style/..." >
</com.example.widget.CompassView>
First of all, you must override any constructor of your superclass. If you don't do that you will get a run time error and you activity will never be opened. Then you should use the fully qualified class name like this:
<your_package_name.your_class_name
android:id="#+id/mycompass"
your attributes here
...
/>
You will have to add your custom view In your xml file, something like this:
<yourpackagename.yourCustomViewClass
android:id="#+id/myCustomView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
After this, you can access this view through its id, like you would have done for any other View
Here's the rub: I have a layout that uses the include tag. The layout is simple ->
<LinearLayout>
<TextView ...>
<LinearLayout>
<include ...>
</LinearLayout>
</LinearLayout>
Now the included file is nothing more than:
<LinearLayout>
<TextView ... android:id="#+id/inner_text">
</LinearLayout>
Now, if I try to access the TextView inner_text in either the create or onStart call, it throws a NPE. I have tried using LayoutInflater to infate the included xml file and then access inner_text but to no avail - it always fails.
So, the question is : does LayoutInflater work with included xml files of the parent xml file? What I would like to do is grab the contents of the included xml file - and set the whole thing to be either visible or not visible based on preferences.
Nothing seems to allow me to grab the TextView object.
Now, when I include the xml as just a nested element in the parent file (not using the include tag) - then it accesses that LinearLayout just fine - but that defeats my purpose of trying to make the layout of the view dynamic - that is, I can change the contents of the child included layout at will - and not have to do any changes to the parent layout.
Any help, pointers, suggestions -> greatly appreciated.
As suggestion I think you can have in the main xml some Layout component left empty, them in runtime, inflate the main xml, then the included xml and add the content of the included in the space you left in the main.
But I think you example have to work, internally the Android uses the inflater to inflate resources. Can you edit and tell a bit more? Code examples can be helpfully.
well, very strange, when you inflate a view from any xml resource (if xml resources have or have not nested resources with include) the view must hold all the parsed xml. So, yes, LayoutInflater work with included xml files of the parent xml file.
i copied here the way i'm doing now...
my generic layout (a header with text, progress bar and image)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dip">
<ImageView
android:id="#+id/genericHeaderLogoPin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:src="#drawable/logo_pin"/>
<TextView
android:id="#+id/genericHeaderTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#id/genericHeaderLogoPin"
android:textSize="18dip"
android:textStyle="bold"
android:textColor="#FF0C9994"/>
<ProgressBar
android:id="#+id/genericHeaderProgressBar"
android:layout_width="25dip"
android:layout_height="25dip"
android:layout_centerVertical="true"
android:layout_toLeftOf="#id/genericHeaderLogoPin"
style="#android:style/Widget.ProgressBar.Inverse"
android:visibility="gone"/>
</RelativeLayout>
my parent layout... include the generic layout and a ListView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#drawable/background_new_search_activity_1">
<include layout="#layout/generic_header_layout" android:id="#+id/listaBusquedasHeader"/>
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:cacheColorHint="#00000000"/>
</LinearLayout>
my onCreate method that inflate the parent layout mentioned above:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
requestWindowFeature(Window.FEATURE_NO_TITLE);
LayoutInflater inflater = LayoutInflater.from(this);
View view = inflater.inflate(R.layout.lista_busquedas_activity, null);
setContentView(view);
listView = (ListView) findViewById(android.R.id.list);
listView.setOnItemClickListener(listItemClickListener);
((TextView)findViewById(R.id.genericHeaderTitle)).setText(R.string.messagesActivityTitle);
}
and that´s all, i hope this helps you.
Thanx for the help - I discovered what my problem was - I was trying to inflate the included file - not the parent container - so that's why it never found the elements. I wish the documentation would have mentioned that - logically I would think the parent xml file would load - but the included files may need inflating - guess not.
Works now thanks to your code examples you submitted.
Thanx.