How to set ViewPager with a ChipGroup android? - android

I have a ChipGroup with 5 chips in it. And I have a view pager with 5 pages in it. For the chip I select, the corresponding page(fragment) should be loaded. How to link the ViewPager and the ChipGroup in android?

set app:singleSelection="true"to your Chip Group XML refer to this
and set ViewPager like this
private void setViewPager() {
mPagerAdapter = new PagerAdapter(getSupportFragmentManager());
if (mViewPagerGetStarted != null) {
mViewPagerGetStarted.setAdapter(mPagerAdapter);
mViewPagerGetStarted.addOnPageChangeListener(this);
mViewPagerGetStarted.setOffscreenPageLimit(4);
mTabLayoutGetStarted.setupWithViewPager(mViewPagerGetStarted);
}
ArrayList<String> categoryList = new ArrayList<>();
int numberOfFrag = mPagerAdapter.getCount();
for (int i = 0; i < numberOfFrag; i++) {
categoryList.add(mPagerAdapter.getPageTitle(i).toString());
}
addChipsToChipGroup(categoryList);
}
Then add chips dynamically to your chip group using addChipsToChipGroup(categoryList);
private void addChipsToChipGroup(List<String> items) {
if (items.size() >= 1) {
for (int i = 0; i < items.size(); i++) {
Chip chip = new Chip(mContext);
chip.setId(i);
ChipDrawable chipDrawable = ChipDrawable.createFromAttributes(this,
null,
0,
R.style.ChipTextStyle);
chip.setCloseIconTint(Utils.ColorStateListFromIntColor(mColorPrimary));
chip.setText(items.get(i));
chip.setTextColor(mColorPrimary);
chip.setChipDrawable(chipDrawable);
chip.setChipBackgroundColor(Utils.ColorStateListFromIntColor(mWhiteColor));
chip.setChipStrokeColor(Utils.ColorStateListFromIntColor(mColorPrimary));
chip.setChipStrokeWidth(2f);
mChipGroup.addView(chip);
}
}
}
And finally set on checked changed listener on your chipgroup
mChipGroup.setOnCheckedChangeListener((group, checkedId) ->
mViewPagerGetStarted.setCurrentItem(checkedId,true));
style.xml :
<style name="ChipTextStyle" parent="Widget.MaterialComponents.Chip.Choice">
<item name="android:textSize">13sp</item>
<item name="android:textColor">#color/colorPrimary</item>
<item name="android:padding">5dp</item>
<item name="checkedIconEnabled">false</item>
<item name="checkedIcon">#null</item>
<item name="closeIconTint">#color/colorPrimary</item>
</style>

Related

How to change date order (from default to day/month/year) in Xamarin.Forms Android spinner?

I have replaced the default style of the data picker with the spinner one but now I need to change the date format (of the spinner not of the "result") to be the same in all cultures (dd/MM/yyyy).
I have tried to change the Format, but it's the format of the placeholder...
I'm sure that there is a way to change it in styles.xml but I don't know how to do it.
In styles.xml I have:
<item name="android:dialogTheme">#style/MyDialogTheme</item>
<item name="android:datePickerStyle">#style/MyDatePicker</item>
<style name="MyDialogTheme" parent="android:Theme.Material.Light.Dialog">
<item name="android:datePickerStyle">#style/MyDatePicker</item>
<item name="android:datePickerMode">spinner</item>
<item name="android:calendarViewShown">false</item>
<item name="android:spinnersShown">true</item>
</style>
<style name="MyDatePicker" parent="android:Widget.Material.Light.DatePicker">
<item name="android:datePickerMode">spinner</item>
<item name="android:calendarViewShown">false</item>
<item name="android:spinnersShown">true</item>
</style>
There is a way to change it here or in the custom renderer?
I had the same problem, I found this answer useful but it's for native android, I had to do some changes for Xamarin.Forms Android, create a custom renderer and add these lines:
protected override DatePickerDialog CreateDatePickerDialog(int year, int month, int day)
{
var dialog = base.CreateDatePickerDialog(year, month, day);
dialog.Show();
OrderDate(dialog, new char[] { 'd', 'm', 'y' });
return dialog;
}
private void OrderDate(DatePickerDialog dialog, char[] ymdOrder)
{
if (!dialog.IsShowing)
{
return;
}
int idYear = Resources.GetIdentifier("year", "id", "android");
int idMonth = Resources.GetIdentifier("month", "id", "android");
int idDay = Resources.GetIdentifier("day", "id", "android");
int idLayout = Resources.GetIdentifier("pickers", "id", "android");
NumberPicker spinnerYear = (NumberPicker)dialog.FindViewById(idYear);
NumberPicker spinnerMonth = (NumberPicker)dialog.FindViewById(idMonth);
NumberPicker spinnerDay = (NumberPicker)dialog.FindViewById(idDay);
LinearLayout layout = (LinearLayout)dialog.FindViewById(idLayout);
layout.RemoveAllViews();
for (int i = 0; i < SPINNER_COUNT; i++)
{
switch (ymdOrder[i])
{
case 'y':
layout.AddView(spinnerYear);
setImeOptions(spinnerYear, i);
break;
case 'm':
layout.AddView(spinnerMonth);
setImeOptions(spinnerMonth, i);
break;
case 'd':
layout.AddView(spinnerDay);
setImeOptions(spinnerDay, i);
break;
}
}
}
private void setImeOptions(NumberPicker spinner, int spinnerIndex)
{
ImeAction imeOptions;
if (spinnerIndex < SPINNER_COUNT - 1)
{
imeOptions = inputMethos.ImeAction.Next;
}
else
{
imeOptions = inputMethos.ImeAction.Done;
}
int idPickerInput = Resources.GetIdentifier("numberpicker_input", "id", "android");
TextView input = (TextView)spinner.FindViewById(idPickerInput);
input.SetImeActionLabel("",imeOptions);
}
The DatePicker (Spinner) on Android defaults to the chosen settings on the User's phone. It is generally advised not to override native behavior.
You can however, override this behavior by creating a custom renderer to use a Custom DatePicker by following the steps shown here: https://stackoverflow.com/a/7208968/11104068

changing the color of number picker items [duplicate]

I've looked at most all of the threads on this and none provided an answer that works. Styling the NumberPicker does not work (as per this thread: NumberPicker textColour)
Setting the style attribute on the numberPicker to a style that has a color item does not have any effect either. Nor does setting the textColor attribute on the numberPicker XML do anything.
Closest I've got to this is using the numberPicker to cast its getChildAt() to an EditText and then do setColor() on that EditText, but that only changes the color of the child once upon initialization and then every time it is selected from thereon; not what I am looking for either.
Any help? Thanks
The solution I tried and worked for me is:
In styles.xml add:
<style name="AppTheme.Picker" parent="Theme.AppCompat.Light.NoActionBar" >
<item name="android:textColorPrimary">#android:color/black</item>
</style>
Then use it like this inside your layout:
<NumberPicker
android:id="#+id/dialogPicker"
android:theme="#style/AppTheme.Picker"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp" />
This code should solve your problem. The problem you are experiencing is because during the construction of NumberPicker it captures the EditText textColor and assigns to to a paint so it can draw the numbers above and below the edit text with the same color.
import java.lang.reflect.Field;
public static void setNumberPickerTextColor(NumberPicker numberPicker, int color)
{
try{
Field selectorWheelPaintField = numberPicker.getClass()
.getDeclaredField("mSelectorWheelPaint");
selectorWheelPaintField.setAccessible(true);
((Paint)selectorWheelPaintField.get(numberPicker)).setColor(color);
}
catch(NoSuchFieldException e){
Log.w("setNumberPickerTextColor", e);
}
catch(IllegalAccessException e){
Log.w("setNumberPickerTextColor", e);
}
catch(IllegalArgumentException e){
Log.w("setNumberPickerTextColor", e);
}
final int count = numberPicker.getChildCount();
for(int i = 0; i < count; i++){
View child = numberPicker.getChildAt(i);
if(child instanceof EditText)
((EditText)child).setTextColor(color);
}
numberPicker.invalidate();
}
Not sure why you would need to dive into Java Reflection API for this. Its a simple styling matter. The attribute that you need to override is: textColorPrimary.
<style name="AppTheme" parent="#android:style/Theme.Holo.Light">
....
<item name="android:textColorPrimary">#ff0000</item>
</style>
If you're using the TimePicker inside a Dialog, override android:textColorPrimary in the dialog's theme.
That's about it.
Additional info:
Here's an insightful comment by Yoann Hercouet:
This solution does not change only the color on the NumberPicker, it
is a global change that will impact A LOT of components
This is correct, but it overlooks the possibilities I am hinting at. Moreover, global implies app-wide impact. That can be limited to activity-scope by applying this theme only to activities containing the NumberPicker. But, I agree, this may still be too corrosive.
The idea here is to somehow inject textColorPrimary=INTENDED_COLOR into the theme that will be seen by NumberPicker. There are multiple ways to achieve this. Here's one way:
Define a bare-bone style in res/values/styles.xml:
<style name="NumberPickerTextColorStyle">
<item name="android:textColorPrimary">#color/intended_color</item>
</style>
Now, create a custom NumberPicker:
public class ThemedNumberPicker extends NumberPicker {
public ThemedNumberPicker(Context context) {
this(context, null);
}
public ThemedNumberPicker(Context context, AttributeSet attrs) {
// wrap the current context in the style we defined before
super(new ContextThemeWrapper(context, R.style.NumberPickerTextColorStyle), attrs);
}
}
Finally, use ThemedNumberPicker in your layout(s):
<package.name.ThemedNumberPicker
android:id="#+id/numberPicker"
....
....
.... />
We have successfully contained the impact that textColorPrimary=INTENDED_COLOR has on our app.
This is of course just one option. For example, if you were inflating a layout containing a NumberPicker, you could use:
// In this case, the layout contains <NumberPicker... />, not <ThemedNumberPicker... />
LayoutInflater.from(new ContextThemeWrapper(context, R.style.NumberPickerTextColorStyle))
.inflate(R.layout.number_picker_layout, ...);
Here is a Xamarin Snippet from the answer above with TextSize and TextStyle Bold
public static bool SetNumberPickerTextColorAndSize(NumberPicker numberPicker, Color color, ComplexUnitType complexUnitType, float textSize, TypefaceStyle style)
{
int count = numberPicker.ChildCount;
for (int i = 0; i < count; i++)
{
View child = numberPicker.GetChildAt(i);
if (child.GetType() == typeof(EditText))
{
try
{
Field selectorWheelPaintField = numberPicker.Class
.GetDeclaredField("mSelectorWheelPaint");
selectorWheelPaintField.Accessible = true;
EditText editText = (EditText) child;
editText.SetTextSize(complexUnitType, textSize);
editText.SetTypeface(editText.Typeface, style);
editText.SetTextColor(color);
Paint paint = (Paint) selectorWheelPaintField.Get(numberPicker);
paint.TextSize = TypedValue.ApplyDimension(complexUnitType, textSize, numberPicker.Resources.DisplayMetrics);
paint.Color = color;
paint.SetTypeface(editText.Typeface);
numberPicker.Invalidate();
return true;
}
catch (NoSuchFieldException e)
{
Log.Warn("setNumberPickerTextColor", e);
}
catch (IllegalAccessException e)
{
Log.Warn("setNumberPickerTextColor", e);
}
catch (IllegalArgumentException e)
{
Log.Warn("setNumberPickerTextColor", e);
}
}
}
return false;
}
For me setting android:textColorPrimary in my theme did nothing, looking at the source code for the NumberPicker it decides the text color from the EditText input thus one need to set the android:editTextColor instead.
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:editTextColor">#color/dark_gray</item>
</style>
Instead of changing every text color to the color you want, better just changing all editText color. NumberPicker actually has a child EditText that display the numbers.
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
<!-- Change edit color here. -->
<item name="android:editTextColor">#000000</item>
</style>
This worked for me. And although I have white text in the buttons, they havent changed.
Based on reflection reject on Android SDK >= 29 better to modify Simon's answer:
public void setNumberPickerTextColor(NumberPicker numberPicker, int color){
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
final int count = numberPicker.getChildCount();
for (int i = 0; i < count; i++) {
View child = numberPicker.getChildAt(i);
if (child instanceof EditText) {
try {
((EditText) child).setTextColor(color);
numberPicker.invalidate();
Field selectorWheelPaintField = numberPicker.getClass().getDeclaredField("mSelectorWheelPaint");
boolean accessible = selectorWheelPaintField.isAccessible();
selectorWheelPaintField.setAccessible(true);
((Paint) selectorWheelPaintField.get(numberPicker)).setColor(color);
selectorWheelPaintField.setAccessible(accessible);
numberPicker.invalidate();
Field selectionDividerField = numberPicker.getClass().getDeclaredField("mSelectionDivider");
accessible = selectionDividerField.isAccessible();
selectionDividerField.setAccessible(true);
selectionDividerField.set(numberPicker, null);
selectionDividerField.setAccessible(accessible);
numberPicker.invalidate();
} catch (Exception exception) {
Logger.exc(exception);
}
}
}
} else {
numberPicker.setTextColor(color);
}
}
In SDK >= 29 NumberPicker have .setTextColor() method.
I took the solution of #Andreas Merz and updated his code. The way things were assigned and the functions signatures/calls he used were not found. I am using min API 19. Here is the code that worked for me.
/**
* Based on https://stackoverflow.com/a/26657169/2313889
* #param picker
* #param color
* #param unit
* #param textSize
* #param typeface
* #return
*/
private void formatNumberPickerText(NumberPicker picker, int color,
int unit, float textSize,
Typeface typeface) {
int count = picker.getChildCount();
for (int i = 0; i < count; i++) {
View child = picker.getChildAt(i);
if (child instanceof EditText) {
try {
Class clazz = picker.getClass();
Field field = clazz.getDeclaredField("mSelectorWheelPaint");
field.setAccessible(true);
EditText editText = (EditText) child;
editText.setTextSize(unit, textSize);
editText.setTypeface(typeface);
editText.setTextColor(color);
Paint paint = (Paint) field.get(picker);
paint.setTextSize(TypedValue.applyDimension(
unit, textSize, getResources().getDisplayMetrics()
));
paint.setColor(color);
paint.setTypeface(typeface);
picker.invalidate();
return;
} catch (IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace();
}
}
}
}
The accepted answer is overly complicated. A much simpler approach that worked for me was to override the: textColorPrimary attribute of the theme I was using.
<style name="Theme.MyTheme" parent="#android:style/Theme.Holo.NoActionBar.Fullscreen" >
<item name="android:textColorPrimary">#000000</item>
</style>
It did the job quite well!
For Kotlin users, use this extension function ( Based on #Tapa Save answer ).
fun NumberPicker.changeTextColor(color: Int) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
val count: Int = childCount
for (i in 0 until count) {
val child: View = getChildAt(i)
if (child is EditText) {
try {
child.setTextColor(color)
invalidate()
val selectorWheelPaintField: Field = this.javaClass.getDeclaredField("mSelectorWheelPaint")
var accessible: Boolean = selectorWheelPaintField.isAccessible
selectorWheelPaintField.isAccessible = true
(selectorWheelPaintField.get(this) as Paint).color = color
selectorWheelPaintField.isAccessible = accessible
invalidate()
val selectionDividerField: Field = this.javaClass.getDeclaredField("mSelectionDivider")
accessible = selectionDividerField.isAccessible()
selectionDividerField.isAccessible = true
selectionDividerField.set(this, null)
selectionDividerField.isAccessible = accessible
invalidate()
} catch (ignore: Exception) { }
}
}
} else {
textColor = color
}
}
It's easy with my NumberPicker library.
<com.github.tomeees.scrollpicker.ScrollPicker
...
app:textColor="..."
/>

colorControlNormal not working on AppCompat.Dialog for lollipop devices

I have created a custom datepicker dialog which extends a
Theme.AppCompat.Light.Dialog.Alert
I have created a style for this both in values/styles.xml and v21/styles.xml...
The code for the style is I created ::
<style name="MyDatePickerDialogTheme" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="android:textColorPrimary">#color/accounts_darkgray_text</item>
<item name="colorControlNormal">#color/graph_rod_red</item>
<item name="android:windowBackground">#color/transparent</item>
</style>
Using colorControlNormal in v21 and above I am able to change the blue divider colors, but in lollipop and pre-lollipop devices, whatever I mention in the colorControlNormal , it does not seem to accept at all.
How can I change the divider colors, for 21 and < 21 android devices??
I was able to resolve the problem and thought would share the answer if this helps someone else.
I used the reflection technique to get hold of the "dividers" and change the color of it from code-behind.
LinearLayout llFirst = (LinearLayout) datePicker.getChildAt(0);
LinearLayout llSecond = (LinearLayout) llFirst.getChildAt(0);
for (int i = 0; i < llSecond.getChildCount(); i++) {
// Numberpickers in llSecond
NumberPicker picker = (NumberPicker) llSecond.getChildAt(i);
Field[] pickerFields = NumberPicker.class.getDeclaredFields();
for (Field pf : pickerFields) {
if (pf.getName().equals("mSelectionDivider")) {
pf.setAccessible(true);
try {
ColorDrawable colorDrawable = new ColorDrawable(mActivity.getResources()
.getColor(R.color.date_picker_divider));
pf.set(picker,colorDrawable);
} catch (IllegalArgumentException | Resources.NotFoundException
| IllegalAccessException e) {
e.printStackTrace();
}
break;
}
}
}

Using custom style for the crouton library

I am using Crouton lib (https://github.com/keyboardsurfer/Crouton).
now , I would like to use custom style instead of default styles. how can I do ?
Style.ALERT is a default style.
Crouton.showText(this, "test", Style.ALERT);
I want to use this style :
#styles :
<style name="CroutonGreen">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:background">#color/color_pressed_buy_an_item</item>
<item name="android:gravity">center</item>
</style>
It says here:
In general you can modify
display duration
dimension settings
options for the text to display
custom Views
appearance & disappearance Animation
displayed Image
Since Style is the general entry point for tweaking Croutons, go and see for yourself what can be done with it.
You can try modifying that class with the following code to change background color:
static {
ALERT = new Builder()
.setBackgroundColorValue(holoRedLight)
.build();
CONFIRM = new Builder()
.setBackgroundColorValue(holoGreenLight)
.build();
INFO = new Builder()
.setBackgroundColorValue(holoBlueLight)
.build();
CUSTOM = new Builder()
.setBackgroundColorValue(myColor)
.build();
}
I haven't test it, but i think it should work.
Then below on that class there is the following code:
public Builder() {
configuration = Configuration.DEFAULT;
paddingInPixels = 10;
backgroundColorResourceId = android.R.color.holo_blue_light;
backgroundDrawableResourceId = 0;
backgroundColorValue = NOT_SET;
isTileEnabled = false;
textColorResourceId = android.R.color.white;
textColorValue = NOT_SET;
heightInPixels = LayoutParams.WRAP_CONTENT;
widthInPixels = LayoutParams.MATCH_PARENT;
gravity = Gravity.CENTER;
imageDrawable = null;
imageResId = 0;
imageScaleType = ImageView.ScaleType.FIT_XY;
fontName = null;
fontNameResId = 0;
}
heightInPixels, widthInPixels, gravity are already set correctly according to your style.
Finally, in your app, call your crouton with Style.CUSTOM.
Crouton.showText(this, "test", Style.CUSTOM);

How to get name of arrays

I have this array.xml
<resources>
<string-array name="Abarth">
<item name="id">1</item><item name="title">500</item>
<item name="id">2</item><item name="title">Grande Punto</item>
<item name="id">3</item><item name="title">Punto Evo</item>
<item name="id">4</item><item name="title">500c</item>
<item name="id">5</item><item name="title">695</item>
<item name="id">6</item><item name="title">Punto</item>
</string-array>
<string-array name="Alfa_Romeo">
<item name="id">1</item><item name="title">155</item>
<item name="id">2</item><item name="title">156</item>
<item name="id">3</item><item name="title">159</item>
<item name="id">4</item><item name="title">164</item>
<item name="id">5</item><item name="title">145</item>
<item name="id">6</item><item name="title">147</item>
<item name="id">7</item><item name="title">146</item>
<item name="id">8</item><item name="title">Gtv</item>
<item name="id">9</item><item name="title">Spider</item>
<item name="id">10</item><item name="title">166</item>
<item name="id">11</item><item name="title">Gt</item>
<item name="id">12</item><item name="title">Crosswagon</item>
<item name="id">13</item><item name="title">Brera</item>
<item name="id">14</item><item name="title">90</item>
<item name="id">15</item><item name="title">75</item>
<item name="id">16</item><item name="title">33</item>
<item name="id">17</item><item name="title">Giulietta</item>
<item name="id">18</item><item name="title">Sprint</item>
<item name="id">19</item><item name="title">Mito</item>
</string-array>
<array name="marcas">
<item>#array/Abarth</item>
<item>#array/Alfa_Romeo</item>
</array>
</resources>
I want to get the content of the array marcas and the name of the subarrays, like "Abarth" or "Alfa_Romeo".
How can I do this? In other post I have read the next code, but it is for obtain the entire array, not only a part of the array.
Resources res = getResources();
TypedArray ta = res.obtainTypedArray(R.array.marcas);
int n = ta.length();
String[][] car = new String[n][];
for (int i = 0; i < n; ++i) {
int id = ta.getResourceId(i, 0);
if (id > 0) {
car[i] = res.getStringArray(id);
} else {
// Error en el XML
}
}
Thank you.
I want to get the content of the array marcas and the name of the
subarrays, like "Abarth" or "Alfa_Romeo".
I don't know if i correctly understood your question but to obtain name of arrays you can use this:
TypedArray parent = getResources().obtainTypedArray(R.array.marcas);
List<String> childs = new ArrayList<String>();
for (int i = 0; i < parent.length(); i++) {
int id = parent.getResourceId(i, 0);
if (id > 0) {
childs.add(getResources().getResourceEntryName(id));
}
}
parent.recycle();
Output:
Abarth
Alfa_Romeo
You have done everything well, To get the TypedArray resource name you need to use getResourceEntryName. Add the following code to get the resourceEntryName, to get what you looking for.
getResources().getResourceEntryName(id);
This will give you the output "Abarth" and "Alfa_Romeo".

Categories

Resources