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.
Related
I'm creating the above popup, the content of which consists of rows of horizontal LinearLayout views within a main vertical LinearLayout. Each horizontal LinearLayout contains one ImageView and one TextView.
I'm creating this within a PopupWindow, and doing so programmatically so that I can change the ImageView source as required.
As you can see the first icon seems to take up a lot of space, despite having the same code generating it as the other icons.
Below is the code:
LinearLayout verticalLayout = new LinearLayout(context);
verticalLayout.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams mainLayoutParams =
new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
verticalLayout.setLayoutParams(mainLayoutParams);
LinearLayout.LayoutParams layoutParams =
new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
LinearLayout.LayoutParams iconParams =
new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
LinearLayout.LayoutParams textParams =
new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
//History row
LinearLayout historyLayout = new LinearLayout(context);
historyLayout.setLayoutParams(layoutParams);
historyLayout.setOrientation(LinearLayout.HORIZONTAL);
ImageView historyIcon = new ImageView(context);
historyIcon.setImageResource(R.drawable.small_book_grey);
historyIcon.setAdjustViewBounds(true);
historyIcon.setLayoutParams(iconParams);
historyLayout.addView(historyIcon);
TextView historyText = new TextView(context);
historyText.setLayoutParams(textParams);
historyText.setText("History");
historyLayout.addView(historyText);
verticalLayout.addView(historyLayout);
//Exam row...
//... (duplicate of history row)
I've tried playing around with the layout parameters, even creating a mock xml layout that displays the content as I'd like, to match the parameters to.
If anyone can give some advice on making that book icon the same size as the others, I'd be grateful.
Add a scaleType to ImageView of fitCenter
Write this code under historyIcon.setAdjustViewBounds(true);
historyIcon.setWidth()`
And put width according to your layout.
Although I didn't figure out why the first image was scaling differently to the other images, I did find another solution: Using compound left drawables.
historyText.getViewTreeObserver()
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
Drawable img = m_context.getResources().getDrawable(
R.drawable.small_book_grey);
img.setBounds(0, 0, img.getIntrinsicWidth() * historyText.getMeasuredHeight() / img.getIntrinsicHeight(), historyText.getMeasuredHeight());
historyText.setCompoundDrawables(img, null, null, null);
historyText.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
Manually setting the bounds to match the TextView worked. Seems clunky, but it was the only way I could get it to do what I was aiming for.
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.
I want to create vertical LinearLayout with couple of Button children, where each child has width of widest of them.
However depending on using MATCH_PARENT or WRAP_CONTENT for children width, I get either LinearLayout taking whole screen's width, or Buttons not filling LinearLayout. Screenshots below (fill/wrap):
Example Activity code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RelativeLayout mainView = new RelativeLayout(this);
mainView.setBackgroundColor(Colors.WHITE);
String[] buttonsNames = new String[] { "Short", "Looooooong", "Medium" };
View buttonsView = getButtonsView(buttonsNames);
mainView.addView(buttonsView, new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT));
setContentView(mainView);
}
private View getButtonsView(String[] buttonNames) {
LinearLayout buttonsView = new LinearLayout(this);
buttonsView.setOrientation(LinearLayout.VERTICAL);
buttonsView.setBackgroundColor(Colors.BLACK);
for (int i = 0; i < buttonNames.length; i++) {
Button button = new Button(this);
button.setText(buttonNames[i]);
///////////// HERE LAYS THE PROBLEM //////////
buttonsView.addView(button, new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
//LinearLayout.LayoutParams.WRAP_CONTENT, // neither of them works
LinearLayout.LayoutParams.WRAP_CONTENT));
View redLineDivider = new View(this);
redLineDivider.setBackgroundColor(Colors.RED);
buttonsView.addView(redLineDivider, new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, 2));
}
return buttonsView;
}
As you can see on second screenshot, red lines actually take whole width without stretching LinearLayout - it is because at least one view has set width.
Potential fix I have came up with is to find widest button (with longest text) and make it use WRAP_CONTENT, while all the rest use MATCH_PARENT, which gives me expected result:
Code:
buttonsView.addView(button, new LinearLayout.LayoutParams(
isLongestText(i) ? LinearLayout.LayoutParams.WRAP_CONTENT
: LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
It doesn't feel like elegant solution though - is there any intended mechanism for situation like this, that I am missing out?
Following is the trick:
Mention the width of the LinearLayout containing the buttons (buttonsView in your code) as WRAP_CONTENT.
Mention the width of each button as MATCH_PARENT
Your program should give you the expected result if you do not include the redLineDivider View. There seems to be some issue with setting the width of redLineDivider. As an alternative you can declare it as a LinearLayout to make your code work perfectly.
// View redLineDivider = new View(this);
// Instead declare it as a LinearLayout
LinearLayout redLineDivider = new LinearLayout(this);
Hope this will be useful.
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);
}
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