android-tv Changing text color and font of browse fragment rows header - android-tv

How to change text color and font of rows header in browse fragment?.
The text not in menu but the text that appears above the rows.

I am assuming you are using the provided android.support.v17.leanback.widget.RowHeaderPresenter as the presenter for the HeaderFragment in your BrowseFragment.
The RowHeaderPresenter inflates the layout from R.layout.lb_row_header which looks like this:
<android.support.v17.leanback.widget.RowHeaderView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/row_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="?rowHeaderStyle" />
As you can see, this uses a style attribute called rowHeaderStyle, which is normally pointing to #style/Widget.Leanback.Row.Header. You can override this by putting the following in your styles.xml:
<style name="MyCustomRowHeaderStyle" parent="Widget.Leanback.Row.Header">
<item name="android:textColor">#color/red</item>
</style>
<style name="MyCustomBrowseStyle" parent="Theme.Leanback.Browse">
<item name="rowHeaderStyle">#style/MyCustomRowHeaderStyle</item>
</style>
And then use MyCustomBrowseStyle for the Activity containing the BrowseFragment by declaring it in your AndroidManifest.xml.

In addition to David's answer.
rowHeaderStyle applies the style both to menu items in HeaderFragment and row titles in RowFragment (these two fragments compose your BrowseFragment).
If you want their styles (font colors in particular) to be different, you can override BrowseFragment::onCreateHeadersFragment() and apply specific theme at that point.
1) Add these styles to styles.xml:
<style name="AppTheme.Leanback.Browse.Row" parent="#style/Theme.Leanback.Browse">
<item name="rowHeaderStyle">#style/AppTheme.Leanback.Row</item>
</style>
<style name="AppTheme.Leanback.Browse.Header" parent="#style/AppTheme.Leanback.Browse.Row">
<item name="rowHeaderStyle">#style/AppTheme.Leanback.Header</item>
</style>
<style name="AppTheme.Leanback.Row" parent="Widget.Leanback.Row.Header">
<item name="android:textColor">#color/font_row</item>
</style>
<style name="AppTheme.Leanback.Header" parent="Widget.Leanback.Row.Header">
<item name="android:textColor">#color/font_header</item>
</style>
2) Apply AppTheme.Leanback.Browse.Row theme to your activity in manifest.
3) Apply AppTheme.Leanback.Browse.Header theme to headers in your BrowseFragment:
// Kotlin snippet
override fun onCreateHeadersFragment() : HeadersFragment {
class CustomHeadersFragment : HeadersFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return super.onCreateView(
inflater.cloneInContext(ContextThemeWrapper(inflater.context, R.style.AppTheme_Leanback_Browse_Header)),
container,
savedInstanceState
)
}
}
return CustomHeadersFragment()
}

The answer by david.mihola helps with the color, however I still had problems with setting a custom font globally. For everybody who stumbles upon this question and is puzzled about this as well, here is my solution:
Thanks to the awesome work done by chrisjenx (Calligraphy), you can easily set a global (custom) font.
Simply add Calligraphy to your gradle.build and add the following snippet to your Application.onCreate():
CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()
.setDefaultFontPath("fonts/MyCustomFont.ttf")
.setFontAttrId(R.attr.fontPath)
.build()
);
and in every Activity add the following:
#Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}
This has done the font-trick for me on every single TextView, without modifying layouts. The documentation of Calligraphy also offers some more possibilities. Check it out.
I hope this helps other people who find this question and are trying to set (custom) fonts globally.

Related

How do I programmatically change the color of the hamburger menu icon using hex values in xamarin forms?

I am working on a mvvm light xamarin forms application where i allow the user to create there own theme with in the application itself. As of right now, i have everything working as intended with the exception of the send button(image icon), add button (image icon), and hamburger menu icon.
The user selects a image/name, then the hex value from that color is applied to the control/font. But i have run into the issue when trying to programmatically set the hamburger menu color.I started with the android side of things.I can set the color once using styles.xml.
But this not sufficient for what i am trying to do. I haven't figure out how to get a reference to the toggledrawer to change the color without creating a new reference and supplying drawables.
I will also need to have the same action happen on iOS(changeable color hamburger menu). I don't want to supply images because the user will set the color based on a hex value...what is my best option? Is what i am trying to do even possible at this point?
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected ActionBarDrawerToggle drawerToggle;
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
Rg.Plugins.Popup.Popup.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
drawerToggle.getDrawerArrowDrawable().setColor(getResources().getColor(R.color.white));
}
}
i found this code here:
drawerToggle.getDrawerArrowDrawable().setColor(getResources().getColor(R.color.white));
It would be ideal, but i don't have a reference to drawerToggle...(the object is null)
i also tried to setting it using styles.xml as should below:
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<style name="MainTheme" parent="MainTheme.Base">
</style>
<!-- Base theme applied no matter what API -->
<style name="MainTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
<!--If you are using revision 22.1 please use just windowNoTitle. Without android:-->
<item name="windowNoTitle">true</item>
<!--We will be using the toolbar so no need to show ActionBar-->
<item name="windowActionBar">false</item>
<!-- Set theme colors from http://www.google.com/design/spec/style/color.html#color-color-palette -->
<!-- colorPrimary is used for the default action bar background -->
<item name="colorPrimary">#2196F3</item>
<!-- colorPrimaryDark is used for the status bar -->
<item name="colorPrimaryDark">#1976D2</item>
<!-- colorAccent is used as the default value for colorControlActivated
which is used to tint widgets -->
<item name="colorAccent">#FF4081</item>
<!-- You can also set colorControlNormal, colorControlActivated
colorControlHighlight and colorSwitchThumbNormal. -->
<item name="windowActionModeOverlay">true</item>
<item name="android:datePickerDialogTheme">#style/AppCompatDialogStyle</item>
<item name="drawerArrowStyle">#style/DrawerArrowStyle</item>
</style>
<style name="DrawerArrowStyle" parent="#style/Widget.AppCompat.DrawerArrowToggle">
<item name="spinBars">true</item>
<item name="color">#android:color/green</item>
</style>
<style name="AppCompatDialogStyle" parent="Theme.AppCompat.Light.Dialog">
<item name="colorAccent">#FF4081</item>
</style>
</resources>
This code does work to set it once, but i need it reset within the application by a button click. So this is not sufficient for the what i am trying to do.
add hamburger menu icon to drawable folder
Add code where you wish to change it.
var toolbar = FindViewById<AndroidToolbar>(Resource.Id.toolbar);
var view = (AppCompatImageButton)toolbar.GetChildAt(2);
// 1. actionmenuview (primary/secondary menu icons),
// 2. appcompattextview (title),
// 3. appcompatimagebutton (hamburger icon)
view.SetImageDrawable(d);
// view.SetImageDrawable(d);
In my case, I have menu Icons so I select GetChildAt(2) [the third item]

Why is my custom css snippet not working?

I created a custom css snippet for nth-of-type keyword in css. But it doesn't seem to work. All other snippets work perfectly.
<snippet>
<content><![CDATA[
nth-of-type(${1})
]]></content>
<!-- Optional: Set a tabTrigger to define how to trigger the snippet -->
<tabTrigger>noty</tabTrigger>
<!-- Optional: Set a scope to limit where the snippet will trigger -->
<scope>source.css</scope>
</snippet>
But when I enter the tab trigger and press tab it just puts a colon ahead. Also I have installed Emmet and I think it might be conflicting with something here.
Also I've saved the snippet in the correct directory.
As Philipp Sander says 'noty' is not an element. it's a content of the <tabTrigger>. CSS won't work for content.
You can use tag/an element name or you can use class/id property in an element, and use that class/id value to select that element.
Id property :
<tabTrigger id="noty_element">noty</tabTrigger>
styles for Id:
#noty_element {
//your styles
}
class property :
<tabTrigger class="noty_element">noty</tabTrigger>
styles for Id:
.noty_element {
//your styles
}

css file rule apply to this class

I have this label within website:
<nav class="exodus-nav-left-right exodus-content-block exodus-content-block-compact exodus-clearfix">
for example want to add the rule to be met in this condition is:
visibility: hidden;
as I have to put in the CSS file?
Thank you for your help
First of all it seems that its not a "Label"
and if you want to hide element, you can do so by using the display property.
.exodus-content-block {
display:none;
}
If there are other elements with same class then you can narrow down your rule by using the whole class attribute value as below..
.exodus-nav-left-right.exodus-content-block.exodus-content-block-compact.exodus-clearfix {
display:none;
}
you can use the inline styling.
example
<nav class="exodus-nav-left-right exodus-content-block exodus-content-block-compact exodus-clearfix" style="visibility:hidden">
Or you can write as css class and add in the code
<style>.hiddenvis{ visibility:hidden}</style>
<nav class="exodus-nav-left-right exodus-content-block exodus-content-block-compact exodus-clearfix hiddenvis "/>
but you got to make sure other classes used here do not override your hidden functionality

Dynamically change element styles via custom properties?

For example, you can change the ink colour in paper-tabs by changing --paper-tab-ink: var(--accent-color);. Is it possible to change the value of the CSS custom properties dynamically similar to how you can toggle a class or change the style in JS?
There are different ways to do this, but a simple answer is to use the Polymer.updateStyles() method after making your class changes.
For example, let's say your styles are:
<style>
.yellow x-example {
--light-primary-color: #fdd85f;
}
.red x-example {
--light-primary-color: red;
}
</style>
and you want to make the component use the styles in the .red class. You simply add it as you normally would in javascript, then be sure to also use this function to actually update it on the page.
<div class="yellow" onclick="this.className='red'; Polymer.updateStyles()">
<x-example></x-example>
</div>
Yes, first get the object of your custom element. Then get the customStyle object. Add a style to that object. And then run element.updateStyles();
t.clickListener= function(e) {
var t = Polymer.dom(e).localTarget; //retarget if needed
t.customStyle['--the-color-etc'] = 'pink';
t.updateStyles(); // mandatory for the CSS variables shim
};
See the docs

Add Content To Dialog Box DOJO

writing an app for opensocial brings up the following problem:
I create a dialog box (css is tundra)
myDialog = new dijit.Dialog({
title: "My Dialog",
content: "test content",
style: "width: 300px"
});
How can I change the properties "overflow" and /or "height" of the
"dijitDialogPaneContent"
contained in myDialog after creating this object?
Thank you
Subin
There are several approaches you can use, depending on how generic the solution should be.
Apply to all dialogs
If you want to apply the same style to all dialogs, you can "extend" a theme, for example, normally you would use the tundra theme like this:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="location/to/tundra.css" />
</head>
<body class="tundra">
<!-- Your content comes here -->
</body>
</html>
If you're going to apply it to all dialogs, you could do the following:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="location/to/tundra.css" />
<link rel="stylesheet" href="custom/style.css" />
</head>
<body class="tundra custom">
<!-- Your content comes here -->
</body>
</html>
And then write a custom stylesheet like this:
.custom .dijitDialogPaneContent {
overflow: hidden; /** Custom styles */
}
This will guarantee that it will override the general Tundra style for all dialogs. If you don't use a class like .custom, you cannot override the Tundra stylesheet because .tundra .dijitDialogPaneContent will be more specific (which means it has a higher priority).
Of course, you could write .tundra .dijitDialogPaneContent in your custom stylesheet as well.
Apply to a single dialog through stylesheet
If you want to apply it to a single dialog, then give an ID to the dialog, for example:
myDialog = new dijit.Dialog({
title: "My Dialog",
content: "test content",
style: "width: 300px",
id: "myDialogId"
});
Then you could write a stylesheet like this:
#myDialogId .dijitDialogPaneContent {
overflow: hidden; /** Custom styles */
}
Apply to a single dialog (using JavaScript)
Seperate stylesheets may improve readability because you seperate logic from design. If you don't need the seperate stylesheet you could do something like this:
require([ "dojo/query", "dojo/NodeList-dom" ], function(query) {
// Your code
query(".dijitDialogPaneContent", myDialog.domNode).style("overflow", "hidden");
});
This will use the domNode property of the dialog to query the content pane and then apply the style.
Apply to multiple dialogs
If you want to apply the same style to multiple dialogs (but not all dialogs), then your best approach would be to create a custom dialog by extending the default dialog. Considering the length of my answer atm I'm not going to explain that into detail, but I recommend reading guides about writing your own widget.

Resources