Android TabLayout fixed mode but different weights - android

I have 4 tabs, one of them has the double size of others, so the weights will be: 20% 40% 20% 20%
But when I use TabLayout (from the android design support library) setting the mode to fixed, then I'm forced to have the same weight for all! here's the part of their source code that applies the width:
private void updateTabViewLayoutParams(LinearLayout.LayoutParams lp) {
if (mMode == MODE_FIXED && mTabGravity == GRAVITY_FILL) {
lp.width = 0;
lp.weight = 1;
} else {
lp.width = LinearLayout.LayoutParams.WRAP_CONTENT;
lp.weight = 0;
}
}
But I need different weights, and to fit the screen width. Any way to apply my own weights?

//SlidingTabStrip in TabLayout
ViewGroup slidingTabStrip = (ViewGroup)mTablayout.getChildAt(0);
//second tab in SlidingTabStrip
View tab1 = slidingTabStrip.getChildAt(1);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) tab1.getLayoutParams();
layoutParams.weight = 2;
tab1.setLayoutParams(layoutParams);

Related

Different tab width for TabLayout

I'm using TabLayout & ViewPager.
I am trying to change the size of the Tab, like Whatsapp (camera icon).
The size of the three Tabs is equal, but the Tab of the camera is smaller.
In every attempt I make the size of the Tabs remains the same (equal across all tabs).
Thanks.
You need to lower the weight of the LinearLayout of the corresponding tab.
LinearLayout layout = ((LinearLayout) ((LinearLayout) tabLayout.getChildAt(0)).getChildAt(YOUR_TAB_NUMBER));
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) layout.getLayoutParams();
layoutParams.weight = YOUR_WEIGHT; // e.g. 0.5f
layout.setLayoutParams(layoutParams);
Hope that helps!
#digger's answer is working. However, if you want the tab which has an icon only wraps its content, you can set weight to 0 and width to LinearLayout.LayoutParams.WRAP_CONTENT. It worked for me.
fun TabLayout.setTabWidthAsWrapContent(tabPosition: Int) {
val layout = (this.getChildAt(0) as LinearLayout).getChildAt(tabPosition) as LinearLayout
val layoutParams = layout.layoutParams as LinearLayout.LayoutParams
layoutParams.weight = 0f
layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT
layout.layoutParams = layoutParams
}
Here I have taken 5 tabs and made 1st tab width is 12% of screen width and rest 4 are sharing remaining width. Doing it after some delay of 400 msec after inflating the views.
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int width= displaymetrics.widthPixels;
int widthOtherThanFirst= (int) ((float)width*(8.80f/10f));
int allOther=widthOtherThanFirst/4;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
LinearLayout layout1 = ((LinearLayout) ((LinearLayout)tabLayout.getChildAt(0)).getChildAt(0));
LinearLayout.LayoutParams layoutParams1 = (LinearLayout.LayoutParams) layout1.getLayoutParams();
layoutParams1.width = width-widthOtherThanFirst;
layout1.setPadding(0,0,0,0);
layout1.setLayoutParams(layoutParams1);
LinearLayout layout2 = ((LinearLayout) ((LinearLayout)tabLayout.getChildAt(0)).getChildAt(1));
LinearLayout.LayoutParams layoutParams2 = (LinearLayout.LayoutParams) layout2.getLayoutParams();
layoutParams2.width = allOther;
layout2.setLayoutParams(layoutParams2);
LinearLayout layout5 = ((LinearLayout) ((LinearLayout)tabLayout.getChildAt(0)).getChildAt(2));
LinearLayout.LayoutParams layoutParams5 = (LinearLayout.LayoutParams) layout5.getLayoutParams();
layoutParams5.width = allOther;
layout5.setLayoutParams(layoutParams5);
LinearLayout layout3 = ((LinearLayout) ((LinearLayout)tabLayout.getChildAt(0)).getChildAt(3));
LinearLayout.LayoutParams layoutParams3 = (LinearLayout.LayoutParams) layout3.getLayoutParams();
layoutParams3.width = allOther;
layout3.setLayoutParams(layoutParams3);
LinearLayout layout4 = ((LinearLayout) ((LinearLayout)tabLayout.getChildAt(0)).getChildAt(4));
LinearLayout.LayoutParams layoutParams4 = (LinearLayout.LayoutParams) layout4.getLayoutParams();
layoutParams4.width = allOther;
layout4.setLayoutParams(layoutParams4);
tabLayout.invalidate();
}
},400);
Check this for dynamic width with wrap_content background
private fun setTabwidth(tabposition: Int, weight: Float) {
val layout: LinearLayout = tabLayout?.getChildAt(0) as LinearLayout).getChildAt(tabpos) as LinearLayout
val layoutParams: LinearLayout.LayoutParams = layout.getLayoutParams() as LinearLayout.LayoutParams
layoutParams.weight = weight
layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT
layout.setLayoutParams(layoutParams)
val tablayoutParams: ViewGroup.LayoutParams? = tabLayout?.layoutParams
tablayoutParams?.width=ViewGroup.LayoutParams.WRAP_CONTENT
tabLayout?.layoutParams=tablayoutParams
}
Usage:
setTabwidth(0,0.4f) // first tab 0.4 weight
setTabwidth(1,0.6f) // second tab 0.6 weight

Android Tablayout: 3 Tabs, let center tab take 70% of available width

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

How to reduce the padding/margins of the Holo DatePicker & TimePicker?

Is it possible to make the Holo DatePicker & TimePicker smaller or reduce padding/margins? I'm having trouble getting elements to fit on the screen when I use Theme.Holo.Light.Dialog as the style. If I use Theme.Dialog as the style it all fits.
This is the dialog as it appears on the HTC One V (please excuse the pic of the phone, I couldn't get it to save screenshots):
You can see that the buttons are being clipped at the bottom. If the DatePicker & TimePicker didn't take up so much space it would all fit.
This is the dialog as it appears on the Galaxy S4 (for reference):
And this is how the Theme.Dialog appears on the HTC (you can see that there is no wasted space):
easiest solution what I found was:
setting negative margin to date/time pickerView.
<DatePicker
android:id="#+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:calendarViewShown="false"
android:datePickerMode="spinner"
android:layout_marginTop="-32dp"
android:layout_marginBottom="-32dp"
tools:ignore="UnusedAttribute"/>
The problem surely comes from the screen's size and Holo defines only one layout with raw margins (in DP).
Override the layout XML file here by importing it in your project's resources. Make sure to save the file in the folder corresponding to your phone's screen size.
Then, you'll be pleased to change the layout properties such as margins.
For the Holo TimePicker you can use this.
public static void setTimePickerHeightTopBottomMargin(
TimePicker timePicker, int height, int topMargin, int bottomMargin) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
try {
Field f;
View v;
ViewGroup.MarginLayoutParams params;
// mHourSpinner
f = TimePicker.class.getDeclaredField("mHourSpinner");
f.setAccessible(true);
v = (View) f.get(timePicker);
params = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
params.height = height;
params.topMargin = topMargin;
params.bottomMargin = bottomMargin;
// mMinuteSpinner
f = TimePicker.class.getDeclaredField("mMinuteSpinner");
f.setAccessible(true);
v = (View) f.get(timePicker);
params = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
params.height = height;
params.topMargin = topMargin;
params.bottomMargin = bottomMargin;
// mAmPmSpinner
f = TimePicker.class.getDeclaredField("mAmPmSpinner");
f.setAccessible(true);
v = (View) f.get(timePicker);
params = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
params.height = height;
params.topMargin = topMargin;
params.bottomMargin = bottomMargin;
} catch (Exception e) {
Log.w(TAG, e);
}
}
}
Units are pixels so make sure to convert from dp. Don't use heights less than 120dp.
Keeping the height and removing the vertical margins should normally be sufficient:
setTimePickerHeightTopBottomMargin(mTimePicker,
ViewGroup.LayoutParams.WRAP_CONTENT, 0, 0);
Although I've not tested it it should be the same for DatePicker by using reflection on fields mDaySpinner, mMonthSpinner and mYearSpinner instead.

Setting margins on RelativeLayout doesnt work on Kindle Fire

This is similar to my previous question but it didnt work with the Kindle Fire (2.3.4).
I used a FragmentTransaction to add a Fragment into a FrameLayout. I want to dynamically change the margin of the RelativeLayout used by the Fragment.
However, the margins are not changing with FrameLayout.layoutParams on the Kindle Fire. However, this works on 3.2.1. I also tried using setMargins() and it didnt work.
Does anyone know how I can dynamically change the margins on the Kindle Fire?
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.infocard, container, false);
RelativeLayout infoLayout = (RelativeLayout) view.findViewById(R.id.info);
infoLayout.setOnClickListener(new EmptyClickListener());
final int width = 250;
final int height = 270;
int leftMargin = 0;
int topMargin = 0;
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(width, height);
if (x - width < 0) {
leftMargin = 0;
} else {
leftMargin = x - width + 40;
}
if (y >= 400 && y <= 480) {
topMargin = 160;
}
params.leftMargin = leftMargin;
params.topMargin = topMargin;
//params.setMargins(leftMargin, topMargin, 0, 0); //this didnt work either
infoLayout.setLayoutParams(params);
TextView titleView = (TextView) view.findViewById(R.id.titleCard);
titleView.setText(title);
return view;
}
Ok I was able to fix this by wrapping my infoLayout in another RelativeLayout, and now it works perfectly

How to add space between tab buttons in Android?

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();

Categories

Resources