SlidingPanel for Xamarin.Android - user-interface

I'm creating a slide view with 2 tabs, but I don't know why the part of tabs are "transparent", they take the background color and not the AppBar color..anyone knows why?
MainActivity:
using Android.App;
using Android.Widget;
using Android.OS;
using Android.Support.Design.Widget;
using Android.Support.V4.View;
namespace M_v1
{
[Activity(Label = "M_v1", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
SetContentView(Resource.Layout.Main);
TabLayout tabLayout = (TabLayout)FindViewById(Resource.Id.tablayout_navigation);
ViewPager viewPager = (ViewPager)FindViewById(Resource.Id.pager);
SetupviewPager(viewPager);
tabLayout.SetupWithViewPager(viewPager);
}
private void SetupviewPager(ViewPager viewPager)
{
viewPager.OffscreenPageLimit = 2;
PageAdapter adapter = new PageAdapter(SupportFragmentManager);
adapter.AddFragment(new Fragment1(), "One");
adapter.AddFragment(new Fragment2(), "Two");
viewPager.Adapter = adapter;
}
}
}
Here the theme:
<style name = "AppTheme" parent = "Theme.AppCompat.Light.NoActionBar">
<item name = "windowActionBar">true</item>
<item name ="windowNoTitle">false</item>
<item name ="colorPrimary">#2B5C56</item>
<item name ="colorPrimaryDark">#000000</item>
<item name ="colorAccent">#FFEE58</item>
</style>

Having the problem that the new TabLayout uses the indicator colour from the value colorAccent, I decided to dig into the android.support.design.widget.TabLayout implementation, finding that there are no public methods to customize this. However, I found this style specification of the TabLayout:
<style name="Base.Widget.Design.TabLayout" parent="android:Widget">
<item name="tabMaxWidth">#dimen/tab_max_width</item>
<item name="tabIndicatorColor">?attr/colorAccent</item>
<item name="tabIndicatorHeight">2dp</item>
<item name="tabPaddingStart">12dp</item>
<item name="tabPaddingEnd">12dp</item>
<item name="tabBackground">?attr/selectableItemBackground</item>
<item name="tabTextAppearance">#style/TextAppearance.Design.Tab</item>
<item name="tabSelectedTextColor">?android:textColorPrimary</item>
Having this style specification, now we can customize the TabLayout like this:
<android.support.design.widget.TabLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#id/pages_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:tabIndicatorColor="#android:color/white"
app:tabIndicatorHeight="4dp"/>

Related

How to draw 1/3 circle on Xamarin forms?

I'm designing a layout as below with Xamarin Forms.
1) How do we draw such a layout?
and 2) How do we draw 1/3 circle?
Please help me!
Reference: Draw Circle in Xamarin form
If you just want to set the CornerRadius of bottom-left and bottom-right. You can use the Custom Renderer .
in Forms ,create a subclass of BoxView
public class MyBoxView:BoxView
{
}
in xaml
<StackLayout VerticalOptions="StartAndExpand" HorizontalOptions="CenterAndExpand">
<local:MyBoxView BackgroundColor = "Red" WidthRequest="800" HeightRequest="200" />
</StackLayout>
in iOS
using Foundation;
using UIKit;
using xxx;
using xxx.iOS;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using CoreGraphics;
using CoreAnimation;
[assembly:ExportRenderer(typeof(MyBoxView),typeof(MyViewRenderer))]
namespace xxx.iOS
{
public class MyViewRenderer : BoxRenderer
{
public override void LayoutSublayersOfLayer(CALayer layer)
{
base.LayoutSublayersOfLayer(layer);
var path = UIBezierPath.FromRoundedRect(this.Bounds, UIRectCorner.BottomRight | UIRectCorner.BottomLeft, new CGSize(1000, 1000)); //set CornerRadius here !!
var mask = new CAShapeLayer();
mask.Path = path.CGPath;
this.Layer.Mask = mask;
}
}
}
in Android
creat a xml file in the folder Resource->drawable boxview_style.xml
<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:shape="rectangle">
<solid
android:color="#ffffff" />
<corners
android:bottomLeftRadius="1000dp"
android:bottomRightRadius="1000dp" />
</shape>
</item>
</selector>
using Android.Support.V4.Content.Res;
using xxx;
using App11.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly:ExportRenderer(typeof(MyBoxView),typeof(MyViewRenderer))]
namespace xxx.Droid
{
public class MyViewRenderer : BoxRenderer
{
public MyAndriodEntry(Context context):base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if(Control!=null)
{
SetBackgroundResource(Resource.Drawable.boxview_style);
}
}
}
}

Xamarin: How to change Stepper color in Android to look like in iOS?

I have Xamarin PCL app which uses Stepper. I wanted to change the color of my Stepper button and now using the following renderer.
In PCL:
public class MyStepper : Stepper
{
public static readonly BindableProperty ColorProperty =
BindableProperty.Create(nameof(Color), typeof(Color), typeof(MyStepper), Color.Default);
public Color MyColor
{
get { return (Color)GetValue(ColorProperty); }
set { SetValue(ColorProperty, value); }
}
}
In iOS:
public class MyStepperRenderer : StepperRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Stepper> e)
{
base.OnElementChanged(e);
MyStepper s = Element as MyStepper;
if (Control != null)
Control.TintColor = s.MyColor.ToUIColor();
}
}
In Android:
protected override void OnElementChanged(ElementChangedEventArgs<Stepper> e)
{
base.OnElementChanged(e);
MyStepper s = Element as MyStepper;
if (Control != null)
{
Control.GetChildAt(0).Background.SetColorFilter(s.MyColor.ToAndroid(), PorterDuff.Mode.Multiply);
Control.GetChildAt(1).Background.SetColorFilter(s.MyColor.ToAndroid(), PorterDuff.Mode.Multiply);
}
}
In XAML:
<local:MyStepper MyColor="Red" Maximum="10" Minimum="0" ....... />
As expected it would work like the images attached. But is it possible to make the Android color to change just the "outline" of the button like what it looks like in iOS?
How about changing the colors of the - and + also to red. Is there a way to do that also?
Based on #Sven-Michael Stübe's answer, I add some code to change the "-" and "+" color:
protected override void OnElementChanged(ElementChangedEventArgs<Stepper> e)
{
base.OnElementChanged(e);
MyStepper s = Element as MyStepper;
if (Control != null)
{
var button = Control.GetChildAt(0) as Android.Widget.Button;
button.SetTextColor(s.MyColor.ToAndroid());
button.SetBackground(ResourcesCompat.GetDrawable(Resources, Resource.Drawable.button_selector, null));
button.Background.SetColorFilter(s.MyColor.ToAndroid(), PorterDuff.Mode.Multiply);
var button2 = Control.GetChildAt(1) as Android.Widget.Button;
button2.SetTextColor(s.MyColor.ToAndroid());
button2.SetBackground(ResourcesCompat.GetDrawable(Resources, Resource.Drawable.button_selector, null));
button2.Background.SetColorFilter(s.MyColor.ToAndroid(), PorterDuff.Mode.Multiply);
}
}
Effectt.
go and create a the drawable with the states and set them in your Renderer instead of setting a single color.
Sven-Michael Stübe wanna say that if you set a single color as a background, then your Button will have no click effect. You could refer to: Material effect on button with background color
for more detail information.
For example:
button_selector.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/colorAccent" android:state_pressed="true"/>
<item android:drawable="#color/colorPrimaryDark" android:state_focused="true"/>
<item android:drawable="#drawable/button_border"/>
</selector>
button_border.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#00FFFFFF" />
<corners android:radius="5dp" />
<stroke
android:width="2dp"
android:color="#FFFFFF" />
</shape>
You can do it if you create a custom vector drawable
button_border.xml
Place this file in your Android Resources\drawable folder and ensure the build action is set to AndroidResource
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#00FFFFFF" />
<corners android:radius="5dp" />
<stroke
android:width="2dp"
android:color="#FFFFFF" />
</shape>
MyStepperRenderer.cs
Then you just need to set it as background of your two buttons.
protected override void OnElementChanged(ElementChangedEventArgs<Stepper> e)
{
base.OnElementChanged(e);
var s = Element as MyStepper;
if (Control != null)
{
Control.GetChildAt(0).SetBackground(Resources.GetDrawable(Resource.Drawable.button_border));
Control.GetChildAt(1).SetBackground(Resources.GetDrawable(Resource.Drawable.button_border));
Control.GetChildAt(0).Background.SetColorFilter(s.MyColor.ToAndroid(), PorterDuff.Mode.Multiply);
Control.GetChildAt(1).Background.SetColorFilter(s.MyColor.ToAndroid(), PorterDuff.Mode.Multiply);
}
}
This will look like:
discussion
You loose states like pressed, disabled, ... (see https://developer.android.com/guide/topics/resources/color-list-resource.html)
If you don't have many different colors, go and create a the drawable with the states and set them in your Renderer instead of setting a single color. So your user will get a better feedback.

Xamarin MVVMCross - Binding on a Google Maps InfoWindow

I´m trying to use MvvmCross binding inside a Google Maps InfoWindow, on Android. I have a MvxFragment with a MapFragment inside.
I created a custom xml layout for the InfoWindow and tried to use a MvxFrameControl to display it, like this:
public class InfoWindow : Java.Lang.Object, GoogleMap.IInfoWindowAdapter
{
private readonly BaseStateFragment _window;
private readonly Dictionary<string, Restaurant> _restaurants;
public InfoWindow(BaseStateFragment window, Dictionary<string, Restaurant> restaurants)
{
_window = window;
_restaurants = restaurants;
}
public View GetInfoContents(Marker p0)
{
var layoutContainer = new MvxFrameControl(Resource.Layout.fragment_home_map_info, _window.Context, null)
{
LayoutParameters = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent),
DataContext = _restaurants[p0.Id] //ViewModel
};
return layoutContainer;
}
public View GetInfoWindow(Marker p0)
{
return null;
}
When I click on the marker, the method GetInfoContents is called but nothing is happening (the event binding is ok, I got it to work without binding).
Any ideas ?
As Requested, the layout file:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<include
android:id="#+id/restaurant_item"
android:layout_width="310dp"
android:layout_height="190dp"
layout="#layout/item_list_restaurant" />
<Button
android:id="#+id/bt_open_restaurant"
android:layout_width="310dp"
android:layout_height="wrap_content"
android:text="#string/label_go_restaurant_page"
android:textColor="#color/colorFacebook"
android:background="#color/lightBlue"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:layout_gravity="bottom"
android:layout_marginTop="8dp"
android:textAllCaps="true"
android:layout_marginBottom="4dp" />
</FrameLayout>

android how to show progress dialog on snackBar?

Is there way to show progress dialog on snackBar while getting data from server for pagination inside AsyncTask.If is this possible then how to do this.Please give suggestions.
For new design library:
if you want to show progressBar in left side:
Snackbar bar = Snackbar.make(root, R.string.data_updating, Snackbar.LENGTH_INDEFINITE);
ViewGroup contentLay = (ViewGroup) bar.getView().findViewById(android.support.design.R.id.snackbar_text).getParent();
ProgressBar item = new ProgressBar(context);
contentLay.addView(item,0);
bar.show();
or in right side:
Snackbar bar = Snackbar.make(root, R.string.data_updating, Snackbar.LENGTH_INDEFINITE);
ViewGroup contentLay = (ViewGroup) bar.getView().findViewById(android.support.design.R.id.snackbar_text).getParent();
ProgressBar item = new ProgressBar(context);
contentLay.addView(item);
bar.show();
the easiest and the best approach would be this:
Snackbar bar = Snackbar.make(layout, "Somthing", Snackbar.LENGTH_INDEFINITE);
Snackbar.SnackbarLayout snack_view = bar.getView();
snack_view.addView(new ProgressBar(context));
bar.show();
SnackbarLayout extends LinearLayout, so you can add view as a child or customize it the way you want.
for example to change the style of the TextView inside SnackBar you can do this:
TextView tv = (TextView) bar.getView().findViewById(android.support.design.R.id.snackbar_text);
tv.setTextColor(Color.WHITE);
tv.setTextSize(0, dimen[1] / 40);
tv.setTypeface(Typeface.createFromAsset(context.getAssets(),"fonts/font.otf"));
I've written a library that do just that. It also includes queue system. Try it out https://github.com/tingyik90/snackprogressbar
Kotlin 2021:
fun showLoadingSnackbar(){
val snackbar: Snackbar = Snackbar.make(findViewById(R.id.rootlayoutid), "TEXT or RES", Snackbar.LENGTH_INDEFINITE)
val viewGroup = snackbar.view.findViewById<View>(com.google.android.material.R.id.snackbar_text).parent as ViewGroup
viewGroup.addView(ProgressBar(this))// Or Context if not in Activity
snackbar.show()
}
If you want it on the left simply call addView(ProgressBar(this),0) instead as mentioned in the other answer
Edit: The answer has the progressbar at the top if the text is too long, so for it to be centered you can do this:
val snackbar: Snackbar = Snackbar.make(this, text, duration)
val viewGroup = snackbar.view.findViewById<View>(com.google.android.material.R.id.snackbar_text).parent as ViewGroup
viewGroup.addView(ProgressBar(context).also {
it.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT)
it.foregroundGravity = Gravity.CENTER_VERTICAL
})
snackbar.show()
I think you could style a custom progress dialog to look like a Snackbar, since snackbar doesn't prevent user interaction with GUI while loading.
Update:
Try this:
Create anim res file name it slide_in.xml and paste this:
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromYDelta="50%p" android:toYDelta="0%p"
android:duration="#android:integer/config_longAnimTime"
/>
create another anim res file name it slide_out.xml:
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="#android:integer/config_longAnimTime"
android:fromYDelta="0%p"
android:toYDelta="100%p" />
now place process dialog style in style res:
<style name="CustomDialog" parent="#android:style/Theme.Holo.Dialog">
<item name="android:windowMinWidthMajor">100%</item>
<item name="android:windowMinWidthMinor">100%</item>
<item name="android:background">#323232</item>
<item name="android:textColor">#FFFFFF</item>
<item name="android:windowBackground">#color/transparent</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:alertDialogStyle">#style/customDialogStyle</item>
<item name="android:windowAnimationStyle">#style/DialogAnimation</item>
</style>
<style name="customDialogStyle">
<item name="android:bottomBright">#android:color/transparent</item>
<item name="android:bottomDark">#android:color/transparent</item>
<item name="android:bottomMedium">#android:color/transparent</item>
<item name="android:centerBright">#android:color/transparent</item>
<item name="android:centerDark">#android:color/transparent</item>
<item name="android:centerMedium">#android:color/transparent</item>
<item name="android:fullBright">#android:color/transparent</item>
<item name="android:fullDark">#android:color/transparent</item>
<item name="android:topBright">#android:color/transparent</item>
<item name="android:topDark">#android:color/transparent</item>
Place this for animation:
<style name="DialogAnimation">
<item name="android:windowEnterAnimation">#anim/slide_in</item>
<item name="android:windowExitAnimation">#anim/slide_out</item>
</style>
Now add you method:
public static ProgressDialog processSnackbar(Context context,String s){
ProgressDialog pSnackbar = new ProgressDialog(context, R.style.CustomDialog) {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ProgressBar progress = (ProgressBar) findViewById(android.R.id.progress);
LinearLayout bodyLayout = (LinearLayout) progress.getParent();
TextView messageView = (TextView) bodyLayout.getChildAt(1);
messageView.setPadding(20,0,0,0);
LinearLayout.LayoutParams llp =
(LinearLayout.LayoutParams) messageView.getLayoutParams();
llp.width = 0;
llp.weight = 1;
bodyLayout.removeAllViews();
bodyLayout.addView(messageView, llp);
bodyLayout.addView(progress);
}
};
pSnackbar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pSnackbar.setMessage(s);
pSnackbar.getWindow().setGravity(Gravity.BOTTOM);
pSnackbar.setCancelable(false);
return pSnackbar;
}
Method Credit returns to #mike-m reference Is it possible to alter progress dialog's message or spinner position?
I am using this as well in my application take a look:

Android: Make custom seekbar opaque

Hi can anyone tell me why is my Seekbar's background and progress always have some opacity and just can't be removed even I have set the alpha to 1.0. Below is my progress_drawable.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#android:id/background">
<shape>
<corners android:radius="5dip" />
<gradient
android:alpha="1.0"
android:startColor="#000000"
android:endColor="#000000"/>
</shape>
</item>
<item android:id="#android:id/secondaryProgress">
<clip>
<shape>
<corners android:radius="5dip" />
<gradient
android:alpha="1.0"
android:startColor="#000000"
android:endColor="#000000" />
</shape>
</clip>
</item>
<item android:id="#android:id/progress">
<clip>
<shape>
<corners android:radius="5dip" />
<gradient
android:alpha="1.0"
android:endColor="#2e2dff"
android:startColor="#2e2dff" />
<solid android:color="#2e2dff" />
</shape>
</clip>
</item>
And this is the SeekBar tag in activity xml:
<SeekBar
android:padding="0dp"
android:id="#+id/normalSeekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/imgPenguin"
android:alpha="1"
android:progress="0"
android:progressDrawable="#drawable/progress_drawable"
android:secondaryProgress="0" />
I got this result but I want the bars to be opaque, please advise and thanks in advanced.
Just found the issue:
normalSB.setEnabled(false);
I shouldn't use setEnabled(false) to avoid user drag on thumb, instead, I have done this to reset progress when fromUser == true:
normalSB.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
int originalProgress;
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
float seekBarStarting = seekBar.getX();
float seekBarWidth = seekBar.getWidth();
float seekBarOffset = seekBar.getThumbOffset();
float ratio = (float) progress / seekBar.getMax();
float scaledProgress = ratio * seekBarWidth;
if (scaledProgress > imgPenguin.getWidth()) {
imgPenguin.setX(seekBarStarting - imgPenguin.getWidth() + scaledProgress);
}
if (fromUser == true) {
seekBar.setProgress(originalProgress);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
originalProgress = seekBar.getProgress();
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});

Resources