Creating Xamarin button with gradient colour and curved edges - xamarin.android

I have a xamarin Android button with curved edges (Border radius). There I want to make colour as gradient.
If I try to make it by painting the canvas (as a custom renderer) it will disappear curved edges as follows by overriding the ButtonRenderer's DispatchDraw function.
protected override void DispatchDraw(Canvas canvas)
{
var gradient = new Android.Graphics.LinearGradient(0, 0, Width, Height,
this.StartColor.ToAndroid(),
this.EndColor.ToAndroid(),
Android.Graphics.Shader.TileMode.Clamp);
var paint = new Android.Graphics.Paint()
{
Dither = true,
};
paint.SetShader(gradient);
canvas.DrawPaint(paint);
base.DispatchDraw(canvas);
}
With the above code it button will disappear the curved edges. Before this code I was settings the color with the background property. With that property I can see the curved edges but not with the above code.
So my assumption is if I can set the gradient color for the background color property of the button this will work, unfortunately I couldn't find a way to do it.
Could someone help me to achieve this?

I find XML to be more understandable so, i would do something like this:
Gradient.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<!--make a gradient background-->
<gradient
android:type="linear"
android:startColor="#556B2F"
android:endColor="#BDB76B"
android:centerColor="#ffffff"
android:angle="90"
android:gradientRadius="90"
/>
<!--apply a border around button-->
<stroke android:color="#006400" android:width="2dp" />
<!-- make the button corners rounded-->
<corners android:radius="25dp"/>
</shape>
</item>
</selector>
Use it like this in your button xml :
android:background="#drawable/Gradient"
Or in C# code like this:
_button.SetBackgroundResource(Resource.Drawable.Gradient);

Related

Set style containing android:textColor and android:background programatically? (Xamarin.Android)

I have the following styles in styles.xml :
<style name="tabSelected">
<item name="android:textColor">#FFFFFF</item>
<item name="android:background">#0000ff</item>
</style>
<style name="tabUnselected">
<item name="android:textColor">#0000ff</item>
<item name="android:background">#FFFFFF</item>
</style>
And I have two TextViews in my activity. When I click the first TextView I want to add the style tabSelected to it and to remove tabUnselected from it and when I click the second TextView I want to add the style tabSelected to it and to remove tabUnselected from it:
I tried the following:
exhibitionAreaTextView.Click += delegate
{
exhibitionAreaTextView.SetTextAppearance(Resource.Style.tabSelected);
multipurposeRoomTextView.SetTextAppearance(Resource.Style.tabUnselected);
};
multipurposeRoomTextView.Click += delegate
{
multipurposeRoomTextView.SetTextAppearance(Resource.Style.tabSelected);
exhibitionAreaTextView.SetTextAppearance(Resource.Style.tabUnselected);
};
But it changed only the textColor of the TextViews. I've seen another solution:
ContextThemeWrapper newContext = new ContextThemeWrapper(baseContext, R.style.MyStyle);
textView= new TextView(newContext);
But it is making a new instance of the TextViews and I don't know if its click event will work after that and more it is 2 lines solution, if it's going to be 2 lines, I better put:
multipurposeRoomTextView.SetTextColor(#ffffff);
multipurposeRoomTextView.SetBackgroundColor(#0000ff);
It will be more readable. Is it a way to set the style with one property programatically, something like that multipurposeRoomTextView.SetStyle(MyStyle)?

android - i want to change the position of request focus error icon so that it does not shows over the toggle icon for password

here is my edit text xml code
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:passwordToggleEnabled="true"
android:theme="#style/TextLabel1">
<EditText
android:id="#+id/editText4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textCursorDrawable="#drawable/color_cursor"/>
</android.support.design.widget.TextInputLayout>
my class code for edit text
if (PassWordSignUp.length()<6) {
PassWordSignUp.setError("Your password is less than 6 characters!");
PassWordSignUp.requestFocus();
}
I was looking for an answer as well, and I got it. You can set your own drawable (which has margin) to be there instead of the red exclamation point icon.
How to make that customised icon with margin.
First, you create a new Vector Asset with the icon you would like.
Drawable -> new -> Vector Asset -> choose your icon -> Next -> Finish
Now create completely new drawable which will access the vector icon.
Plus you will now add the margin.
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:right="32dp" //Adding the margin
android:drawable="#drawable/the_name_of_your_vector_icon"/> //Accessing the vector icon
</layer-list>
You have your XML resources. Now just display your newly (with margin) created icon instead of the normal one.
Drawable customisedErrorIcon =
getResources().getDrawable(R.drawable.your_new_error_icon);
if (customisedErrorIcon != null) {
customisedErrorIcon.setBounds(0, 0,
customisedErrorIcon.getIntrinsicWidth(),
customisedErrorIcon.getIntrinsicHeight());
}
yourEditText.setError("Error message", customisedErrorIcon);
This is how you set a customised drawable to be an error icon. And this is the result.

Xamarin - Button with text and image in absolute layout results in mis-aligned elements

I am trying to create a button in a Xamarin Forms cross-platform app (iOS and Android), where the button has both text and an image. The XAML is pretty straightforward:
<AbsoluteLayout ...>
<Labels and backgrounds and such>
<Button x:Name="HomeButton2" TranslationX="6" TranslationY="100"
BackgroundColor="#efeff4" TextColor="#4a4a4a"
WidthRequest="58" HeightRequest="76"
ContentLayout="Top,5"
Image="TaskBar_Assets_HomeButtonIcon.png" Text="Home"
Clicked="HomeButton_Clicked" />
</AbsoluteLayout>
but what I get on the iPad is a button where both the image and the text are strangely pushed over to the side:
(the source image "TaskBar_Assets_HomeButtonIcon.png" is 47 x 44 so it should fit fine in the overall button area)
The only way I can find to make this look better, is to make a custom control based on Button, and then I can see that several of the properties of the underlying UIButton seem wonky:
The Control.ImageView.Frame is all zeroes:
Control.ImageView = <UIImageView: 0x12df52940; frame = (0 0; 0 0);
clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO;
layer = <CALayer: 0x173623180>>
The Control.ImageEdgeInsets and .TitleEdgeInsets look odd (the right + left seem like they leave no space for the image or text):
Control.ImageEdgeInsets = {-8.9501953125, 20.33935546875, 8.9501953125, -20.33935546875}
Control.TitleEdgeInsets = {22, -23.5, -22, 23.5}
What I'm doing, is adjusting the Control.ImageEdgeInsets so that Control.ImageEdgeInsets.Left is equal to the half of the (button width minus the image width) and setting Control.ImageEdgeInsets.Right to zero (for no particular reason except that it works)
and then figuring out what to set Control.TitleEdgeInsets was done with trial & error, I ended up with values related to the width of the "Home" text (41 pixels):
Control.ImageEdgeInsets updated to {-8.9501953125, 5.5, 8.9501953125, 0}
Control.TitleEdgeInsets updated to {22, -50, -22, -9}
That results in a reasonable button look:
although it looks like I need to do more trial & error to get the text "Home" actually centered.
But why do I need to go through all this? Why doesn't the button just display text & image correctly in the first place?
And if I do have to go through all this, why are the values for Left & Right for ImageEdgeInsets and TitleEdgeInsets so different?
Most of the articles I have read about images on buttons suggest constructing your own using an Image and a Label in a grid using a gesture recognizer to handle the tap.
You could also try a button and an image in a grid.
Use Margin to adjust placement.
I try and stay clear of absolute layout.
Here's the ButtonRenderer source code from Xamarin.Froms.If you set the ContentLayout to Top, the below codes will be run:
void ComputeEdgeInsets(UIButton button, Button.ButtonContentLayout layout)
{
...
var horizontalImageOffset = labelWidth / 2;
var horizontalTitleOffset = imageWidth / 2;
...
button.ImageEdgeInsets = new UIEdgeInsets(-imageVertOffset, horizontalImageOffset, imageVertOffset, -horizontalImageOffset);
button.TitleEdgeInsets = new UIEdgeInsets(titleVertOffset, -horizontalTitleOffset, -titleVertOffset, horizontalTitleOffset);
}
As the codes show, the Left offset of image is horizontalImageOffset which is labelWidth / 2. The Left offset of title is horizontalTitleOffset which is imageWidth / 2.
So, when the text is wider, the left offset of image will be bigger. When the image is wider, the left offset of text will be bigger.
Edit:
In native iOS, the default layout is like the left image: Image is at left and Label is at right. In Xamarin for Top setting, Xamarin moves the Image up and right, moves the Label down and left to makes them like the right image. I paint this illustration, hope it clear.

YouTube Player not working with a Transparent Panel Menu Android

The YouTube Player will play videos no problem either without the transparent panel on the form or it will play them in full screen, the transparent panel has some images in it nothing special. If I take out the transparent panel, the YouTube Player works as desired, embedded in app. If I add the transparent panel to the form, this is when it will not play but in full screen. The video starts and then stops instantly. I assume it has something to do with the transparent panel but I can not understand what is happening. Any help or thoughts would be great. My java file does not change except for the initPopup would not be there. Shortened Java file version below.
XML Layout File Below:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mlayout"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<com.google.android.youtube.player.YouTubePlayerView
android:id="#+id/youtube_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/spnrPSA" >
</com.google.android.youtube.player.YouTubePlayerView>
</RelativeLayout>
<com.TransparentPanel
android:id="#+id/popup_window"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
android:gravity="left"
android:orientation="vertical"
android:padding="1px" >
<com.TransparentPanel>
</RelativeLayout>
JAVA File Below:
public final class PSA extends YouTubeFailureRecoveryActivity{
private Animation animShow, animHide;
private YouTubePlayer player;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.psa);
initPopup();
}
private void initPopup() {
final TransparentPanel popup = (TransparentPanel) findViewById(R.id.popup_window);
// Start out with the popup initially hidden.
popup.setVisibility(View.GONE);
if (PubVars.ScreenOrientation==0){
animShow = AnimationUtils.loadAnimation( this, R.anim.popup_show);
animHide = AnimationUtils.loadAnimation( this, R.anim.popup_hide);
}
if (PubVars.ScreenOrientation==1){
animShow = AnimationUtils.loadAnimation( this, R.anim.l_popup_show);
animHide = AnimationUtils.loadAnimation( this, R.anim.l_popup_hide);
}
//animShow = AnimationUtils.loadAnimation( this, R.anim.popup_show);
//animHide = AnimationUtils.loadAnimation( this, R.anim.popup_hide);
final ImageView showButton = (ImageView) findViewById(R.id.show_popup_button);
final ImageView hideButton = (ImageView) findViewById(R.id.hide_popup_button);
showButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
popup.setVisibility(View.VISIBLE);
popup.startAnimation( animShow );
showButton.setEnabled(false);
hideButton.setEnabled(true);
}});
hideButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
popup.startAnimation( animHide );
showButton.setEnabled(true);
hideButton.setEnabled(false);
popup.setVisibility(View.GONE);
}});
}
}
I must be missing something simple. Thanks in advance, I am fairly new to android.
Youtube Player View does not authorize overlays. Even if it's a transparent Layout(Relative, frame, ..).
The player stops the video and log into logcat some useful info. But this case is reported as "youtubeplayer is completely covered".
This api not permit anyone layer over this. "Layout is the problem"
I suggest you use the hierarchy View to see this on your layout.
I have many problems with it, because my layout stay over a little point over player.

Scrolling 2 lists with 1 scroller Flex 4

Been trying to scroll 2 lists with their native scrollers disabled with 1 scroller added to the right of them.
I tried setting the viewport of each List as the scroller and while that works it just instantiates the scroller to each of the Lists rather than use 1.
Essentially i'm trying to have them scroll vertically at the same time while dragging only 1 scrollbar thumb.
I thought this was an interesting question and did a little investigation. Here is what I came up with.
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
initialize="application1_initializeHandler(event)"
creationComplete="application1_creationCompleteHandler(event)">
<fx:Script>
<![CDATA[
import flashx.textLayout.container.ScrollPolicy;
import mx.collections.ArrayCollection;
import mx.events.FlexEvent;
[Bindable] private var dp:ArrayCollection = new ArrayCollection();
protected function application1_initializeHandler(event:FlexEvent):void
{
//Add some dummy content
for (var i:int=0; i<20; i++){
dp.addItem("Test Item " + i);
}
//Turn off vertical scrolling for the two lists
list1.scroller.setStyle("verticalScrollPolicy", ScrollPolicy.OFF);
list2.scroller.setStyle("verticalScrollPolicy", ScrollPolicy.OFF);
}
protected function vScroll_changeHandler(event:Event):void
{
//Set the maximum of the one scroll bar to equal the maximum value of the hidden scroll bar
vScroll.maximum = list1.scroller.verticalScrollBar.maximum;
//Set the scroll position of the two hidden scroll bars to the value of the visible bar
list1.scroller.verticalScrollBar.value = vScroll.value;
list2.scroller.verticalScrollBar.value = vScroll.value;
}
protected function application1_creationCompleteHandler(event:FlexEvent):void
{
//Initialize the maximum value to the value of the hidden scroll bar after data has been loaded
vScroll.maximum = list1.scroller.verticalScrollBar.maximum;
}
]]>
</fx:Script>
<s:HGroup>
<s:List id="list1" dataProvider="{dp}" height="200"/>
<s:List id="list2" dataProvider="{dp}" height="200"/>
<s:VScrollBar id="vScroll" height="200" change="vScroll_changeHandler(event)"/>
</s:HGroup>
</s:Application>

Resources