How to display Android UI via XML Layout? - android

Currently I understand I can create a XML Layout and pass that to setContentView(...), or I can pass a Customized view to setContentView(...).
But what if I want to combine the elements of both? Is it possible to use a layout first, then to programmatically add to the UI via java code?
For example: How could I create a view that uses an Asset background picture with an added loading widget on top?
ADDED INQUIRY: Right now and I think of a View and a Layout as two things for setContentView to display. But can a View hold a layout within it to be displayed?

Yes its possible to set an XML layout with setContentView(), and programmatically add more views/widget to that layout. Here's a short example.
main.xml
<?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_image">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Some text"/>
<LinearLayout
android:id="#+id/custom_content_root"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- This is where we will add views programmatically -->
</LinearLayout>
</LinearLayout>
TestActivity.java
public class TestActivity extends Activity {
private LinearLayout mRoot;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set the layout
setContentView(R.layout.main);
// Get the Linearlayout we want to add new content to..
mRoot = (LinearLayout) findViewById(R.id.custom_content_root);
// Create a TextView for example
TextView moreText = new TextView(this);
// Set the layout parameters of the new textview.
moreText.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
moreText.setText("More text :)");
// Add the new textview to our existing layout
mRoot.addView(moreText);
}
}
The result is an activity with background_image.png as background, and two textviews with text ;)
You can add any type of view (TextView, EditText, ImageView, Buttons etc) this way.

Yes, it is possible to add widgets after using setContentView(). It's also possible to inflate XML layouts yourself using LayoutInflater.
You could add the loading widget to a layout that was defined inside your XML by getting it using findViewById and then using a method from ViewGroup.

Related

Adding items to the ScrollView dynamically make it doesn't scroll

I have a simple layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="300dp"
android:padding="15dp">
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/scrollLayout">
</LinearLayout>
</ScrollView>
</RelativeLayout>
Now, I inflate the outer RelativeLayout to retrieve the inner LinearLayout to put items in it.
RelativeLayout relative = (RelativeLayout) LayoutInflater.from(activity).inflate(R.layout.gradient_pick_view, null);
LinearLayout view = (LinearLayout) relative.findViewById(R.id.scrollLayout);
After that I created a method to add some buttons to it:
for(int i=0;i<10;i++){
LinearLayout wrapper = (LinearLayout) LayoutInflater.from(activity).inflate(R.layout.button_wrapper, null);
Button button = (Button)wrapper .findViewById(R.id.button);
view.addView(layout);
}
Everything works fine, but it doesn't scroll.
What am I doing wrong here?
Here's the screenshot (displaying 7 of 10 buttons):
I forgot to mention - I'm using a MaterialDialog library and add this RelativeLayout as a custom view to a dialog.
Try to set the following attribute to your scrollview,
android:fillViewport="true"
above attribute is used to make your scrollview to use entire screen of your application.
I had a false parameter passed to a customView in a MaterialDialog.
dialog = new MaterialDialog.Builder(activity)
.title(R.string.about)
.customView(view, true)
.positiveText(R.string.changing_fragments)
.show();
As doc says:
If wrapInScrollView is true, then the library will place your custom view inside of a ScrollView for you. This allows users to scroll your custom view if necessary (small screens, long content, etc.). However, there are cases when you don't want that behavior. This mostly consists of cases when you'd have a ScrollView in your custom layout, including ListViews, RecyclerViews, WebViews, GridViews, etc. The sample project contains examples of using both true and false for this parameter.
Now it's working.

Add background image to individual fragments

I have an app with multiple fragments and I would like to know how to add a background that is different for each fragment. The layout I am using has scrollable tabs which all use the same xml file. I also have a MainActivity that sets the view and an adapter for each fragment. I know you can add a background using the xml file with android:background or something of the sort as well as setting it to the view in the main activity but I can't figure out how to do it to each tab. Thank you for any help!
To add background to fragment, you have to wrap it in some container
<LinearLayout
android:id="#+id/linearlayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ccc"
android:layout_weight="1"
android:orientation="vertical">
<fragment android:name="com.example.simplefragmentexample.LayOutOne"
android:id="#+id/frag_1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
If you wish to use same xml file, you should set images programmatically
LinearLayout l = (LinearLayout) findViewById(R.id.linearlayout01);
l.setBackground(Image);
or use several xmls with android:background.
You can get the root View of the fragment with the Fragment getView() method. Then you can set the background of the View using one of the setBackground() methods of the View. For example to set a random background color to each fragment:
for ( Fragment f : fragments ) {
f.getView().setBackgroundColor ( (new Random()).nextInt() );
}
PS: I never used fragments, therefore my answer could be wrong.

Adding new widget controls dynamically to an existing layout

i've seen this question added on the stack but the information hasn't been helpful or successful yet, so i remain quite not sure.
The gist of what I'm trying to do:
I have a layout defined in xml, some_details_view.xml for example.
setContentView(R.layout.some_details_view);
It has a bunch of text views laid out using a parent relative layout, a linear header layout, a linear footer layout, a middle scroll layout that contains a relative layout that hold some label - value type of text views.
And at the bottom of the scroll view relative layout, I currently placed a frame layout as a place holder.
On create of the corresponding activity, I set text in respective text views with data handed over from previous activity; basic stuff.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/white" >
<LinearLayout
android:id="#+id/header"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true" >
...some header content
</LinearLayout>
<LinearLayout
android:id="#+id/footer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="vertical" >
..some footer content
</LinearLayout>
<ScrollView
android:id="#+id/scroll"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#+id/footer"
android:layout_below="#+id/header"
android:layout_margin="5dip" >
<RelativeLayout
android:layout_width="fill_parent"
android:id="#+id/relativeScroll"
android:layout_height="wrap_content" >
...text views in relative layout
<FrameLayout
android:id="#+id/placeholder"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="#+id/moreInfoValue" />
</RelativeLayout>
</ScrollView>
</RelativeLayout>
After setting up text views for the given data, I use an async task to get some additional data that I want to show as a history list type of thing at the bottom of the static form layout. There could be 0 or more items so I either add 1 or more text views or none at all.
In the post execute, which I understand to run on the main UI thread, I try to find an exiting container Layout/view group and add either a new Linear Layout to which I add new text Views, or just add the new text views directly to the existing container layout.
here's the latest thing I tried:
ViewGroup mContainer = null; //defined as member variable of activity class and instatiated in on create
mContainer = (ViewGroup)findViewById(R.id.placeholder); //set in on create
LinearLayout ll = new LinearLayout(context); //on post execute of async task
ll.setOrientation(LinearLayout.VERTICAL);
mContainer.addView(ll); //add a new linear layout to an existing container layout
//add some new text view widgets items dynamically
for(NewDisplayItem item : items)
{
TextView tv = new TextView(context);
tv.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
tv.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
tv.setText(item.getSomeText());
ll.addView(tv); //add text view to new linear layout
}
When the UI loads I don't see new items added to my layout after stepping through and watching the controls get added using the code above.
Not sure what it is but something doesn't seem right about this approach in addition to the fact that it's not working. When the activity loads up, all the static views are setup and in view. I pop up a loading dialog, step through the async task stuff and I guess expect to see the dynamic controls add to the layout one by one?
First of all textView.setWidth(int) takes as parameter the width in pixels.
Second you should also set your layout parameters on the LinearLayout you are adding.
The way you should set LayoutParams is as follows :
ll.setLayoutParams(new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
the same for yout TextViews.
Ovidiu Latcu has a good answer. A good question is: is there a reason why you aren't using a ListView (which btw there ARE cases where what he's doing works better)? A ListView has a lot of mechanisms to help you keep from running out of RAM

Android Can we add a footer view to a content view

I have a 'ParentActivity'
public class ParentActivity extends Activity
and all the activities of my application extends this ParentActivity
public class MainActivity extends ParentActivity
I have roughly 20 activities all extending ParentActivity and all activities have different layouts from each other(like some have LinearLayout ,some RelativeLayout,some ScrollView)
My app is almost complete,but my client now requires to have an adsense ad display at the end of each activity.
One general solution is to include following layout to all of my activity layouts
<?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="30dip"
android:orientation="vertical"
android:background="#color/header_bgcolor"
android:gravity="bottom"
android:layout_gravity="bottom">
<com.google.ads.GoogleAdView
android:id ="#+id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
But what I want to do is on ParentActivity I will define a function which automatically adds the following view to end of the content view as follows
ViewGroup view =(ViewGroup)this.findViewById(android.R.id.content);
View adSenseView = View.inflate(this, R.layout.ad_sense_layout,view);
GoogleAdView adView =(GoogleAdView)adSenseView.findViewById(R.id.adView);
AdSenseSpec adSenseSpec = new AdSenseSpec("CLIENT_ID")
.setCompanyName("COMPANY NAME")
.setAppName("APP NAME")
.setChannel("Channel Id")
.setAdType(AdType.TEXT);
adView.showAds(adSenseSpec);
In this way I am able to add the adsense view at the bottom but it overlaps the lower end of the content view.So is there any way ,I can dynamically add a footerview to a content view of an activity.
I am still working on solution,and if I find any I will surely post.
Thanks in advance
Also, I wonder if some of the setters you are using have an xml equivilent, removing some of the need for the code?
Put your last code snippet in ParentActivity::onCreate and define a_child_activity::onCreate as { /* my create stuff */; super.onCreate(); }
Just a beginner so probably rubbish though.

Is possible to set an listener just for a part of a custom view?

I want to create a custom view (extends View) which contains an image and a text.
Is it possible to set an listener just for image if i use canvas.drawBitmap(imageBitmap, ...) method?
Thank you!
If you want your view just to show an image and a text, why not create a specific layout in your XML file and use setContentView to display the view?
If thats what you were looking for, I think that is the easiest approach. XML example coming soon.
Here is the contents of my personal view to display my main application, just to demonstrate how I can switch view's, your view would be different including a TextView and an ImageView.
dblist.xml inside of res/layout folder.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FFFFFF">
<ListView android:id="#+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textColor="#000000"/>
</LinearLayout>
This contents display my database results onto a Spinner
I can call that view by using:
setContentView(R.layout.dblist);
And if I want to return to my main layout, I can switch the view by calling
setContentView(R.layout.main);
EDIT:
You can manipulate the view you are working with programmatically by using findViewById method. Let's use my dblist.xml file as an example, notice that my ListView has an id of list. So I would call:
ListView myList = (ListView) findViewById(R.id.list);
With corresponds to that layout, so whenever I want to change anything to my XML file, I would reference myList use methods and callbacks to meet my needs.
I hope this helps.

Categories

Resources