Dynamically set views using the LayoutParams.addRule parameter for the last view position

I dynamically add views to the relative layout and programmatically define them. Views can be moved around the screen to change their position.

When I try to set the view (button2) to sit below another view (button1), button2 is placed in the old location of button1 (the default location is where the views are added before moving). I linked the images to hope to convey this better.

This is the layout of the original. Original layout

Layout after clicking Button2 Re-positioned layout

I have a LinkedList link tracking all view changes and presentation attributes for the layout, if that matters.

Here are the code functions:

How do I redefine Button1:

Buttons b = (Buttons) viewIndex; positioningLayout = new RelativeLayout.LayoutParams(b.getLayoutParams()); positioningLayout.addRule(RelativeLayout.CENTER_VERTICAL); b.setLayoutParams(positioningLayout); baseLayout.addView(b); 

Moving views under a different kind of code snippet:

 Buttons b = (Buttons) viewIndex; positioningLayout = new RelativeLayout.LayoutParams(b.getLayoutParams()); positioningLayout.addRule(RelativeLayout.BELOW, viewIdFromList.intValue()); b.setLayoutParams(positioningLayout); b.invalidate(); 

How do I add views to the layout.

 uiList.addView(new Buttons(this), "BUTTON"); setDialogView(uiList.getLast()); showDialog(SET_ID); reloadUI(); 

setDialogView simply passes the view to Dialog SET_ID so that I can manually assign an ID for the view (for testing). reloadUI () simply finds the last view added to the LinkedList background and adds it to relativeLayout using .addView;

If you need more code, please let me know. Am I missing a call to update view layouts after making changes to relativeLayout child views? It seems that the view becomes visually positioned, but the actual LayoutParams are not updated, so when you set Button2 to Button1, it gets the old position.

Is there a way to force the relative position of the view to be set?

+5
source share
3 answers

I think you should try a simple solution - replace b.invalidate() with b.requestLayout() . For additional background check this link . I have not tested, but hope this works. Therefore, the code should look like this:

 Buttons b = (Buttons) viewIndex; positioningLayout = new RelativeLayout.LayoutParams(b.getLayoutParams()); positioningLayout.addRule(RelativeLayout.BELOW, viewIdFromList.intValue()); b.setLayoutParams(positioningLayout); b.requestLayout(); 

Or maybe you can simplify this:

 Buttons b = (Buttons) viewIndex; ((RelativeLayout.LayoutParams) b.getLayoutParams()).addRule(RelativeLayout.BELOW, viewIdFromList.intValue()); b.requestLayout(); 
+2
source

You seem to be in the right direction, but you are making a small mistake. Without additional code, it is quite difficult to provide the actual solution. But I will try to point out the error.

Please note: for relatively positional elements programmatically in RelativeLayout you must assign unique identifiers for each of them.

How,

 Button b = new Button(this); b.setId(1); Button c = new Button(this); c.setId(2); 

Each item must have unique identifiers.

Now, if you want to place the b button vertically in the center,

 layout.addRule(RelativeLayout.CENTER_VERTICAL); b.setLayoutParams(layout); 

Now, if you want to place the c button below,

 layout.addRule(RelativeLayout.BELOW, b.getId()); layout.addRule(RelativeLayout.ALIGN_PARENT_LEFT); b.setLayoutparams(layout); 

This will certainly lead to the c button below the b button. As you said, you can use any data structure of your choice to track the identifiers of each element.

+1
source

This is just a detailed example of how you move the button correctly. So, first create a unique identifier for the View , i.e. Create a new XML resource file in res/values/ and name it ids.xml :

structure

And the contents of ids.xml :

 <?xml version="1.0" encoding="utf-8"?> <resources> <item name="button_1" type="id"/> <item name="button_2" type="id"/> </resources> 

We must set the id in your main layout:

 <?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" android:id="@+id/layout_main"> <!-- the id --> <!-- content of this layout --> </RelativeLayout> 

Then create Button s:

  RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.layout_main); final Button button1 = new Button(this); button1.setId(R.id.button_1); button1.setText("BUTTON 1"); button1.setTextColor(Color.BLACK); final Button button2 = new Button(this); button2.setId(R.id.button_2); button2.setText("BUTTON 2"); button2.setTextColor(Color.BLACK); relativeLayout.addView(button1, new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT)); relativeLayout.addView(button2, new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT)); RelativeLayout.LayoutParams params1 = (RelativeLayout.LayoutParams) button1.getLayoutParams(); params1.addRule(RelativeLayout.CENTER_IN_PARENT); // set to the center of screen button1.setLayoutParams(params1); final RelativeLayout.LayoutParams params2 = (RelativeLayout.LayoutParams) button2.getLayoutParams(); params2.addRule(RelativeLayout.ALIGN_PARENT_TOP); params2.addRule(RelativeLayout.ALIGN_PARENT_LEFT); button2.setLayoutParams(params2); button2.setOnClickListener(new View.OnClickListener() { @SuppressLint("NewApi") @Override public void onClick(View v) { /* We need to remove the existing rules and update it! * For API 16 and earlier, set the rule to 0, eg --> layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0); * For API 17 and higher, call layoutParams.removeRule(RelativeLayout.ALIGN_PARENT_LEFT); */ int api = android.os.Build.VERSION.SDK_INT; if (api >= Build.VERSION_CODES.JELLY_BEAN_MR1) { // API level 17 params2.removeRule(RelativeLayout.ALIGN_PARENT_TOP); params2.removeRule(RelativeLayout.ALIGN_PARENT_LEFT); }else if (api < Build.VERSION_CODES.JELLY_BEAN_MR1) { params2.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0); params2.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0); } params2.addRule(RelativeLayout.CENTER_IN_PARENT); params2.addRule(RelativeLayout.BELOW, R.id.button_1); // place below button1 button2.setLayoutParams(params2); } }); 

So, as soon as you press button2 , it will move below button1 .

+1
source

All Articles