cannot add view to nested linear layout in fragment - android

I want to build whole fragment layout programatically and dynamically. So I've created this code:
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.empty_container, container, false);
final FrameLayout rootView = (FrameLayout) view.findViewById(R.id.empty_container);
final LinearLayout linearLayout = new LinearLayout(getActivity());
linearLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
linearLayout.setBackgroundColor(Color.BLACK);
rootView.addView(linearLayout);
final Button button = new Button(getActivity());
button.setBackgroundColor(Color.GREEN);
button.setText("button name");
button.setLayoutParams(new LinearLayout.LayoutParams(100, 100));
linearLayout.addView(button);
return view;
}
and the xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
android:id="#+id/empty_container"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
I cant figure out why this is not working properly. Button is not visible at all (but linear layout is visible - whole screen is black). When I set one of button Layout params to MATCH_PARENT it suddenly appears, but when I set it to 100 px or WRAP_CONTENT its not showing.

It looks like you are adding it.
Open Android Device Monitor, run the app, then check your DOM with the tree viewer. You will be able to see if Views are being added to your DOM.
developer.android.com/tools/help/hierarchy-viewer.html

Why don't you just make the root view a LinearLayout? Then you can just cast the root view to a LinearLayout, you don't need to find it by id because you already have reference to it. Also not sure what you intend by this line linearLayout.setGravity(LinearLayout.HORIZONTAL); Check this link for valid values to put into setGravity http://developer.android.com/reference/android/view/Gravity.html

The button was hiding under the toolbar, and size 100px x 100px was not enough to display it. Hierarchy viewer helped me figure this out it.

Related

add dynamic relative layout below another relative layout which is in xml

I have some relative layouts in my xml file. I want to add relative layout dynamically on click of add button below last relative layout added in my xml. I have searched n find some articles on stack overflow about it but everyone has added the layout below some dynamic view.I want to add dynamic relative layout below my static relative layout.
Code-
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
//get id of relative layout which is in xml
rlOption4=(RelativeLayout)view.findViewById(R.id.rlOption4);
}
if(v.getId()==R.id.imageButtonAdd)
{
Log.e("onclick","add");
// Creating a new RelativeLayout
RelativeLayout relativeLayout = new RelativeLayout(getActivity());
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.BELOW,rlOption4.getId());
relativeLayout.setLayoutParams(lp);
EditText optNew=new EditText(getActivity());
optNew.setText("Option 5");
relativeLayout.addView(optNew);
}
If you change the line :
relativeLayout.addView(optNew);
to
rlOption4.addView(optNew);
then optNew will be appended as a child of rlOption4 in your layout.

How to dynamically wrap root layout in a ScrollView

I want to add a scroll view to all the layouts that I have. But dynamically. Because the app will run in different screen sizes, and when I will get a screen size smaller than a specific size, then I want to show the layout in a scroll view.
So I made this method, it will be called on the check that the screen is small. I will pass my activity and I want to change the root layout to scroll view or just add a ScrollView as the root layout. So if the root layout is a LinearLayout, then I want to put that layout in the ScrollView. And I have not named all the layouts, meaning that I didn't give an ID to the layout, so I cannot use findViewById.
public static void SetActivityRoot(Activity c) {
View v = c.getWindow().getDecorView();
// View v = v.getRootView();
ScrollView sv = new ScrollView(c);
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
sv.setLayoutParams(lp);
((ViewGroup)v.getParent()).removeView(v);
sv.addView((View) v);
((ViewGroup)v.getParent()).addView(sv);
}
It's giving me an error saying that "you cannot remove view from null" etc. Or that "you cannot add view to layout as it already has parent view". How can I make this work?
Finally solved my problem.
public static void SetActivityRoot(Activity c) {
View v = ((ViewGroup)c.findViewById(android.R.id.content)).getChildAt(0);
ScrollView sv = new ScrollView(c);
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
sv.setLayoutParams(lp);
((ViewGroup) v.getParent()).removeAllViews();
sv.addView((View) v);
c.addContentView(sv, lp);
}

Programatically add LinearLayout in fragment with padding between buttons

I want to know how to add or link with findviewID a LinearLayout with multiple buttons (programatically added) and space between them. I have tried to create a XML layout in my fragment and link it to a variable of the type LinearLayout and work from there with LayoutParams but I don't get it to work properly. I would like to know if anyone here has any suggestions. below is my code.
private GuiLoader guiloader = new GuiLoader();
private LinearLayout layout;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.media_list_fragment, container, false);
layout = (LinearLayout)v.findViewById(R.id.LinearLayout1);
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT, 2.0f);
param.setMargins(100, 100, 100, 100);
layout.setPadding(500, 86, 50, 50);
layout.setLayoutParams(param);
and the button creation throug a class
for (final VideoDevice videoDevice : videoDevices) {
Button myButton = guiloader.createButton(getActivity());
myButton.setBackgroundColor(getResources().getColor(R.color.green));
myButton.setText(videoDevice.description);
layout.addView(myButton, guiloader.buttonWidth, guiloader.buttonHeight);
Thanks in advance!
When you call setPadding and setLayoutParams on your LinearLayout - this deals with the padding/margins around the edges of the LinearLayout - not between the buttons.
It sounds like you would like to have a gap between the buttons. For that, you can:
1) add a margin to each button inside your for loop
2) consider using GridView which allows you to specify the spacing between children using android:horizontalSpacing and android:verticalSpacing

How to add View dynamically from right side in Android?

I need to layout the views from the RIGHT side in a Fragment in Android, however, android did not layout the sub views as what I thought.
I tried to add a TableLayout and an ImageView to a LINEARLAYOUT, the width of the ImageView was fixed and the width of TableLayout is dynamic. Furthermore, the ImageView need to be located on the right side.
Part of the source code:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
Context c = getActivity().getApplicationContext();
LinearLayout l = new LinearLayout(c);
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT, 0);
params.gravity = Gravity.RIGHT;
l.setLayoutParams(params);
// l.setGravity(Gravity.RIGHT);
PankouAttachmentView pav = new PankouAttachmentView(c, null);
pav.setLayoutParams(params);
l.addView(pav);
ImageView iv = new ImageView(c);
iv.setClickable(true);
iv.setFocusable(true);
iv.setImageResource(R.drawable.testarrow);
iv.setMaxWidth(BUTTON_WIDTH);
iv.setLayoutParams(new LayoutParams(BUTTON_WIDTH,
LayoutParams.MATCH_PARENT));
l.addView(iv);
return l;
}
Any help will be appreciated.THX :)
I'm not sure I completely understand your question but have you tried using a relative layout? Relative layout lets you accomplish much easier than a linear layout. See the android hello views tutorial.

Place view inside FrameLayout in Android

I want to add a view inside a FrameLayout programmatically and to place it in a specific point within the layout with a specific width and height. Does FrameLayout support this? If not, should I use an intermediate ViewGroup to achieve this?
int x; // Can be negative?
int y; // Can be negative?
int width;
int height;
View v = new View(context);
// v.setLayoutParams(?); // What do I put here?
frameLayout.addView(v);
My initial idea was to add an AbsoluteLayout to the FrameLayout and place the view inside the AbsoluteLayout. Unfortunately I just found out that AbsoluteLayout is deprecated.
Any pointers will be much appreciated. Thanks.
The following example (working code) shows how to place a view (EditText) inside of a FrameLayout. Also it shows how to set the position of the EditText using the setPadding setter of the FrameLayout (everytime the user clicks on the FrameLayout, the position of the EditText is set to the position of the click):
public class TextToolTestActivity extends Activity{
FrameLayout frmLayout;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
frmLayout = (FrameLayout)findViewById(R.id.frameLayout1);
frmLayout.setFocusable(true);
EditText et = new EditText(this);
frmLayout.addView(et,100,100);
frmLayout.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.i("TESTING","touch x,y == " + event.getX() + "," + event.getY() );
frmLayout.setPadding(Math.round(event.getX()),Math.round(event.getY()) , 0, 0);
return true;
}
});
}
}
main.xml
<?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">
<FrameLayout
android:id="#+id/frameLayout1"
android:layout_height="fill_parent" android:layout_width="fill_parent">
</FrameLayout>
</LinearLayout>
You can also add a margin around the newly added view to position it inside the FrameLayout.
FrameLayout frameLayout = (FrameLayout) findViewById(R.id.main); // or some other R.id.xxx
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.setMargins(0, metrics.heightPixels - 20, 0, 0);
View v = new View(context);
v.setLayoutParams(params);
frameLayout.addView(v);
This will position the FrameLayout 20 pixels from the bottom of the screen.
Edit: completed the example so it stands by itself. And oh, yes it does work.
It's true that with FrameLayout all children are pegged to the top left of the screen, but you still have some control with setting their padding. If you set different padding values to different children, they will show up at different places in the FrameLayout.
From the link Quinn1000 provided:
You can add multiple children to a FrameLayout, but all children are pegged to the top left of the screen.
This means you can't put your View at a specific point inside the FrameLayout (except you want it to be at the top left corner :-)).
If you need the absolute positioning of the View, try the AbsoluteLayout:
A layout that lets you specify exact locations (x/y coordinates) of its children. Absolute layouts are less flexible and harder to maintain than other types of layouts without absolute positioning.
As for setting the width and height of the View, also like Quinn1000 said, you supply the v.setLayoutParams() method a LayoutParams object, depending on the container you chose (AbsoluteLayout, LinearLayout, etc.)
The thread here on stackOverflow at
How do you setLayoutParams() for an ImageView?
covers it somewhat.
For instance:
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(30, 30);
yourImageView.setLayoutParams(layoutParams);
implies that you need to be defining a LinearLayout.LayoutParams (or in your case a FrameLayout.layoutParams) object to pass to the setLayoutParams method of your v object.
At
http://developer.android.com/reference/android/widget/FrameLayout.html
it almost makes it looks like you could ask your v to:
generateDefaultLayoutParams () via this method if you have not defined the parameters specifically.
But it's late, and those links are making my eyes bleed a little. Let me know if they nhelp any :-)

Categories

Resources