I need to separate tab buttons with space, I tried to set margin to views and then add them as tabs, but it does not work, I also thought of adding empty view as divider, but haven't tried it yet, is there any standard way of doing this, or any tweak that can achieve same effect?
Thanks!
Here's the way:
TabWidget tabWidget = (TabWidget) findViewById(android.R.id.tabs);
final int tabChildrenCount = tabWidget.getChildCount();
View currentView;
for (int i = 0; i < tabChildrenCount; i++) {
currentView = tabWidget.getChildAt(i);
LinearLayout.LayoutParams currentLayout =
(LinearLayout.LayoutParams) currentView.getLayoutParams();
currentLayout.setMargins(0, 5, 5, 0);
}
tabWidget.requestLayout();
This is really a good solution even for my problem! Many thanks for that! I used it to implement space before the first and after the last item in the widget to have the possibility to scroll them visible to the center without adding additional (and disturbing, because the widget does not excpect such silly things) invisible buttons.
//pump up space for first entry on the left and last entry on the right!
Display display = getWindowManager().getDefaultDisplay();
//Point size = new Point();
int width = display.getWidth();
View currentView = mTabHost.getTabWidget().getChildAt(0);
LinearLayout.LayoutParams currentLayout = (LinearLayout.LayoutParams) currentView.getLayoutParams();
currentLayout.setMargins(currentLayout.leftMargin + width/2, currentLayout.topMargin, currentLayout.rightMargin, currentLayout.bottomMargin);
currentView = mTabHost.getTabWidget().getChildAt(mTabHost.getTabWidget().getChildCount()-1);
currentLayout = (LinearLayout.LayoutParams) currentView.getLayoutParams();
currentLayout.setMargins(currentLayout.leftMargin, currentLayout.topMargin, currentLayout.rightMargin + width/2, currentLayout.bottomMargin);
mTabHost.getTabWidget().requestLayout();
Related
I'm currently using a TabLayout in my application.
I set GRAVITY_FILL and MODE_FIXED but that does not accomplish what I want.
I have 3 tabs all the time. The left and the right tab header only show a small Icon while the middle tab has a long text.
This is what I want:
[________TOTAL WIDTH__________]
[Icon][A very long tab header][Icon2]
This is how it looks like:
[__________________________TOTAL WIDTH__________________________]
[_________Icon________][A very long tab header][_________Icon2________]
So as you can hopefully see from my poor illustration I want to have the middle tab take about 70% of the space and give the rest to the 2 tabs with the icons.
Now I have already done some research and people suggest that I extend some of the layout classes but I could not get it to work.
Can someone please be so kind to let me know if this is possible and how I would achieve it.
this is the only solution of your problem
int padding_in_dp = 2; // 6 dps
final float scale = getResources().getDisplayMetrics().density;
int padding_in_px = (int) (padding_in_dp * scale + 0.5f);
for (int i = 0; i < 3; i++) {
TabLayout.Tab tab = mTabLayout.newTab();
mTabLayout.addTab(tab);
LinearLayout layout = ((LinearLayout) ((LinearLayout) mTabLayout.getChildAt(0)).getChildAt(i));
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) layout.getLayoutParams();
layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT;
layout.setLayoutParams(layoutParams);
layout.setPadding(padding_in_px, 0, padding_in_px, 0);
tab.setText(array[i]);
}
It will surely help you
I'm trying to make a dynamic grid layout, it being API 10+ is the part that's been making it slow going. I tried to make it wrap automatically.. but in the end found it easier just to try to force it into a grid pattern using coordinates. This script was working by itself when I did the positioning at time of creation, but now I am trying to loop through each item as a sort. So if one item is deleted, they all float back into a grid without a hole in the middle.
Problem is, it seems the layout parameters are only applying to the last object.
Here's some base variables and onCreate setup:
int screenWidth;
int screenHeight;
int distStep = 130;
int leftPad = 20;
int numCols;
int baseID = 0;
android.util.DisplayMetrics metrics = this.getResources().getDisplayMetrics();
screenWidth = metrics.widthPixels;
screenHeight = metrics.heightPixels;
numCols = (int) (screenWidth - leftPad) / distStep;
int scrRemain = screenWidth - ((numCols * distStep) + leftPad);
distStep += (int) scrRemain / numCols;
Then on to the main function for adding:
public void addObjToLayout() {
RelativeLayout relLay = (RelativeLayout) this.findViewById(R.id.mainWindow);
for(int i = 1; i <= currQuantity; i++){
TextView tv=new TextView(this);
tv.setTextSize(40);
tv.setId(baseID + i);
tv.setPadding(24, 4, 24, 4);
tv.setBackgroundColor(0x110000FF);
tv.setText(String.valueOf(baseID + i)); //Val for debugging
tv.setTextColor(0xFFFFFFFF);
relLay.addView(tv);
}
baseID += currQuantity;
sortLayout();
}
Then the sorting:
public void sortLayout() {
int leftNum = 20;
int topNum = 0;
for(int i = 1; i <= baseID; i++){
TextView tv= (TextView) this.findViewById(baseID);
MarginLayoutParams mp = new MarginLayoutParams(tv.getLayoutParams());
mp.setMargins(leftNum, topNum, 0, 0);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(mp);
tv.setLayoutParams(lp);
leftNum += distStep;
if(leftNum >= distStep * numCols){
leftNum = leftPad;
topNum += distStep;
}
}
}
What I am getting is all the textViews pile up in the top left corner, except the last one which is positioned exactly where it should be. So it seems in my head, the params object isn't applying until the loop ends or something.. but logically I don't see why.
As I said, this worked when I set the params at the get go, problem is mass updating them all at once. I am pretty new to android, so I hope I'm not just doing something stupid.
Thanks for your time
Margin means it will set a gap between the previous view and current view.
When you add view1, view2 and view3 to grid layout and if you remove view2 at some point of time, then the margin for view3 is set according to view1. So, it won't leave empty space in place of view2. Instead of removing view2 at run time, set the background for view2 as null and set the text as empty as below.
textView.setBackground(null);
textView.setText("");
So that the view is still available but looks as deleted.
Started looking into GridView using an extended baseAdapter. Looks promising:
For more (see #2):
http://www.mkyong.com/android/android-gridview-example/
I was wondering how I could "randomly" place an array of Buttons in a RelativeLayout?
Is it possible to space the buttons around the entire view?
Thanks for your help! I tried using setX() and setY() but they are float numbers and I'm unsure how they place the buttons in proportion to the size of the screen.
You can add layout margins to your buttons. As margins will be interpreted not relative to each other but to the frame, it will in fact position your buttons.
To set the margins you have to set the view's layout params:
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
Random random = new Random();
params.leftMargin = random.nextInt(100);
params.topMargin = random.nextInt(100);
button.setLayoutParams(params);
However this may cause your buttons to overlap, or be outside the Activity, so it's best not to use entirely random values for positions but to perform checks for overlapping and set random ranges according to the device resolution and button size.
To get device display size:
Display display= activity.getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int Height = display.getHeight();
instead do something like this first create a button array and find the respective id...
LayoutParams lp = new LinearLayout.LayoutParams(widthOfButtons,LayoutParams.WRAP_CONTENT);
Button[] buttons;
for(int i=0; i<4; i++) { //suppose you have four buttons
{
String buttonID = "button" + (i+1);
int resID = getResources().getIdentifier(buttonID, "id", getPackageName());
buttons[i] = ((Button) findViewById(resID));
buttons[i].setHeight(yourvalue);
buttons[i].setWidth(yourvalue);
buttons[i].setLayoutParams(lp);
}
hope it works for your
the thing which I want to achieve in my application is to create dynamically a set of buttons with different text size and after that align these view inside a linear layout. Here is a sample of what I want to achieve :
. Depending on the textsize I want the buttons to be align in a single line, if the last button is bigger than the screen size, it should properly go to the next line.
Any suggestions how can I achieve this or what should I look for, because I know that if I try button.getWidth(); it will return 0 and it won't work.
Thanks for any kind of suggestions!
EDIT
To achieve this you can use a new layout open sources by Google called: FlexboxLayout. You can learn more about it in this post from Android Developers Blog.
Thanks to #Kameswari 's code which gave me the right direction I achieve this by using :
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
params.setMargins(5, 5, 5, 5);
String[] mKeywordsArray = mKeywords.split(", ");
if(mKeywordsArray != null){
LinearLayout mNewLayout = new LinearLayout(getActivity()); // Horizontal layout which I am using to add my buttons.
mNewLayout.setOrientation(LinearLayout.HORIZONTAL);
int mButtonsSize = 0;
Rect bounds = new Rect();
for(int i = 0; i < mKeywordsArray.length; i++){
String mButtonTitle = mKeywordsArray[i];
Button mBtn = new Button(getActivity());
mBtn.setPadding(10, 3, 10, 3);
mBtn.setText(mButtonTitle);
Paint textPaint = mBtn.getPaint();
textPaint.getTextBounds(mButtonTitle, 0, mButtonTitle.length(), bounds);
// size of all buttons in current horizontal layout
// i am using +45 because of extra padding which is set in xml for this layout
mButtonsSize += ( bounds.width() + 45);
if(mButtonsSize < (mScreenWidth - 32)){ // -32 because of extra padding in main layout.
mNewLayout.addView(mBtn, params);
} else {
mButtonsLayout.addView(mNewLayout);
mNewLayout = new LinearLayout(getActivity());
mNewLayout.setOrientation(LinearLayout.HORIZONTAL);
mButtonsSize = bounds.width();
mNewLayout.addView(mBtn, params); // add button to a new layout so it won't be stretched because of it's width.
}
}
mButtonsLayout.addView(mNewLayout); // add the last layout/ button.
}
You can try the following
While adding the buttons you can calculate the how much width till occupied as
occupiedWidth = button1Width + button2Width + ...
Every button width = textWidth + 2*margin + 2*padding
You can get your width of the text which you put on the button like
String buttonText = "<Your Button Text>"
paint.getTextBounds(buttonText, 0, buttonText.length(), bounds);
int textWidth = bounds.width();
Add this new button margins and paddings as
int newWidth = textWidth + buttonMargin*2 + buttonPadding*2;
if the total width is exceeding the screenwidth then move to next row.
According to me, you have 2 options:
1) Take a linear layout with horizontal orientation.
and keep adding buttons to this layout programmatically.
if the width of the button is not able to fit in the line, it will automatically go to next line in linear layout.
ViewGroup linearLayout = (ViewGroup) findViewById(R.id.linearLayoutID);
Button bt = new Button(this);
bt.setText("A Button");
bt.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
linerLayout.addView(bt);
2) You can calculate x,y location of each button as mentioned by #kameswari and draw corresponding button at x,y location
Button button = (Button)findViewById(R.id.button);// or new Button(this);
AbsoluteLayout.LayoutParams absParams =
(AbsoluteLayout.LayoutParams)button.getLayoutParams();
absParams.x = X;
absParams.y = Y;
button.setLayoutParams(absParams);
u can try this `enter code here`
LinearLayout.LayoutParams leftMarginParams = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
leftMarginParams.leftMargin = 50;
Button btn1 = new Button(this);
btn1.setText("Button1");
linLayout.addView(btn1, leftMarginParams)
I'm adding some views to a LinearLayout with a slight overlap in the top, here is the code:
viewHolder.linearLayout.removeAllViews();
for (int i = 0; i < conversation.getPreviousMessages().length; i++) {
View messageView = layoutInflater.inflate(R.layout.layout_previous_message_row, null);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(0, -5, 0, 0);
viewHolder.linearLayout.addView(messageView, layoutParams);
}
In this code some views are added to layout in order A, B, C, with A to the back and C to the front.
I would like to reverse the order, making A to the front and C to the back.
I have tried this, but nothing happens.
How can I reach this?
Please, could you people bring me some code?
Thanks in advance.
There is the capability to change the z-order of a view if that is the question that you are asking. And if so desired, you can usually get the effect of using the View.bringToFront() capabilities within that class.
View.bringToFront
After some punches against the wall, I finally found a solution:
1.- I changed the layout from being a LinearLayout to being a RelativeLayout because bringChildToFront has a weird behavior among LinearLayout.
2.- After adding the view to the RelativeLayout, I iterated backwards over the views and I made a bringChildToFront.
Here is the code:
for (int i = 0; i < conversation.getPreviousMessages().length; i++) {
View messageView = layoutInflater.inflate(R.layout.layout_previous_message_row, null);
messageView.setId(99+i);
viewHolder.relativeLayout.addView(messageView);
if (i > 0) {
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(0, -5, 0, 0);
layoutParams.addRule(RelativeLayout.BELOW, 99+i-1);
messageView.setLayoutParams(layoutParams);
}
}
for (int i = viewHolder.relativeLayout.getChildCount() - 1; i >= 0; i--) {
viewHolder.relativeLayout.bringChildToFront(viewHolder.relativeLayout.getChildAt(i));
}
I hope it help someone.