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.
Related
I have a layout section which is part of a Fragment and its a layout for the activity.
fragment.xml
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none”>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp">
<include layout="#layout/sectional_component"/>
<include layout="#layout/list_component" />
<include layout="#layout/usage_component" />
</RelativeLayout>
</ScrollView>
list_component.xml
<LinearLayout
android:id="#+id/list"
style="#style/VerticalMatchParent">
// programatically added top 3 customer list
</LinearLayout>
activity_list.xml
<LinearLayout
android:id="#+id/list"
style="#style/VerticalMatchParent">
// programmatically render all customer list
</LinearLayout>
I'm new to android. I wanted to use a common method for rendering the list based on the request (3 or all). For now, I have written a separate method in Fragment and in an activity to handle this.
I want to make it as a single method which can be used by the fragment as well as an activity since the functionality is nearly same. I tried to make it as a separate util method, but the issue I'm facing is inside the method I have do manipulations for the view elements not sure how to do it without inflating the view element layouts. Already the layouts having the view elements are inflated in the respective Fragment and Activity.
Kindly provide a solution for this.
There are multiple approaches to do this, one of them would be to create an static method inside a separated class, pass the required parameters and call it wherever you want.
Class MyClass:
public class MyClass {
public static View myMethod(View myView){
// Do whatever you want with your View
return myView;
}
}
Call to myMethod from MyClass:
View modifiedView = MyClass.myMethod(myView);
If you need to handle some Views send them to the method as a list, array or whatever
If you plan on populating a list, you can go for listView. And write an adapter class to populate your list on it.
Note: You need a separate layout file with design for listView saved under you layout folder.
Hope this helps!
Is there any possible way to share layout(part) between activities? For example, in my app, all activities have similar layout, the top part is long operation indicator (a progress bar, hidden when no operation is being executed), the bottom part is for showing errors. Only the middle part is different for all activities. See the picture below.
so my question is, is it possible to reuse the common layout(loading and error part) for all activities in my app? (currently I don't want to use fragment to do it for some reasons)
maybe the layout resources should like this:
layoutfolder
activity_common.xml
activity_one_content.xml
activity_two_content.xml
thanks
You can create an abstract 'base' activity that all your activities extend from, overriding setContentView to merge the base, and sub activity layouts.
This way you can handle all the loading/error code in the base activity, and simply toggle between hiding and showing the views in the sub activities.
The abstract activity:
public abstract class BaseActivity extends Activity {
protected RelativeLayout fullLayout;
protected FrameLayout subActivityContent;
#Override
public void setContentView(int layoutResID) {
fullLayout = (RelativeLayout) getLayoutInflater().inflate(R.layout.activity_base, null); // The base layout
subActivityContent = (FrameLayout) fullLayout.findViewById(R.id.content_frame); // The frame layout where the activity content is placed.
getLayoutInflater().inflate(layoutResID, subActivityContent, true); // Places the activity layout inside the activity content frame.
super.setContentView(fullLayout); // Sets the content view as the merged layouts.
}
}
the layout file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The main content view -->
<FrameLayout
android:id="#+id/loading_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!-- The main content view -->
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<FrameLayout
android:id="#+id/error_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
You could use include in XML to, well.. include the re-useable part of your layout code.
As an example, here's my layout file for the Toolbar I used in my app:
// /res/layout/component_toolbar.xml
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:taggr="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/primary"
android:minHeight="?attr/actionBarSize"
taggr:popupTheme="#style/ThemeOverlay.AppCompat.Light"
taggr:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" />
Now, say if I want to use that Toolbar again in a different Activity, this is all I'd have to write:
// /res/layout/whatever_layout_this_might_be.xml
<include layout="#layout/component_toolbar" />
Bear in mind that this would only copy the layout - not the actual behavior of said widget/component.
If you want to actually copy all of the aspects (layout, behaviour) I'm afraid Fragment is the only way to go.
Although ActivityGroup is deprecated fro API 13 but if you don't wish to go with fragments then this can be your best choice.
According to documentation, an ActivityGroup is:
A screen that contains and runs multiple embedded activities.
You can find a tutorial here and here Although the mentioned tutorial uses a Tablayout you can replace that with your common layout in XML.
A second Approach could be Reuse the layout with include tag, in this approach you could just reuse your once created common layout everywhere in the app.
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.
This question already has an answer here:
Custom Layout in android
(1 answer)
Closed 2 years ago.
I'm looking to a simple way to do layout templating in android.
I already check include and merge techniques without success.
(I think that it's possible creating custom Layouts and defining by code this behavior, but i wondered if that could be done by xml)
I want to define something like this:
[globalLayout]
<linearLayout params=xxx>
<linearLayout params=yyy>
<?yied ?>
</linearLayout>
</linearLayout>
[customView1]
<Linearlayout>
<ImageView />
<Button/>
</LinearLayout>
[customView2]
<Linearlayout>
<Button/>
<Button/>
<Button/>
</LinearLayout>
(these 3 xml should be reusable)
[HomeLayout]
<?include globalLayout >
<?include customView1 />
</include>
[ParamsLayout]
<?include globalLayout >
<?include customView2 />
</include>
The thing is that i want to have a reusable layout, if a perform a small change, it will affect all dependent views. somethink linked to "partial views or templating" in other languages.
Could anyone help me?
I have done something like this before by using view stub.
You can inflate any view you like inside that view.
<GlobalLayout>
<ViewStub>
<GlobalLayout>
Use LayoutInflater to do something like this:
On the Activity's onCreate:
super.onCreate(savedInstanceState);
setContentView(new TemplateInflater(this).apply(R.layout.products)
.onViewGroup(R.id.replace_here).ofTemplate(R.layout.template));
An implementation snippet:
public View ofTemplate(int templateId) {
LayoutInflater inflater = LayoutInflater.from(context);
View root = inflater.inflate(templateId, null);
View content = inflater.inflate(contentId, null);
((ViewGroup)root.findViewById(viewGroupId)).addView(content);
return root;
}
An example of a working code is in my git: https://github.com/erichegt/AndroidTemplating
I think this code will solve your problem, but you should use Fragments instead. You can have one Activity associated with a template and a Fragment to inflate it.
ViewStub is pretty straightforward and can cover basic layout templating needs.
It serves as a placeholder for some other layout which you can specify and inflate at runtime and then:
The inflated View is added to the ViewStub's parent with the ViewStub's layout parameters.
Here is example from one of my projects. In my layout template I have:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout ... >
...
<ViewStub
android:layout_width="0dp"
android:layout_height="0dp"
android:id="#+id/button_1_stub"
app:layout_constraintDimensionRatio="H,1:1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#id/split_guideline"
app:layout_constraintLeft_toRightOf="#+id/primary_left_guideline"
app:layout_constraintRight_toLeftOf="#+id/primary_right_guideline">
</ViewStub>
....
</android.support.constraint.ConstraintLayout>
... then, when I inflate it I am setting actual button layout that I need and inflate stub:
View contentView = inflater.inflate(R.layout.activity_main_template, null);
ViewStub button1Stub = contentView.findViewById(R.id.button_1_stub);
button1Stub.setLayoutResource(R.layout.work_button);
button1Stub.inflate();
... which inserts layout from R.layout.work_button instead of stub, imposing layout constraints I defined on the R.id.button_1_stub.
Is this possible?
I would display an activity that shows a welcome page, and that welcome page doesn't have any Views where I can attach an onClickListener.
EDIT: ok, the reason for this welcome kind of welcome page, is that this application is used to take something like a survey... after a customer is done with the survey, the app returns to this welcome page so another person can take the survey again.
Yes, if the original layout is somehow not appropriate, use a FrameLayout at the top level of your layout to achieve this. FrameLayout allows stackable views/layouts, so you can have your existing view as the bottom layer, and then a transparent view on top that listens for the touch event:
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- Put your complete original layout/view here -->
<View
android:id="#+id/view_to_listen_for_touch"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</FrameLayout>
try like this,
welcome screen xml layout.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</RelativeLayout>
add this in your activity,
private RelativeLayout mainLayout;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.welcome_screen);
mainLayout=(RelativeLayout)findViewById(R.id.mainLayout);
mainLayout.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// here you can write code to proceed next step.
}
});
}
I think you are using an XML layout for this page. And using at least one ViewGroup (e.g Linear Layout/Relative Layout etc). Put an id to this ViewGroup element and In the Activity initialize this ViewGroup element using find view by id. Now set the click listener to the ViewGroup element