Add a toolbar in a MvxPreferenceFragmentCompat - xamarin

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?

Related

OnTabChanged not called when click on current tab

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);
}
...

How to implement Recycler View in MvvmCross using MvxRecyclerView

In MvvmCross, I have an android listview within an activity that works.
I read somewhere that changing the listView to a recyclerView is as simple as changing MvxListView to MvxRecyclerView in my layout .axml file. Trying that gives me the following runtime exception:
Android.Views.InflateException: Binary XML file line #1: Binary XML file line #1: Error inflating class Mvx.MvxRecyclerView
Is there anything that I have to do differently in the code behind or view model when using MvxRecyclerView? Below is my code.
Layout files:
Main.axml
<?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">
<Mvx.MvxRecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:id="#+id/words_listview"
local:MvxItemTemplate="#layout/words_listview_row"
local:MvxBind="ItemsSource Words" />
</LinearLayout>
words_listview_row.axml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:p1="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
p1:minWidth="25px"
p1:minHeight="25px"
p1:layout_width="match_parent"
p1:layout_height="match_parent"
p1:id="#+id/relativeLayout1"
p1:background="#FFFFFF">
<TextView
p1:text="Word name"
p1:layout_width="wrap_content"
p1:layout_height="wrap_content"
p1:id="#+id/headingTextView"
p1:width="325dp"
p1:textColor="#000000"
p1:layout_alignParentLeft="true"
p1:textSize="18sp"
p1:paddingLeft="20dp"
p1:paddingTop="15dp"
local:MvxBind="Text Name" />
<TextView
p1:text="Word meaning"
p1:layout_width="match_parent"
p1:layout_height="wrap_content"
p1:layout_below="#id/headingTextView"
p1:id="#+id/detailTextView"
p1:textColor="#8f949a"
p1:layout_alignParentLeft="true"
p1:textSize="16sp"
p1:paddingLeft="20dp"
p1:paddingRight="20dp"
p1:paddingBottom="15dp"
local:MvxBind="Text Meaning" />
</RelativeLayout>
WordViewModel.cs
using MvvmCross.Core.ViewModels;
using VocabBuilder.Core.Models;
using VocabBuilder.Core.Services.Interfaces;
namespace VocabBuilder.Core.ViewModels
{
public class WordViewModel : MvxViewModel
{
private IWordService _wordService;
public MvxObservableCollection<Word> Words { get; set; }
public WordViewModel(IWordService wordService)
{
Words = new MvxObservableCollection<Word>();
_wordService = wordService;
Words.ReplaceWith(_wordService.GetAllWords());
}
}
}
Codebehind/ WordView.cs
using Android.App;
using Android.OS;
using MvvmCross.Droid.Views;
using VocabBuilder.Core.ViewModels;
namespace VocabBuilder.UI.Droid.Views
{
[Activity(Label="Vocab Builder", MainLauncher=true)]
public class WordView : MvxActivity<WordViewModel>
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
}
}
}
Thanks.
EDIT:
Here is my Setup.cs file:
using Android.Content;
using MvvmCross.Core.ViewModels;
using MvvmCross.Droid.Platform;
namespace VocabBuilder.UI.Droid
{
public class Setup : MvxAndroidSetup
{
public Setup(Context applicationContext) : base(applicationContext)
{
}
protected override IMvxApplication CreateApp()
{
return new Core.App();
}
}
}
OK, I got RecyclerView to work easily after replacing MvxListView with MvxRecyclerView. Not sure what the particular problem with your implementation is but i will give you the tidbits of mine and you can try it all out.
My RecyclerView lives in a Fragment inheriting from MvxFragment - a bit different than yours but should not be the determining factor. Here are some Fragment snippets:
public class ListsFragment : MvxFragment<ListsViewModel>
{
...
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
base.OnCreateView(inflater, container, savedInstanceState);
var view = this.BindingInflate(Resource.Layout.fragment_listsfragment, null);
return view;
}
...
}
Here is the axml for fragment_listsfragment:
<?xml version="1.0" encoding="utf-8"?>
<MvvmCross.Droid.Support.V7.RecyclerView.MvxRecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:MvxItemTemplate="#layout/item_list"
app:MvxBind="ItemsSource Lists; ItemClick ShowListItemsCommand" />
I do see a bit of difference in your ViewModel implementation - mine is like this:
public class ListsViewModel : BaseViewModel
{
...
private readonly IListService _listService;
private ObservableCollection<Models.List> _lists;
public ObservableCollection<Models.List> Lists
{
get { return _lists; }
set
{
_lists = value;
RaisePropertyChanged(() => Lists);
}
}
public MvxCommand<Models.List> ShowListItemsCommand
{
get
{
return new MvxCommand<Models.List>(selectedList =>
{
ShowViewModel<ListItemsViewModel>
(new { listId = selectedList.Id });
});
}
}
...
public override async void Start()
{
base.Start();
await InitializeAsync();
}
protected override async Task InitializeAsync()
{
await _listService.InitializeAsync();
Lists = (await _listService.GetListsAsync())
.ToObservableCollection();
}
}
Hope this helps.

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>();

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

Android: implementing Checkbox List with ListFragment and ArrayAdapter

I am converting a working application to Fragments. My checkbox list is not displaying the labels, and I am guessing, the id's. I am new to Android/Java and this is my first post to Stackoverflow, so apologies if the question is simple or not following correct protocol.
My ListFragment is as follows:
import java.util.ArrayList;
import java.util.List;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.TextView;
public class DistributionTransFragment extends ListFragment {
protected TextView subheader;
protected Context mContext;
protected DatabaseHandler db;
protected String user_id;
protected String user;
protected String recipients;
protected int number;
protected LayoutInflater inflater;
protected View v;
DistributionArrayAdapter dataAdapter = null;
public DistributionTransFragment(){
super();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
v = inflater.inflate(R.layout.distribution_fragment, container, false);
mContext = getActivity().getApplicationContext();
db = new DatabaseHandler(mContext);
subheader = (TextView)v.findViewById(R.id.textView2);
subheader.setText("Spent On?");
displayListView();
checkButtonClick();
return v;
}
private void displayListView() {
ArrayList<Participant> distributionList = new ArrayList<Participant>();
Participant participant;
List<User> users = db.getAllUsers();
for (User u : users) {
user_id = String.valueOf(u.getID());
user = u.getUser();
participant = new Participant(user_id, user, false);
distributionList.add(participant);
}
//create an ArrayAdaptar from the String Array
dataAdapter = new DistributionArrayAdapter(mContext, R.layout.distributionlist, distributionList);
setListAdapter(dataAdapter);
}
private class DistributionArrayAdapter extends ArrayAdapter<Participant> {
private ArrayList<Participant> distributionList;
public DistributionArrayAdapter(Context context, int textViewResourceId, ArrayList<Participant> distributionList) {
super(context, textViewResourceId, distributionList);
this.distributionList = new ArrayList<Participant>();
this.distributionList.addAll(distributionList);
}
private class ViewHolder {
TextView code;
CheckBox name;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
Log.v("ConvertView", String.valueOf(position));
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.distributionlist, null);
holder = new ViewHolder();
holder.code = (TextView) convertView.findViewById(R.id.code);
holder.name = (CheckBox) convertView.findViewById(R.id.checkBox1);
convertView.setTag(holder);
Log.d("HOLDER CODE", (holder.code).toString());
holder.name.setOnClickListener( new View.OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v ;
Participant participant = (Participant) cb.getTag();
participant.setSelected(cb.isChecked());
}
});
} else {
holder = (ViewHolder) convertView.getTag();
}
Participant participant = distributionList.get(position);
holder.name.setText(participant.getName());
holder.name.setChecked(participant.isSelected());
holder.name.setTag(participant);
return convertView;
}
}
private void checkButtonClick() {
Button myButton = (Button) v.findViewById(R.id.button1);
myButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
final ArrayList<Participant> distributionList = dataAdapter.distributionList;
// Do Stuff
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setMessage(tempTransaction);
builder.setCancelable(false);
builder.setPositiveButton("Commit", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Do More Stuff
Intent intent = new Intent(mContext, Home.class);
startActivity(intent);
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Do Other Stuff
Intent intent = new Intent(mContext, Home.class);
startActivity(intent);
}
});
AlertDialog alert = builder.create();
alert.show();
}
});
}
}
My XML for the list is as follows:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#color/white"
android:padding="15dip" >
<CheckBox
android:id="#+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:focusable="false"
android:focusableInTouchMode="false" />
<TextView
android:id="#+id/code"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/checkBox1"
android:layout_alignBottom="#+id/checkBox1"
android:layout_toRightOf="#+id/checkBox1"
android:textSize="15sp" />
</RelativeLayout>
My XML for the fragment is as follows:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/grey">
<RelativeLayout
android:id="#+id/subheader"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/secondheader"
android:orientation="vertical" >
<TextView
android:id="#+id/textView2"
style="#style/subheader" />
<TextView
android:id="#+id/textView3"
style="#style/info" />
</RelativeLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/subheader"
android:layout_above="#+id/footer"
android:orientation="vertical" >
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:id="#id/footer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#color/grey"
android:layout_alignParentBottom="true" >
<Button
android:id="#+id/button1"
style="#style/button.form"
android:text="#string/moneyspent" />
</LinearLayout>
</RelativeLayout>
Any help would be greatly appreciated.
I nutted it out, so thought I would post my answer in case others have the same problem. It was my context. It should have been:
mContext = getActivity();

Resources