OnTabChanged not called when click on current tab - xamarin

I implemented a tabbed application with Xamarin.Android using TabHost and MvxTabsFragmentActivity.
I want to refresh the current tab when clicking on it the second time.
Is there any method like OnTabReselected from Android?
That's how I am creating the tabs, using TabHost:
<TabHost android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/white">
<LinearLayout android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="7dp"
android:background="#drawable/gradient_border_top"
android:orientation="horizontal" />
<TabWidget android:id="#android:id/tabs"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_weight="0"
android:background="#color/white" />
<FrameLayout android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
</LinearLayout>
</TabHost>
And MainView:
[Activity(Theme = "#style/MyTheme", ScreenOrientation = ScreenOrientation.Portrait, WindowSoftInputMode = SoftInput.AdjustPan)]
public class MainView : MvxTabsFragmentActivity
{
public MainView() : base(Resource.Layout.main_layout, Resource.Id.actualtabcontent)
{
}
private static TabHost TabHost { get; set; }
public override void OnTabChanged(string tag)
{
var pos = TabHost.CurrentTab;
var tabView = TabHost.TabWidget.GetChildTabViewAt(pos);
tabView.FindViewById<ImageView>(Resource.Id.tabImage)
.SetColorFilter(new Color(ContextCompat.GetColor(Application.Context, Resource.Color.tabColorSelected)));
tabView.FindViewById<TextView>(Resource.Id.tabTitle)
.SetTextColor(new Color(ContextCompat.GetColor(Application.Context, Resource.Color.tabColorSelected)));
for (var i = 0; i < TabHost.TabWidget.ChildCount; i++)
{
if (pos != i)
{
var tabViewUnselected = TabHost.TabWidget.GetChildTabViewAt(i);
tabViewUnselected.FindViewById<ImageView>(Resource.Id.tabImage)
.SetColorFilter(new Color(ContextCompat.GetColor(Application.Context, Resource.Color.tabColor)));
tabViewUnselected.FindViewById<TextView>(Resource.Id.tabTitle)
.SetTextColor(new Color(ContextCompat.GetColor(Application.Context, Resource.Color.tabColor)));
}
}
base.OnTabChanged(tag);
}
}
// This is where I add all 4 tabs
protected override void AddTabs(Bundle args)
{
AddTab<TrackHomeView>(
args,
Mvx.IoCProvider.IoCConstruct<TrackHomeViewModel>(),
CreateTabFor(((int)TabIdentifier.TrackTab).ToString(), Resource.Drawable.ic_track_icon, Strings.Track));
AddTab<SendView>(
args,
Mvx.IoCProvider.IoCConstruct<SendViewModel>(),
CreateTabFor(((int)TabIdentifier.SendTab).ToString(), Resource.Drawable.ic_send_icon, Strings.Send));
if (MainViewModel.IsUserLoggedIn())
{
AddTab<ProfileView>(
args,
Mvx.IoCProvider.IoCConstruct<ProfileViewModel>(),
CreateTabFor(((int)TabIdentifier.ProfileTab).ToString(), Resource.Drawable.ic_profile_icon, Strings.Profile));
}
else
{
AddTab<CreateAccountView>(
args,
Mvx.IoCProvider.IoCConstruct<CreateAccountViewModel>(),
CreateTabFor(((int)TabIdentifier.ProfileTab).ToString(), Resource.Drawable.ic_profile_icon, Strings.Profile));
}
AddTab<MoreView>(
args,
Mvx.IoCProvider.IoCConstruct<MoreViewModel>(),
CreateTabFor(((int)TabIdentifier.MoreTab).ToString(), Resource.Drawable.ic_more_icon, Strings.More));
}
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
TabHost = FindViewById<TabHost>(global::Android.Resource.Id.TabHost);
TabHost.TabWidget.SetDividerDrawable(null);
TabHost.Setup();
}
I added only relevant code.
The tabs are created using TabHost, and the Activity is inherited from MvxTabsFragmentActivity.

You can inherit the ActionBar.ITabListener interface in your TabHost's MvxTabsFragmentActivity and then you can get the events that you need.
public class MainActivity : MvxTabsFragmentActivity, ActionBar.ITabListener
{
public void OnTabReselected(ActionBar.Tab tab, FragmentTransaction ft)
{
// Optionally refresh/update the displayed tab.
Log.Debug(Tag, "The tab {0} was re-selected.", tab.Text);
}
public void OnTabSelected(ActionBar.Tab tab, FragmentTransaction ft)
{
// Display the fragment the user should see
Log.Debug(Tag, "The tab {0} has been selected.", tab.Text);
}
public void OnTabUnselected(ActionBar.Tab tab, FragmentTransaction ft)
{
// Save any state in the displayed fragment.
Log.Debug(Tag, "The tab {0} as been unselected.", tab.Text);
}
...

Related

Update textview in android custom notification

I have a custom local notification implementing remoteview comprising of three buttons and a textview. Button click in notification changes volume of ringer but I want to increment a variable count each time the up button click or decrement then count each time downbutton click. I have problem updating textview as the broadcaster class can't access it directly. I tried a method from a post, but I can't make it work.
I get null exception at tvUpdate.text=t;
Any idea would be appreaciated. Thanks
RemoteView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="75dp"
android:weightSum="100"
android:padding="5dp"
android:background="#969696"
android:minWidth="25px"
android:minHeight="25px">
<Button
android:text="Vol_Up"
android:layout_width="0dp"
android:layout_weight="25"
android:background="#drawable/roundcnr"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:textColor="#FFFFFF"
android:id="#+id/btnVolUp" />
<Button
android:text="V_Down"
android:layout_width="0dp"
android:layout_weight="25"
android:layout_margin="5dp"
android:textColor="#FFFFFF"
android:background="#drawable/roundcnr"
android:layout_height="wrap_content"
android:id="#+id/btnVolDown" />
<Button
android:text="Silent"
android:layout_width="0dp"
android:layout_weight="25"
android:layout_margin="5dp"
android:background="#drawable/roundcnr"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:id="#+id/btnVolSilent" />
<TextView
android:text="Status"
android:layout_width="0dp"
android:layout_weight="25"
android:textColor="#FFFFFF"
android:layout_height="wrap_content"
android:id="#+id/tvVol" />
</LinearLayout>
Broadcaster Class
namespace RingerTest
{
[BroadcastReceiver]
public class myBroadCastR : BroadcastReceiver
{
public double counter { get; set; }
public override void OnReceive(Context context, Intent intent)
{
if(intent.Action== "VolumeUp")
{
counter += 6;
// Toast.MakeText(context,"VolumeUp",ToastLength.Long).Show();
AudioManager audioManager = (AudioManager)context.GetSystemService(Context.AudioService);
audioManager.AdjustSuggestedStreamVolume(Adjust.Raise, Stream.Ring, VolumeNotificationFlags.PlaySound);
try
{
MainActivity.getinstance().updateTextView(counter.ToString() + "%");
}
catch (Exception ex)
{
}
}
else if (intent.Action == "VolumeDown")
{
counter -= 6;
// Toast.MakeText(context, "VolumeDown",ToastLength.Long).Show();
AudioManager audioManager = (AudioManager)context.GetSystemService(Context.AudioService);
audioManager.AdjustSuggestedStreamVolume(Adjust.Lower, Stream.Ring, VolumeNotificationFlags.PlaySound);
try
{
MainActivity.getinstance().updateTextView(counter.ToString() + "%");
}
catch (Exception ex)
{
}
}
else if (intent.Action == "Silent")
{
counter = 0;
// Toast.MakeText(context, "VolumeDown",ToastLength.Long).Show();
AudioManager audioManager = (AudioManager)context.GetSystemService(Context.AudioService);
audioManager.RingerMode = RingerMode.Silent;
MainActivity.getinstance().updateTextView(counter.ToString()+"%");
}
}
}
}
MainActivity
namespace RingerTest
{
[Activity(Label = "RingerTest", MainLauncher = true)]
public class MainActivity : Activity
{
public static MainActivity ins;
private myBroadCastR myBroadl;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
ins = this;
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
var myreceiver = new myBroadCastR();
var intentfilter = new IntentFilter();
intentfilter.AddAction("VolumeUp");
intentfilter.AddAction("VolumeDown");
intentfilter.AddAction("Silent");
RegisterReceiver(myreceiver, intentfilter);
Button btnNotify = FindViewById<Button>(Resource.Id.button1);
btnNotify.Click += BtnNotify_Click;
}
public static MainActivity getinstance()
{
return ins;
}
public void updateTextView(string t)
{
MainActivity.ins.RunOnUiThread(() =>
{
TextView tvUpdate = FindViewById<TextView>(Resource.Id.tvVol);
tvUpdate.Text = t;
});
}
private void BtnNotify_Click(object sender, System.EventArgs e)
{
const int requestID = 1;
//Volume Up
Intent intent_V_UP = new Intent("VolumeUp");
PendingIntent pIntent_V_UP = PendingIntent.GetBroadcast(this, requestID, intent_V_UP, PendingIntentFlags.UpdateCurrent);
//Volume Down
Intent intent_V_Down = new Intent("VolumeDown");
PendingIntent pIntent_V_Down = PendingIntent.GetBroadcast(this, requestID, intent_V_Down, PendingIntentFlags.UpdateCurrent);
//Silent
Intent intent_Silent = new Intent("Silent");
PendingIntent pIntent_Silent = PendingIntent.GetBroadcast(this, requestID, intent_Silent, PendingIntentFlags.UpdateCurrent);
Notification.Builder builder = new Notification.Builder(this);
builder.SetSmallIcon(Resource.Drawable.addContact);
/*
builder.SetContentTitle("VolControl");
builder.AddAction(Resource.Drawable.addContact, "VolDown", pIntent_V_Down);
builder.AddAction(Resource.Drawable.addContact, "VolUP", pIntent_V_UP);*/
//Custom View for Notification
RemoteViews remoteViews = new RemoteViews(this.PackageName, Resource.Layout.customNotification);
//On Button Click in CustomView
remoteViews.SetOnClickPendingIntent(Resource.Id.btnVolUp, pIntent_V_UP);
remoteViews.SetOnClickPendingIntent(Resource.Id.btnVolDown, pIntent_V_Down);
remoteViews.SetOnClickPendingIntent(Resource.Id.btnVolSilent, pIntent_Silent);
Notification notification = builder.Build();
notification.BigContentView = remoteViews;
notification.Flags = NotificationFlags.NoClear;
NotificationManager notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.Notify(1, notification);
}
}
}

How to display image with text in 2 columns GridView

How to display image with text ( like name, price.. etc )
Below code only display images with no text.
--- UI :
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnWidth="230dp"
android:numColumns="2"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:background="#ffffff"
android:stretchMode="columnWidth"
android:gravity="center" />
-- Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
namespace ModSpforce
{
class ImageAdapter : BaseAdapter
{
Context context;
public ImageAdapter(Context c)
{
context = c;
}
public override int Count
{
get { return thumbIds.Length; }
}
public override Java.Lang.Object GetItem(int position)
{
return null;
}
public override long GetItemId(int position)
{
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public override View GetView(int position, View convertView, ViewGroup parent)
{
ImageView imageView;
if (convertView == null)
{ // if it's not recycled, initialize some attributes
imageView = new ImageView(context);
imageView.LayoutParameters = new GridView.LayoutParams(200, 200);
imageView.SetScaleType(ImageView.ScaleType.CenterCrop);
imageView.SetPadding(3, 3, 3, 3);
}
else
{
imageView = (ImageView)convertView;
}
imageView.SetImageResource(thumbIds[position]);
return imageView;
}
// references to our images
int[] thumbIds = {
Resource.Drawable.sample_2, Resource.Drawable.sample_3,
Resource.Drawable.sample_4, Resource.Drawable.sample_5,
Resource.Drawable.sample_6, Resource.Drawable.sample_7,
Resource.Drawable.sample_0, Resource.Drawable.sample_1,
Resource.Drawable.sample_2, Resource.Drawable.sample_3,
Resource.Drawable.sample_4, Resource.Drawable.sample_5,
Resource.Drawable.sample_6, Resource.Drawable.sample_7,
Resource.Drawable.sample_0, Resource.Drawable.sample_1,
Resource.Drawable.sample_2, Resource.Drawable.sample_3,
Resource.Drawable.sample_4, Resource.Drawable.sample_5,
Resource.Drawable.sample_6, Resource.Drawable.sample_7
};
}
}
You can inflate your GridView's cell in the GetView method of your adapter, so you can simply design your item's template in xml.
For example:
Code behind of your GridView:
public ObservableCollection<MyItemModel> items = new ObservableCollection<MyItemModel>();
public MyGridViewAdapter adapter;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
//add your items here.
for (int i = 0; i < 50; i++)
{
items.Add(new MyItemModel { ImageSource = Resource.Drawable.Pika, Name = "Name " + i });
}
adapter = new MyGridViewAdapter(this, items);
GridView gv = FindViewById<GridView>(Resource.Id.gridview);
gv.Adapter = adapter;
}
MyItemModel is for image resource and name of this image, like this:
public class MyItemModel
{
public string Name { get; set; }
public int ImageSource { get; set; }
}
And MyGridViewAdapter is like this:
public class MyGridViewAdapter : BaseAdapter<MyItemModel>
{
private ObservableCollection<MyItemModel> items;
private Activity context;
public MyGridViewAdapter(Activity context, ObservableCollection<MyItemModel> items)
{
this.items = items;
this.context = context;
}
public override MyItemModel this[int position]
{
get
{
return items[position];
}
}
public override int Count
{
get
{
return items.Count;
}
}
public override long GetItemId(int position)
{
return position;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
View view = convertView;
if (view == null)
{
view = context.LayoutInflater.Inflate(Resource.Layout.MyGridViewCell, null);
}
var image = view.FindViewById<ImageView>(Resource.Id.image);
image.SetImageResource(items[position].ImageSource);
var name = view.FindViewById<TextView>(Resource.Id.name);
name.Text = items[position].Name;
return view;
}
}
Finally the layout of MyGridViewCell is like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView android:id="#+id/image"
android:layout_height="200dp"
android:layout_width="200dp" />
<TextView android:id="#+id/name"
android:layout_height="wrap_content"
android:layout_width="200dp"
android:textColor="#android:color/holo_blue_light" />
</LinearLayout>

Xamarin.Android MvvmCross Data-Binding Issue

I'm trying to create a simple app that uses the Xamarin Geofence plugin. (https://github.com/domaven/xamarin-plugins/tree/master/Geofence).
I'm using MvvmCross for model binding and the App View is interested in events coming from the Geofence instance.
On My ViewModel i have implemented the IGeofenceListener interface so that when any of the events are fired i can directly change the value of the binding properties in my ViewModel that are being targeted in the View.
public class MainViewModel : MvxViewModel, IGeofenceListener
{
double _latitude;
public double Latitude
{
get
{
return _latitude;
}
set
{
_latitude = value;
RaisePropertyChanged(() => Latitude);
}
}
double _longitude;
public double Longitude
{
get
{
return _longitude;
}
set
{
_longitude = value;
RaisePropertyChanged(() => Longitude);
}
}
string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
RaisePropertyChanged(() => Name);
}
}
public void OnAppStarted()
{
Debug.WriteLine(string.Format("{0} - {1}", CrossGeofence.Id, "App started"));
}
public void OnError(string error)
{
Debug.WriteLine(string.Format("{0} - {1}: {2}", CrossGeofence.Id, "Error", error));
}
public void OnLocationChanged(GeofenceLocation location)
{
Longitude = location.Longitude;
Latitude = location.Latitude;
Name = CrossGeofence.Id;
Debug.WriteLine(string.Format("{0} - Long: {1} || Lat: {2}", CrossGeofence.Id, location.Longitude, location.Latitude));
}
public void OnMonitoringStarted(string identifier)
{
Debug.WriteLine(string.Format("{0} - Monitoring started in region: {1}", CrossGeofence.Id, identifier));
}
public void OnMonitoringStopped()
{
Debug.WriteLine(string.Format("{0} - {1}", CrossGeofence.Id, "Monitoring stopped for all regions"));
}
public void OnMonitoringStopped(string identifier)
{
Debug.WriteLine(string.Format("{0} - {1}: {2}", CrossGeofence.Id, "Monitoring stopped in region", identifier));
}
public void OnRegionStateChanged(GeofenceResult result)
{
Longitude = result.Longitude;
Latitude = result.Latitude;
Debug.WriteLine(string.Format("{0} - {1}", CrossGeofence.Id, result.ToString()));
}
}
As you can see, On certain events Im updating the properties of my ViewModel and then calling the RaisePropertyChanged event for the View.
I've added Debug tracing to ensure that these events are actually being fired.
I can see the events firing in my Output window.. and when i debug the application i can see the properties on the ViewModel been updated. It's just that the RaisePropertyChanged event in not actually updating the View.
Here is my View Code :-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00007f"
android:layout_marginTop="10dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
local:MvxBind="Text Longitude"
android:id="#+id/textViewLongitude"
android:textColor="#android:color/white" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
local:MvxBind="Text Latitude"
android:id="#+id/textViewLatitude"
android:textColor="#android:color/white" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
local:MvxBind="Text Name"
android:textColor="#android:color/white"
android:id="#+id/textViewName" />
</LinearLayout>
This is the App setup code in my Core Library :-
public class App : MvxApplication
{
public App()
{
Mvx.RegisterSingleton<IMvxAppStart>(new MvxAppStart<MainViewModel>());
}
}
Here is the Main Activity MvxClass :-
[Activity(Label = "Geofence.Android", MainLauncher = true)]
public class MainActivity : MvxActivity<MainViewModel>
{
protected override void OnViewModelSet()
{
SetContentView(Resource.Layout.Main);
}
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
CrossGeofence.Initialize<MainViewModel>();
CrossGeofence.Current.StopMonitoring("LHR");
CrossGeofence.Current.StartMonitoring(new Plugin.Abstractions.GeofenceCircularRegion("Location", 54.9672132, -1.5992939, 2000)
{
NotifyOnStay = true,
NotifyOnEntry = true,
NotifyOnExit = true,
ShowNotification = true,
ShowEntryNotification = false,
ShowExitNotification = false,
ShowStayNotification = true,
NotificationStayMessage = "stay message!",
NotificationEntryMessage = "entry message!",
NotificationExitMessage = "exit message!",
StayedInThresholdDuration = TimeSpan.FromSeconds(1),
});
}
}
This is because CrossGeofence.Initialize<MainViewModel>(); creates a new ViewModel, that is not that one that was created by MvvmCross. You can see that, when you inspect the ViewModel of the activity in the debugger.
Solution
Use the GeofenceListener property.
CrossGeofence.GeofenceListener = (IGeofenceListener)ViewModel;
CrossGeofence.Initialize<MainViewModel>();

Add a toolbar in a MvxPreferenceFragmentCompat

I'm getting some problems creating a settings page using MvxPreferenceFragmentCompat. I've already shown the preferences view, but I could not include the toolbar in the same page.
I'm using XPlatformMenus sample to create my app.
I've already try many solutions like
attempt 1 or attempt 2, but no success.
Here is my current code:
SettingsFragment.cs
[MvxFragment(typeof(MainViewModel), Resource.Id.content_frame)]
[Register("myapp.droid.fragments.SettingsFragment")]
public class SettingsFragment : BasePreferenceFragment<SettingsViewModel>
{
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
base.showHamburgerMenu = true;
return base.OnCreateView(inflater, container, savedInstanceState);
}
public override void OnCreatePreferences(Bundle savedInstanceState, string rootKey)
{
this.AddPreferencesFromResource(FragmentId);
}
protected override int FragmentId
{
get
{
return Resource.Layout.fragment_settings;
}
}
}
fragment_settings.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:key="pref_sync"
android:title="Title sample"
android:summary="Here is the checkbox summary"
android:defaultValue="true" />
</PreferenceScreen>
BasePreferenceFragment
public abstract class BasePreferenceFragment : MvxPreferenceFragmentCompat
{
protected Toolbar _toolbar;
protected MvxActionBarDrawerToggle _drawerToggle;
/// <summary>
/// If true show the hamburger menu
/// </summary>
protected bool showHamburgerMenu = false;
protected BasePreferenceFragment()
{
RetainInstance = true;
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var view = base.OnCreateView(inflater, container, savedInstanceState);
_toolbar = view.FindViewById<Toolbar>(Resource.Id.toolbar);
if (_toolbar != null)
{
((MainActivity)Activity).SetSupportActionBar(_toolbar);
if (showHamburgerMenu)
{
((MainActivity)Activity).SupportActionBar.SetDisplayHomeAsUpEnabled(true);
_drawerToggle = new MvxActionBarDrawerToggle(
Activity, // host Activity
((MainActivity)Activity).DrawerLayout, // DrawerLayout object
_toolbar, // nav drawer icon to replace 'Up' caret
Resource.String.drawer_open, // "open drawer" description
Resource.String.drawer_close // "close drawer" description
);
_drawerToggle.DrawerOpened += (object sender, ActionBarDrawerEventArgs e) =>
{
if (Activity != null)
((MainActivity)Activity).HideSoftKeyboard();
};
((MainActivity)Activity).DrawerLayout.AddDrawerListener(_drawerToggle);
}
}
return view;
}
protected abstract int FragmentId { get; }
public override void OnConfigurationChanged(Configuration newConfig)
{
base.OnConfigurationChanged(newConfig);
if (_toolbar != null && null != _drawerToggle)
{
_drawerToggle.OnConfigurationChanged(newConfig);
}
}
public override void OnActivityCreated(Bundle savedInstanceState)
{
base.OnActivityCreated(savedInstanceState);
if (_toolbar != null && null != _drawerToggle)
{
_drawerToggle.SyncState();
}
}
}
public abstract class BasePreferenceFragment<TViewModel> : BasePreferenceFragment where TViewModel : class, IMvxViewModel
{
public new TViewModel ViewModel
{
get { return (TViewModel)base.ViewModel; }
set { base.ViewModel = value; }
}
}
toolbar_actionbar.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:id="#+id/appbar"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
local:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
</android.support.design.widget.AppBarLayout>
fragment_setting_screen.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
layout="#layout/toolbar_actionbar" />
<FrameLayout
android:id="#+id/content_frame"
android:layout_below="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
What am I doing wrong? Any idea?

How to make a Single Row Horizontal ListView/List?

What I want to do is Create a Single Row Listview/List with a image and text is this is what i have right now
I have Changed the numColumns to 1 but how do I change it so it is Horizontal and Scrollable? the image should be one top and the text should be below it?
This is the Layout
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnWidth="90dp"
android:numColumns="1"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:gravity="center"
/>
Single Grid Item
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="250dp"
android:scaleType="centerCrop"
android:id="#+id/my_image_vieww" />
<TextView
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/my_text_view" />
</LinearLayout>
Main Activity
var gridview = FindViewById<GridView> (Resource.Id.gridview);
gridview.Adapter = new ImageAdapter (this);
gridview.ItemClick += delegate (object sender, AdapterView.ItemClickEventArgs args) {
Toast.MakeText (this, args.Position.ToString (), ToastLength.Short).Show ();
};
public class ImageAdapter : BaseAdapter
{
Context context;
public ImageAdapter (Context c)
{
context = c;
}
public override int Count {
get { return thumbIds.Length; }
}
public override Java.Lang.Object GetItem (int position)
{
return null;
}
public override long GetItemId (int position)
{
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public override View GetView (int position, View convertView, ViewGroup parent)
{
ImageView imageView;
View view;
if (convertView == null) { // if it's not recycled, initialize some attributes
view = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.my_grid_row, parent, false);
} else {
view = convertView;
}
var imageView2 = view.FindViewById<ImageView>(Resource.Id.my_image_vieww);
imageView2.SetImageResource (thumbIds[position]);
var textView = view.FindViewById<TextView>(Resource.Id.my_text_view);
textView.Text = "Text to Display";
return view;
}
}
Please Dont user horizontal list view.
There is predefined android controll to achieve this. View Pager
Sample Code:
var _viewPager = view.FindViewById<ViewPager>(Resource.Id.viewPager);
var _viewPageIndicatorCircle = view.FindViewById<CirclePageIndicator>(Resource.Id.viewPageIndicator);
_viewPager.Adapter = new TestFragmentAdapter(fm);
_viewPageIndicatorCircle.SetViewPager(_viewPager);
public class TestFragmentAdapter : FragmentPagerAdapter
{
public TestFragmentAdapter(Android.Support.V4.App.FragmentManager fm)
: base(fm)
{
}
public override Android.Support.V4.App.Fragment GetItem(int position)
{
return new TestFragment();
}
public override int Count
{
get
{
return 5;
}
}
}
class TestFragment : Android.Support.V4.App.Fragment
{
public TestFragment()
{
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var view = inflater.Inflate(Resource.Layout.MyViewPager , container, false);
return view;
}
}
Viewpager.xml
<android.support.v4.view.ViewPager
android:id="#+id/viewPager"
android:layout_width="fill_parent"
android:layout_height="209.6dp" />
If you have any queries please feel free to ask me

Resources