Programmatically set the position of a view on Pre-Honeycomb devices - android

I am trying to programmatically set the position of a view on Android with the following code :
LayoutParams layoutParams = new LayoutParams(100, 100);
layoutParams.leftMargin = 200;
layoutParams.topMargin = 200;
myView.setLayoutParams( layoutParams );
It works on my Nexus 7 and Motorola G devices but not on old devices under Android 2.2.
On these devices the view is alway set at the top left position of the screen.
How can I do the same thing on these devices ?

Here is the solution.
The XML code:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id = "#+id/rootView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</RelativeLayout>
The Java code :
View myView = new View(this);
LayoutParams layoutParams=new LayoutParams(320,240);
layoutParams.leftMargin = 50;
layoutParams.topMargin = 60;
myView.setLayoutParams(layoutParams);
myView.setBackgroundColor(Color.YELLOW);
rootView.addView( myView );
View myView2 = new View(this);
layoutParams=new LayoutParams(320,240);
layoutParams.leftMargin = 200;
layoutParams.topMargin = 120;
myView2.setLayoutParams(layoutParams);
myView2.setBackgroundColor(Color.BLUE);
rootView.addView( myView2 );
And we need to import
import android.widget.RelativeLayout.LayoutParams;
At the beginning I used FrameLayout instead of RelativeLayout. It seems it is not possible to programmatically set the position of a view with Android 2.2 if the parent layout is a FrameLayout.
Thanks a lot for your help.

Related

Set Layout Params for custom View

In XML I was creating a new Entity of SwipeDeck (customView) like this :
<com.daprlabs.aaron.swipedeck.SwipeDeck
android:id="#+id/swipe_deck"
android:layout_width="match_parent"
android:layout_height="20dp"
swipedeck:card_spacing="15dp"
swipedeck:max_visible="1"
swipedeck:render_above="true"
swipedeck:swipe_enabled="true">
Now I am trying to programmatically set the x and y position. this works fine:
cardStack = (SwipeDeck) findViewById(R.id.swipe_deck);
cardStack.setX(20);
cardStack.setY(10+actionBarHeight);
When I am trying to set the height and width dynamically, nothing happens:
cardStack = (SwipeDeck) findViewById(R.id.swipe_deck);
ViewGroup.LayoutParams params = cardStack.getLayoutParams();
params.height=500;
params.width = screen_width - 40;
cardStack.setLayoutParams(params);
Everything happens in onCreate. Any ideas?
You should be declaring "params"'s type with respect to the ViewGroup that contains it.
For example, replace the line
ViewGroup.LayoutParams params = cardStack.getLayoutParams();
with
LinearLayout.LayoutParams params = cardStack.getLayoutParams();
if your custom view is inside a LinearLayout

GridLayout crashes app

I have a GridLayout and I want to alter it with java.
I have the following code:
GridLayout gridLayout = (GridLayout) findViewById(R.id.gridLayout1);
GridLayout.LayoutParams param =new GridLayout.LayoutParams();
param.rightMargin = 5;
param.topMargin = 5;
gridLayout.setLayoutParams(param);
Why does it crash?
The type of LayoutParams is determined by the parent of the View. Unless your R.id.gridLayout1 is inside another GridLayout, you should not be using GridLayout.LayoutParams.
You can do this :
GridLayout gridLayout = (GridLayout) findViewById(R.id.gridLayout1);
PARENT_LAYOUT.LayoutParams layoutParams = ( PARENT_LAYOUT.LayoutParams) gridLayout.getLayoutParams();
layoutParams.rightMargin = 5;
layoutParams.topMargin = 5;
and replace PARENT_LAYOUT with the LinearLayout or whatever your are using as Root layout

Unwanted spacing between android viewgroups added programmatically

I'm adding a RelativeLayout in a FrameLayout ( added in xml ) and I attach a LinearLayout in this RelativeLayout.
The problem is I get an unwanted left/right spacing/padding between the RelativeLayout and its child LinearLayout as you can see here from the uiautomator dump.
The weird thing is that spacing is always 11 pixels from each side tested on emulator N5, N4, N7 images and Moto G and N4 devices.
Thank you
The code is :
rlBottomBarContainer = new RelativeLayout(this);
rlBottomBarContainer.setId(R.id.bottomBarContainer);
rlBottomBarContainer.setClipToPadding(false);
rlBottomBarContainer.setClipChildren(false);
rlBottomBarContainer.setBackground(getResources().getDrawable(R.drawable.bara));
int topMargin = whiteTowerContainerHeight /2 + tower_height/2 + 100;
int containerHeight = whiteTowerContainerHeight - topMargin;
FrameLayout.LayoutParams containerParams = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
containerHeight);
containerParams.topMargin = topMargin;
rlBottomBarContainer.setLayoutParams(containerParams);
frameLayoutRoot.addView(rlBottomBarContainer); // parentLayout
llBottomBarContainer = new LinearLayout(this);
llBottomBarContainer.setId(R.id.upper_bottombar_ID);
llBottomBarContainer.setClipChildren(false);
llBottomBarContainer.setClipToPadding(false);
llBottomBarContainer.setBackgroundColor(Color.parseColor("#00FFFFFF"));
llBottomBarContainer.setOrientation(LinearLayout.HORIZONTAL);
RelativeLayout.LayoutParams bottomBarParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
getBottomBarTextSize());
llBottomBarContainer.setLayoutParams(bottomBarParams);
rlBottomBarContainer.addView(llBottomBarContainer);
As you can see from the code the LinearLayout is added with match_parent for the width. RelativeLayout width is from 0 to 720px but LinearLayout is from 11 to 709pixels.
First of all I do not understand why you use a FrameLayout and you do not use directly the RelativeLayout as your parent layout.
The error I see on your code is that you set a FrameLayout.LayoutParams to your RelativeLayout and a RelativeLayout.LayoutParams to your LinearLayout.
Probably this is why you get some extra spacing.
I would suggest that you do not create your layouts programmatically, but rather do it on xml and then if you need the layout objects on java you can get them with the findViewById(int id) method

Custom View in Relative Layout overlapping other Custom Views [duplicate]

Is it possible to set the absolute position of a view in Android? (I know that there is an AbsoluteLayout, but it's deprecated...)
For example, if I have a 240x320px screen, how could I add an ImageView which is 20x20px such that its center is at the position (100,100)?
You can use RelativeLayout. Let's say you wanted a 30x40 ImageView at position (50,60) inside your layout. Somewhere in your activity:
// Some existing RelativeLayout from your layout xml
RelativeLayout rl = (RelativeLayout) findViewById(R.id.my_relative_layout);
ImageView iv = new ImageView(this);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(30, 40);
params.leftMargin = 50;
params.topMargin = 60;
rl.addView(iv, params);
More examples:
Places two 30x40 ImageViews (one yellow, one red) at (50,60) and (80,90), respectively:
RelativeLayout rl = (RelativeLayout) findViewById(R.id.my_relative_layout);
ImageView iv;
RelativeLayout.LayoutParams params;
iv = new ImageView(this);
iv.setBackgroundColor(Color.YELLOW);
params = new RelativeLayout.LayoutParams(30, 40);
params.leftMargin = 50;
params.topMargin = 60;
rl.addView(iv, params);
iv = new ImageView(this);
iv.setBackgroundColor(Color.RED);
params = new RelativeLayout.LayoutParams(30, 40);
params.leftMargin = 80;
params.topMargin = 90;
rl.addView(iv, params);
Places one 30x40 yellow ImageView at (50,60) and another 30x40 red ImageView <80,90> relative to the yellow ImageView:
RelativeLayout rl = (RelativeLayout) findViewById(R.id.my_relative_layout);
ImageView iv;
RelativeLayout.LayoutParams params;
int yellow_iv_id = 123; // Some arbitrary ID value.
iv = new ImageView(this);
iv.setId(yellow_iv_id);
iv.setBackgroundColor(Color.YELLOW);
params = new RelativeLayout.LayoutParams(30, 40);
params.leftMargin = 50;
params.topMargin = 60;
rl.addView(iv, params);
iv = new ImageView(this);
iv.setBackgroundColor(Color.RED);
params = new RelativeLayout.LayoutParams(30, 40);
params.leftMargin = 80;
params.topMargin = 90;
// This line defines how params.leftMargin and params.topMargin are interpreted.
// In this case, "<80,90>" means <80,90> to the right of the yellow ImageView.
params.addRule(RelativeLayout.RIGHT_OF, yellow_iv_id);
rl.addView(iv, params);
In general, you can add a View in a specific position using a FrameLayout as container by specifying the leftMargin and topMargin attributes.
The following example will place a 20x20px ImageView at position (100,200) using a FrameLayout as fullscreen container:
XML
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/root"
android:background="#33AAFF"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
Activity / Fragment / Custom view
//...
FrameLayout root = (FrameLayout)findViewById(R.id.root);
ImageView img = new ImageView(this);
img.setBackgroundColor(Color.RED);
//..load something inside the ImageView, we just set the background color
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(20, 20);
params.leftMargin = 100;
params.topMargin = 200;
root.addView(img, params);
//...
This will do the trick because margins can be used as absolute (X,Y) coordinates without a RelativeLayout:
Just to add to Andy Zhang's answer above, if you want to, you can give param to rl.addView, then make changes to it later, so:
params = new RelativeLayout.LayoutParams(30, 40);
params.leftMargin = 50;
params.topMargin = 60;
rl.addView(iv, params);
Could equally well be written as:
params = new RelativeLayout.LayoutParams(30, 40);
rl.addView(iv, params);
params.leftMargin = 50;
params.topMargin = 60;
So if you retain the params variable, you can change the layout of iv at any time after adding it to rl.
A more cleaner and dynamic way without hardcoding any pixel values in the code.
I wanted to position a dialog (which I inflate on the fly) exactly below a clicked button.
and solved it this way :
// get the yoffset of the position where your View has to be placed
final int yoffset = < calculate the position of the view >
// position using top margin
if(myView.getLayoutParams() instanceof MarginLayoutParams) {
((MarginLayoutParams) myView.getLayoutParams()).topMargin = yOffset;
}
However you have to make sure the parent layout of myView is an instance of RelativeLayout.
more complete code :
// identify the button
final Button clickedButton = <... code to find the button here ...>
// inflate the dialog - the following style preserves xml layout params
final View floatingDialog =
this.getLayoutInflater().inflate(R.layout.floating_dialog,
this.floatingDialogContainer, false);
this.floatingDialogContainer.addView(floatingDialog);
// get the buttons position
final int[] buttonPos = new int[2];
clickedButton.getLocationOnScreen(buttonPos);
final int yOffset = buttonPos[1] + clickedButton.getHeight();
// position using top margin
if(floatingDialog.getLayoutParams() instanceof MarginLayoutParams) {
((MarginLayoutParams) floatingDialog.getLayoutParams()).topMargin = yOffset;
}
This way you can still expect the target view to adjust to any layout parameters set using layout XML files, instead of hardcoding those pixels/dps in your Java code.
Just in case it may help somebody, you may also try this animator ViewPropertyAnimator as below
myView.animate().x(50f).y(100f);
myView.animate().translateX(pixelInScreen)
Note: This pixel is not relative to the view. This pixel is the pixel
position in the screen.
credits to bpr10 answer
Place any view on your desire X & Y point
layout file
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.test.MainActivity" >
<AbsoluteLayout
android:id="#+id/absolute"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
android:id="#+id/rlParent"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/img"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/btn_blue_matte" />
</RelativeLayout>
</AbsoluteLayout>
</RelativeLayout>
Java Class
public class MainActivity extends Activity {
private RelativeLayout rlParent;
private int width = 100, height = 150, x = 20, y= 50;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AbsoluteLayout.LayoutParams param = new AbsoluteLayout.LayoutParams(width, height, x, y);
rlParent = (RelativeLayout)findViewById(R.id.rlParent);
rlParent.setLayoutParams(param);
}
}
Done
Try below code to set view on specific location :-
TextView textView = new TextView(getActivity());
textView.setId(R.id.overflowCount);
textView.setText(count + "");
textView.setGravity(Gravity.CENTER);
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12);
textView.setTextColor(getActivity().getResources().getColor(R.color.white));
textView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// to handle click
}
});
// set background
textView.setBackgroundResource(R.drawable.overflow_menu_badge_bg);
// set apear
textView.animate()
.scaleXBy(.15f)
.scaleYBy(.15f)
.setDuration(700)
.alpha(1)
.setInterpolator(new BounceInterpolator()).start();
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
layoutParams.topMargin = 100; // margin in pixels, not dps
layoutParams.leftMargin = 100; // margin in pixels, not dps
textView.setLayoutParams(layoutParams);
// add into my parent view
mainFrameLaout.addView(textView);
My code for Xamarin,
I am using FrameLayout for this purpose and following is my code:
List<object> content = new List<object>();
object aWebView = new {ContentType="web",Width="300", Height = "300",X="10",Y="30",ContentUrl="http://www.google.com" };
content.Add(aWebView);
object aWebView2 = new { ContentType = "image", Width = "300", Height = "300", X = "20", Y = "40", ContentUrl = "https://www.nasa.gov/sites/default/files/styles/image_card_4x3_ratio/public/thumbnails/image/leisa_christmas_false_color.png?itok=Jxf0IlS4" };
content.Add(aWebView2);
FrameLayout myLayout = (FrameLayout)FindViewById(Resource.Id.frameLayout1);
foreach (object item in content)
{
string contentType = item.GetType().GetProperty("ContentType").GetValue(item, null).ToString();
FrameLayout.LayoutParams param = new FrameLayout.LayoutParams(Convert.ToInt32(item.GetType().GetProperty("Width").GetValue(item, null).ToString()), Convert.ToInt32(item.GetType().GetProperty("Height").GetValue(item, null).ToString()));
param.LeftMargin = Convert.ToInt32(item.GetType().GetProperty("X").GetValue(item, null).ToString());
param.TopMargin = Convert.ToInt32(item.GetType().GetProperty("Y").GetValue(item, null).ToString());
switch (contentType) {
case "web":{
WebView webview = new WebView(this);
//webview.hei;
myLayout.AddView(webview, param);
webview.SetWebViewClient(new WebViewClient());
webview.LoadUrl(item.GetType().GetProperty("ContentUrl").GetValue(item, null).ToString());
break;
}
case "image":
{
ImageView imageview = new ImageView(this);
//webview.hei;
myLayout.AddView(imageview, param);
var imageBitmap = GetImageBitmapFromUrl("https://www.nasa.gov/sites/default/files/styles/image_card_4x3_ratio/public/thumbnails/image/leisa_christmas_false_color.png?itok=Jxf0IlS4");
imageview.SetImageBitmap(imageBitmap);
break;
}
}
}
It was useful for me because I needed the property of view to overlap each other on basis of their appearance, e.g the views get stacked one above other.

Positioning of a View at runtime

i want to use a unknown (at begin) number of Views in my CustomView, so I have to set the position of each of them programatically. The problem is that I cannot use setX()/... or seTop()/... , because Im developing for froyo. But how can I set the position else?
With RelativeLayout you can do the following:
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)child.getLayoutParams();
layoutParams.leftMargin = x;
layoutParams.topMargin = y;
child.setLayoutParams(layoutParams);

Categories

Resources