I want to add some spacing between the actionbar's back navigation button, icon and title. Anyone knows how to do it?
int actionbarTitleId = getResources().getIdentifier("android:id/action_bar_title", null, null); //TextView hosted in LinearLayout
int upImageViewId = getResources().getIdentifier("android:id/up", null, null);//ImageView hosted in LinearLayout or HomeView
int homeId = android.R.id.home; //ImageView hosted in HomeView
Use findViewById with each of the ids to get View (or appropriate cast) for each.
Try not to modify the LayoutParams. But add padding between them or just use existing LayoutParams to modify the margins.
Related
I followed the below link to dynamically add a layout multiple times using inflater and AddView()
Is there a way to programmatically create copies of a layout in android?
I used a loop to create multiple entries. But only one entry is comming up which is the result of last loop index
Below is my C# code
I can see only one child inside the parent which is the result of last loop.
What I missed?
var parent = FindViewById<RelativeLayout>(Resource.Id.ParentLayoutWrapper);
for (int i = 0; i < 4; i++)
{
var view = LayoutInflater.Inflate(Resource.Layout.RepeatingLayout, parent, false);
var txtView = view.FindViewById<TextView>(Resource.Id.textViewSample);
txtView.Text = i.ToString()+ " Android application is debugging";
txtView.Id = i;
parent.AddView(view, i);
}
The original post you worked from had a LinearLayout as the parent layout, not a RelativeLayout like you have. When you add a view (or another layout) to a LinearLayout, it gets positioned below (when LinearLayout has vertical orientation) any existing elements in the layout. However, the elements in a RelativeLayout need to use positioning properties to determine where they will be in the RelativeLayout, so every time you add the new layout, RepeatingLayout, since you are not changing the layout options, the view/layout is added over the existing view/layout. So change the parent layout to a LinearLayout in your layout file and then this should work:
LinearLayout parent = FindViewById<LinearLayout>(Resource.Id.parentLayout);
for (int i = 0; i < 4; i++)
{
var view = LayoutInflater.Inflate(Resource.Layout.RepeatingLayout, null);
var tv = view.FindViewById<TextView>(Resource.Id.textViewSample);
tv.Text = i.ToString() + " Android application is debugging";
parent.AddView(view);
}
Trying to do the same with a RelativeLayout as the parent layout highly complicates things unnecessarily.
I'm adding multiple Views by code into Layout. I need each new View to be above previous one(top of the parent layout).
EDIT: To be more accurate I'll describe what the app module should does. User start with clean screen and one button at the bottom of the screen. The button adds a View at the top of the screen. Next clicks should add next views above previous ones to make the newest View be on the top of a container. The app saves state and on restart user see views in the same order.
Call the following method from Button's onClick Event.
private final int LAYOUT_TOP_INDEX = 0;
private void addViewOnTop(View view){
if(layout != null && view !=null)
layout.addView(view, LAYOUT_TOP_INDEX);
}
where 'layout' is your Layout (e.g., LinearLayout) to which the View is to be added.
Would really need more information from you to give a more accurate answer, but if you're saying what i think you are then you can just add these views to a LinearLayout with orientation set to vertical.
And assuming you're iterating through a list to dynamically add views, instead of incrementing from 0, increment down from the size of the list.
for(int i = size; i >= 0; i--){
linearLayout.add(new TextView(Context));
}
View positions inside ViewGroups are defined by the LayoutParams
How does this happen? Views pass their LayoutParams to their parent ViewGroups
//100% programatic approach with simple LayoutParams
LinearLayout myLinearLayout = new LinearLayout(this);
//if the **parent** of the new linear layout is a FrameLayout
FrameLayout.LayoutParams layoutParams =
new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
//or if you have the XML file you don't have to worry about this
//myLinearLayout = (LinearLayout)findViewById(R.id.my_simple_linear_layout);
//you could have a LinkedList<TextView>
LinkedList<TextView> textViewList = new LinkedList<>();
//assuming the order is the correct order to be displayed
Iterator<TextView> descendingIterator = textViewList.descendingIterator();
while(descendingIterator.hasNext())
{
//just add each TextView programatically to the ViewGroup
TextView tView = descendingIterator.next();
myLinearLayout.addView(tView);
}
Just like we defined LayoutParams for the LinearLayout we could also define LayoutParams for the TextView
IMPORTANT: when setting LayoutParams you need to be sure they fit the VIEWGROUP, that is the parent of the View being added
private TextView textViewFactory(String myText) {
TextView tView = new TextView(getBaseContext());
//controling the position relatively to the PARENT
//because you are adding the textview to a LINEAR LAYOUT
LinearLayout.LayoutParams paramsExample =
new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f);
tView.setLayoutParams(paramsExample);
//configuring the insides of the textview
//you can also do all kinds of stuff programatically
tView.setGravity(Gravity.CENTER_HORIZONTAL);
tView.setPadding(10, 10, 10, 10);
tView.setTypeface(Typeface.DEFAULT_BOLD);// (null, Typeface.BOLD_ITALIC);
tView.setTypeface(Typeface.SANS_SERIF);
tView.setTypeface(null, Typeface.ITALIC);
tView.setTypeface(Typeface.defaultFromStyle(R.style.AppTheme));
tView.setId(R.id.aux_info);
tView.setText(myText);
//.........all kinds of stuff really
return tView;
}
If you mean adding a view programmatically so that the new one is added above the previous one, instead of below it, then I suggest this:
Maintain an ArrayList with the items you want to turn into views
Put them into a ListView
When you want to add a new view that must appear at the top of the list, insert it as the first element of your ArrayList and recreate the ListView from it.
Hi I am having troubles trying to get this Relative Layout placed below another Relative Layout. In my Activity I have a NavBar (RelativeLayout) that is aligned to the top of the activity. I would like to place my TitleBar (RelativeLayout) below this programmatically.
Here is my onCreate method where I allocate both the NavBar and TitleBar and add them to my Activity. The NavBar is correctly aligned at the top of the activity, however, the TitleBar is aligned with the top of the activity as well. I'd like the top of the TitleBar to align with the bottom of the NavBar so it is placed below the NavBar.
super.onCreate(bundle);
Context context = getApplicationContext();
RelativeLayout.LayoutParams params;
//navbar
this.navBar = new BINavBar(context);
relativeLayout.addView(this.navBar);
params = (LayoutParams)this.navBar.getLayoutParams();
params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
this.navBar.setLayoutParams(params);
//titleBar
this.titleBar = new BITitleBar(context);
relativeLayout.addView(this.titleBar);
params = (LayoutParams)this.titleBar.getLayoutParams();
params.addRule(RelativeLayout.BELOW, R.id.BINavBar_layout);
this.titleBar.setLayoutParams(params);
I don't think you are actually setting the id of the nav bar. Try the following:
super.onCreate(bundle);
Context context = getApplicationContext();
RelativeLayout.LayoutParams params;
//navbar
this.navBar = new BINavBar(context);
relativeLayout.addView(this.navBar);
params = (LayoutParams)this.navBar.getLayoutParams();
params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
this.navBar.setLayoutParams(params);
this.navBar.setId(R.id.BINavBar_layout); // this is the change
//titleBar
this.titleBar = new BITitleBar(context);
relativeLayout.addView(this.titleBar);
params = (LayoutParams)this.titleBar.getLayoutParams();
params.addRule(RelativeLayout.BELOW, this.navBar.getId()); // this should use navBar's id
this.titleBar.setLayoutParams(params);
Note that you may need to set the id yourself. Are you sure that R.id.BINavBar_layout exists? If not, try using the following function: View.generateViewId()
I have a feeling the ID of the view you're creating isn't using the ID you're trying to use. Try this:
//params.addRule(RelativeLayout.BELOW, R.id.BINavBar_layout);
params.addRule(RelativeLayout.BELOW, this.navBar.getId());
I'm currently making one of my very first applications. I'm using ActionBarSherlock.
I would like to make my logo overlap the actionbar (scrollview).
Currently I have main_activity.xml. In MainActivity.java I use setContentView to view main_activity.xml. After that I use getSupportActionBar() for ActionBarSherlock. I've tried things out using RelativeLayout (http://www.mkyong.com/android/android-relativelayout-example/). That didn't really work because there are multiple layouts.
So I've tried some things right and left, but it always ends up infront or behind the actionbar, or stops just before reaching the content. It's because of two different layouts, that's what I know. But how can I going to solve this? Is it possible? Thanks in advance!
What I want:
http://f.cl.ly/items/3N0w243N1t2Q3i1H1f1k/Untitled-1.png
You can either:
A. Split your image in two
Have the top part as the ActionBar logo, then show the bottom part over your content.
B. Use a single image
You'll need a layout file that contains just your logo (you'll probably want something like an ImageView inside a LinearLayout so you can easily set the correct margins).
Then after calling setContentView for your activity, add your logo view with:
ViewGroup decorViewGroup = (ViewGroup) getWindow().getDecorView();
decorViewGroup.addView(logoView);
Using a layout file
Example layout file (logo_view.xml):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/logo_image"
android:scaleType="center"
android:layout_marginLeft="10dip"
/>
</LinearLayout>
Inflate the layout file:
LayoutInflater inflater = LayoutInflater.from(this);
View logoView = inflater.inflate(R.layout.logo_view, null, false);
Although the original answer works on some devices, on others the image sits under the status bar. I resolved this by getting the location of the top ActionBar and comparing it to the location of the top of the logo image and then just adding some top padding, as follows:
// Inflate logo layout
LayoutInflater inflater = LayoutInflater.from(this);
final View logoView = inflater.inflate(R.layout.menu_logo, null);
// Add logo to view
ViewGroup viewGroup = (ViewGroup) getWindow().getDecorView();
viewGroup.addView(logoView);
// Adjust the logo position
int resId = getResources().getIdentifier("action_bar_container", "id", "android");
final View actionBarView = viewGroup.findViewById(resId);
if (actionBarView != null) {
actionBarView.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
// Remove the listener
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
actionBarView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
actionBarView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
// Measure views
int[] location = new int[2];
actionBarView.getLocationOnScreen(location);
int[] logoLocation = new int[2];
logoView.getLocationOnScreen(logoLocation);
// Add top padding if necessary
if (location[1] > logoLocation[1]) {
logoView.setPadding(0, location[1] - logoLocation[1], 0, 0);
}
}
}
);
}
This worked on a wide range of devices (phones, big/small tablets - inc Kindle Fire HDX) running Android versions 4.0 up to 4.4.4 as well as Android L preview.
I need to dynamically add a 'template' layout to my activity at runtime based on the click of a button.
Shown in the code block below is a simplified version of my layout. The contents of HEADER C (i.e. BODY C1, BODY C2 ... BODY Cn) are the components that need to be added at runtime. They are all of the same format and are defined in a separate xml file with a relative layout. How do I accomplish this task? I have tried a LayoutInflater, but was unsuccessful. Does LayoutInflater require a LinearLayout to inflate?
<SCROLLVIEW>
<RELATIVE_LAYOUT>
____________
HEADER A
____________
BODY A
</RELATIVE_LAYOUT>
<RELATIVE_LAYOUT>
____________
HEADER B
____________
BODY B
</RELATIVE_LAYOUT>
<RELATIVE_LAYOUT>
____________
HEADER C
____________
BODY C1
____________
BODY C2
.
.
.
____________
BODY Cn
<RELATIVE_LAYOUT>
</SCROLLVIEW>
Thanks, any guidance is appreciated!
LinearLayout Parent = (LinearLayout) findViewById(R.id.linearLayout);
View child = getLayoutInflater().inflate(R.layout.main_new,null);
Parent.addView(child);
use
View headerView = View.inflate(this, R.layout.class_name, null);
to inflate your layout.
/**rootView represent the RelativeLayout*/
View headerView = LayoutInflater.from(context).inflater(R.layout.header_view, rootView, false);
rootView.add(headerView);
You can do that like so:
general = (LinearLayout) findViewById(R.id.general_tab); // get the id of the layout you wish to add your view to
TextView programs = new TextView(this); // create a new view/widget to add
programs.setText("Program(s): " + prgdisp); // set the text
general.addView(programs); // add the new view/widget to the existing layout
EDIT
I missed that you had an xml layout for it already. Change the above to:
general = (LinearLayout) findViewById(R.id.general_tab); // get the id of the layout you wish to add your view to
View header = View.inflate(this, R.layout.class_name, null); // inflate your layout
general.addView(header); // add the new view/widget to the existing layout