How to add the icon to the right side in the NavigationView - xamarin.android

I am working on Xamarin.android application, where it contains the Drawer layout with NavigationView. I need to change the icon to the right side instead of left of the textView.
here is my layout code:
<android.support.design.widget.NavigationView
android:id="#+id/questiontypes_nav_view"
android:layout_width="220dp"
android:ellipsize="end"
android:layout_below="#+id/navigation_drawer_top"
android:maxLines="1"
android:scrollbars="none"
android:layout_above="#+id/navigation_drawer_bottom"
android:nestedScrollingEnabled="true"
android:layoutDirection="ltr"
android:layout_height="match_parent"
app:theme="#style/NavigationDrawerStyle"
android:background="#031d2c"
android:fitsSystemWindows="true"
app:itemTextAppearance="?android:attr/textAppearanceSmall"
app:itemTextColor="#android:color/white"
app:itemBackground="#drawable/nav_item_drawable"
app:itemIconTint="#drawable/nav_item_drawable">
</android.support.design.widget.NavigationView>
is there any way to get icon to the right side in the NavigationView.

Based on your description, do you want to switch position between textview and icon? If so, you could create a listview to achieve it in NavigationView like the following code.
This is GIF of demo.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="220dp"
android:scrollbars="none"
android:nestedScrollingEnabled="true"
android:layoutDirection="ltr"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main">
<ListView
android:paddingTop="500px"
android:id="#+id/lst_menu_items"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
ListItem.axml(customize menu)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/Ls_textview"
android:text="this is text"
android:textSize="15dp"
android:layout_marginRight="5dp"
android:layout_marginLeft="15dp"
android:layout_marginTop="18dp"/>
<ImageView
android:layout_marginLeft="50dp"
android:layout_width="50dp"
android:layout_height="50dp"
android:id="#+id/Ls_ImageView"
android:src="#drawable/lcon"/>
</LinearLayout>
This is in OnCreate() method.
ListView listView = FindViewById<ListView>(Resource.Id.lst_menu_items);
List<ListItem> listItems = new List<ListItem>();
listItems.Add(new ListItem(Resource.Drawable.lcon, "Title1"));
listItems.Add(new ListItem(Resource.Drawable.lcon, "Title2"));
listItems.Add(new ListItem(Resource.Drawable.lcon, "Title3"));
listItems.Add(new ListItem(Resource.Drawable.lcon, "Title4"));
MyAdapter myAdapter= new MyAdapter(listItems, this);
listView.Adapter = myAdapter;
listView.ItemClick += (s, e) =>
{
OnClick(e.Position);
};
You could handle click event like following code.
private void OnClick(int position)
{
position++;
if (position == 1)
{
Toast.MakeText(this, $"you click title" + position, ToastLength.Short).Show();
}
else if (position == 2)
{
Toast.MakeText(this, $"you click title" + position, ToastLength.Short).Show();
}
else if (position == 3)
{
Toast.MakeText(this, $"you click title" + position, ToastLength.Short).Show();
}
else if (position == 4)
{
Toast.MakeText(this, $"you click title" + position, ToastLength.Short).Show();
}
DrawerLayout drawer = FindViewById<DrawerLayout>(Resource.Id.drawer_layout);
drawer.CloseDrawer(GravityCompat.Start);
}
This is adapter of listview
public class ListItem {
public ListItem(int ImageSrc, string ItemName)
{
this.ImageSrc = ImageSrc;
this.ItemName = ItemName;
}
public int ImageSrc { get; set; }
public string ItemName { get; set; }
}
public class MyAdapter : BaseAdapter
{
List<ListItem> listItems;
Context context;
public MyAdapter(List<ListItem> listItems, Context context)
{
this.listItems = listItems;
this.context = context;
}
public override int Count => listItems.Count;
public override Java.Lang.Object GetItem(int position)
{
throw new NotImplementedException();
}
public override long GetItemId(int position)
{
return position;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
convertView = LayoutInflater.From(context).Inflate(Resource.Layout.ListItem, parent, false);
TextView textView = convertView.FindViewById<TextView>(Resource.Id.Ls_textview);
ImageView imageView = convertView.FindViewById<ImageView>(Resource.Id.Ls_ImageView);
//int id=Resource.Drawable.Capture;
textView.Text = listItems[position].ItemName;
imageView.SetImageResource(listItems[position].ImageSrc);
return convertView;
}
}

Related

ProgressBar stops spinning at some point while loading data inside activity (Xamarin.Android)

I have the following screen:
When I click on Ponentes ImageButton, ProgressBar appears while the data inside Ponentes activity is loading. The problem is that it stops spinning at some point. What may cause the issue and how can I fix it?
Here is the ProgressBar in the Ponentes axml:
<ProgressBar
android:id = "#+id/loadingSpinner"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:gravity="center"/>
Here is the OnCreate method of Ponentes Activity:
protected override async void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.SpeakersActivity);
Android.Widget.Toolbar toolbar = FindViewById<Android.Widget.Toolbar>(Resource.Id.toolbar);
toolbar.NavigationOnClick += delegate
{
this.OnBackPressed();
};
loadingSpinner = FindViewById<ProgressBar>(Resource.Id.loadingSpinner);
loadingSpinner.Visibility = ViewStates.Visible;
await Task.Run(() =>
{
//get all the speakers from the db
allSpeakers = DatabaseHelper.GetAllFromTable<Speaker>("speakers.db");
//get only the international spakers
internationalSpeakers = allSpeakers.Where(x => x.Nationality.Equals("international")).ToList();
//get only the national speakers
nationalSpeakers = allSpeakers.Where(x => x.Nationality.Equals("national")).ToList();
RunOnUiThread(() =>
{
speakersRecyclerView = FindViewById<RecyclerView>(Resource.Id.speakersRecyclerView);
speakersLayoutManager = new LinearLayoutManager(this);
speakersRecyclerView.SetLayoutManager(speakersLayoutManager);
speakersAdapter = new SpeakersAdapter(internationalSpeakers);
speakersAdapter.ItemClick += OnItemClick;
speakersRecyclerView.SetAdapter(speakersAdapter);
loadingSpinner.Visibility = ViewStates.Gone;
});
});
internationalSpeakersTextView = FindViewById<TextView>(Resource.Id.internationalSpeakersTextView);
internationalSpeakersTextView.Click += delegate
{
//change TextViews's style when selected/not-selected
internationalSpeakersTextView.SetBackgroundResource(Resource.Drawable.textView_selected);
nationalSpeakersTextView.SetBackgroundResource(Resource.Drawable.textView_unselected);
LoadSpeakers(internationalSpeakers);
};
nationalSpeakersTextView = FindViewById<TextView>(Resource.Id.nationalSpeakersTextView);
nationalSpeakersTextView.Click += delegate
{
//change TextViews's style when selected/not-selected
nationalSpeakersTextView.SetBackgroundResource(Resource.Drawable.textView_selected);
internationalSpeakersTextView.SetBackgroundResource(Resource.Drawable.textView_unselected);
LoadSpeakers(nationalSpeakers);
};
}
If you want I can paste you the entire Ponentes Activity
SpeakersActivity.cs :
[Activity(Label = "SpeakersActivity", ScreenOrientation = ScreenOrientation.Portrait)]
public class SpeakersActivity : BaseActivity
{
TextView internationalSpeakersTextView;
TextView nationalSpeakersTextView;
RecyclerView speakersRecyclerView;
// Layout manager that lays out each card in the RecyclerView:
RecyclerView.LayoutManager speakersLayoutManager;
// Adapter that accesses the data set (speakers):
SpeakersAdapter speakersAdapter;
/// <summary>
/// List that contains all the speakers
/// </summary>
List<Speaker> allSpeakers;
/// <summary>
/// List that contains the international speakers
/// </summary>
List<Speaker> internationalSpeakers;
/// <summary>
/// List that contains the national speakers
/// </summary>
List<Speaker> nationalSpeakers;
ProgressBar loadingSpinner;
protected override async void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.SpeakersActivity);
Android.Widget.Toolbar toolbar = FindViewById<Android.Widget.Toolbar>(Resource.Id.toolbar);
toolbar.NavigationOnClick += delegate
{
this.OnBackPressed();
};
loadingSpinner = FindViewById<ProgressBar>(Resource.Id.loadingSpinner);
loadingSpinner.Visibility = ViewStates.Visible;
await Task.Run(() =>
{
//get all the speakers from the db
allSpeakers = GetAllSpeakers();
//get only the international spakers
internationalSpeakers = allSpeakers.Where(x => x.Nationality.Equals("international")).ToList();
//get only the national speakers
nationalSpeakers = allSpeakers.Where(x => x.Nationality.Equals("national")).ToList();
RunOnUiThread(() =>
{
speakersRecyclerView = FindViewById<RecyclerView>(Resource.Id.speakersRecyclerView);
speakersLayoutManager = new LinearLayoutManager(this);
speakersRecyclerView.SetLayoutManager(speakersLayoutManager);
LoadSpeakers(internationalSpeakers);
loadingSpinner.Visibility = ViewStates.Gone;
});
});
internationalSpeakersTextView = FindViewById<TextView>(Resource.Id.internationalSpeakersTextView);
internationalSpeakersTextView.Click += delegate
{
//change TextViews's style when selected/not-selected
internationalSpeakersTextView.SetBackgroundResource(Resource.Drawable.textView_selected);
nationalSpeakersTextView.SetBackgroundResource(Resource.Drawable.textView_unselected);
LoadSpeakers(internationalSpeakers);
};
nationalSpeakersTextView = FindViewById<TextView>(Resource.Id.nationalSpeakersTextView);
nationalSpeakersTextView.Click += delegate
{
//change TextViews's style when selected/not-selected
nationalSpeakersTextView.SetBackgroundResource(Resource.Drawable.textView_selected);
internationalSpeakersTextView.SetBackgroundResource(Resource.Drawable.textView_unselected);
LoadSpeakers(nationalSpeakers);
};
}
/// <summary>
/// Load speakers inside activity
/// </summary>
/// <param name="speakers">speakers</param>
private void LoadSpeakers(List<Speaker> speakers)
{
speakersAdapter = new SpeakersAdapter(speakers);
speakersAdapter.ItemClick += OnItemClick;
speakersRecyclerView.SetAdapter(speakersAdapter);
}
private void OnItemClick(object sender, string speakerResumeUrl)
{
var speakerDetailsActivity = new Intent(this, typeof(SpeakerDetailsActivity));
speakerDetailsActivity.PutExtra("speakerResumeUrl", speakerResumeUrl);
StartActivity(speakerDetailsActivity);
}
public override void OnBackPressed()
{
StartActivity(typeof(CongressActivity));
Finish();
}
private List<Speaker> GetAllSpeakers()
{
System.Threading.Thread.Sleep(4000);
List<Speaker> speakers = new List<Speaker>();
speakers.Add(new Speaker { Photo = "https://i.imgur.com/DDH2Ckk.png", Name = "Anne-Maree Keenan", Resume = "https://51congresopodologia.com/?page_id=4004", Nationality = "international" });
speakers.Add(new Speaker { Photo = "https://i.imgur.com/DDH2Ckk.png", Name = "Anthony Redmond", Resume = "https://51congresopodologia.com/?page_id=4004", Nationality = "international" });
speakers.Add(new Speaker { Photo = "https://i.imgur.com/DDH2Ckk.png", Name = "Chris Nester", Resume = "https://51congresopodologia.com/?page_id=4004", Nationality = "national" });
speakers.Add(new Speaker { Photo = "https://i.imgur.com/DDH2Ckk.png", Name = "Amol Saxena", Resume = "https://51congresopodologia.com/?page_id=4004", Nationality = "international" });
return speakers;
}
}
SpeakersActivity.axml :
<?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="match_parent"
android:weightSum="100">
<Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:background="#color/appColor"
android:navigationIcon="#drawable/ic_toolbar_back_button">
<TextView
android:text="Ponentes"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"/>
</Toolbar>
<LinearLayout
android:orientation="horizontal"
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="match_parent"
android:layout_height="0dp"
android:weightSum="100"
android:layout_weight="10">
<TextView
android:text="Internacionales"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="0dp"
android:layout_height="match_parent"
android:id="#+id/internationalSpeakersTextView"
android:layout_weight="50"
android:gravity="center"
android:background="#drawable/textView_selected"/>
<TextView
android:text="Nacionales"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="0dp"
android:layout_height="match_parent"
android:id="#+id/nationalSpeakersTextView"
android:layout_weight="50"
android:gravity="center"
android:background="#drawable/textView_unselected"/>
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="#+id/speakersRecyclerView"
android:layout_weight="90"/>
<ProgressBar
android:id = "#+id/loadingSpinner"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:gravity="center"/>
<!--android:indeterminateDrawable="#drawable/animdraw"-->
</LinearLayout>
SpeakersAdapter.cs :
public class SpeakersAdapter : RecyclerView.Adapter
{
public event EventHandler<string> ItemClick;
public List<Speaker> listOfSpeakers;
public SpeakersAdapter(List<Speaker> speakers)
{
listOfSpeakers = speakers;
}
public override int ItemCount
{
get { return listOfSpeakers.Count; }
}
void OnClick(int position)
{
if (ItemClick != null)
ItemClick(this, listOfSpeakers[position].Resume);
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
SpeakerViewHolder vh = holder as SpeakerViewHolder;
var imageBitmap = GetImageBitmapFromUrl(listOfSpeakers[position].Photo);
vh.speakerPhotoImageView.SetImageBitmap(imageBitmap);
vh.speakerNameTextView.Text = listOfSpeakers[position].Name;
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.From(parent.Context).
Inflate(Resource.Layout.SpeakerCardView, parent, false);
SpeakerViewHolder vh = new SpeakerViewHolder(itemView, OnClick);
return vh;
}
private Bitmap GetImageBitmapFromUrl(string url)
{
Bitmap imageBitmap = null;
using (var webClient = new WebClient())
{
var imageBytes = webClient.DownloadData(url);
if (imageBytes != null && imageBytes.Length > 0)
{
imageBitmap = BitmapFactory.DecodeByteArray(imageBytes, 0, imageBytes.Length);
}
}
return imageBitmap;
}
}
SpeakerViewHolder.cs :
public class SpeakerViewHolder : RecyclerView.ViewHolder
{
public ImageView speakerPhotoImageView { get; private set; }
public TextView speakerNameTextView { get; private set; }
public TextView speakerResumeTextView { get; private set; }
// Get references to the views defined in the CardView layout.
public SpeakerViewHolder(View itemView, Action<int> listener)
: base(itemView)
{
// Locate and cache view references:
speakerPhotoImageView = itemView.FindViewById<ImageView>(Resource.Id.speakerPhotoImageView);
speakerNameTextView = itemView.FindViewById<TextView>(Resource.Id.speakerNameTextView);
// Detect user clicks on the item view and report which item
// was clicked (by layout position) to the listener:
itemView.Click += (sender, e) => listener(base.LayoutPosition);
}
}
textView_selected.xml :
<?xml version="1.0" encoding="utf-8" ?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#6495ED" />
<stroke
android:width="1dp"
android:color="#DCDCDC" />
</shape>
textView_unselected.xml :
<?xml version="1.0" encoding="utf-8" ?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<stroke
android:width="1dp"
android:color="#DCDCDC" />
</shape>
I've put System.Threading.Thread.Sleep(4000); in the GetAllSpeakers method in SpeakersActivity in order to imitate the delay when I get the records from a real database. Tell me if I am missing some file.

webview overlaps appbar in Xamarin Android app

i am using xamarin android app template with drawerlayout.i am using webview in app_bar_main.axml. when the activity is launched .it overlaps the appbar and does not show toolbar.my app_bar_main.axml is as follows: i want to show webview but below appbar.the webview is below toolbar but contents of toolbar are hidden.i want contents of toolbar so that i can navigate through toolbar in appbar .app_bar_main.axml .
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/appBarLayout"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<ProgressBar
android:id="#+id/progressBar"
android:layout_below="#id/toolbar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v4.widget.NestedScrollView
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"
android:layout_gravity="fill_vertical"
android:layout_below="#id/progressBar"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<WebView
android:id="#+id/StoreView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
app:srcCompat="#android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
the MainActivity.cs code is here.
the app_bar_main.axml is in activity_main.axml as produced by drawerlayout template.
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.activity_main);
Android.Support.V7.Widget.Toolbar toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
FloatingActionButton fab = FindViewById<FloatingActionButton>(Resource.Id.fab);
fab.Click += FabOnClick;
DrawerLayout drawer = FindViewById<DrawerLayout>(Resource.Id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, Resource.String.navigation_drawer_open, Resource.String.navigation_drawer_close);
drawer.AddDrawerListener(toggle);
toggle.SyncState();
NavigationView navigationView = FindViewById<NavigationView>(Resource.Id.nav_view);
navigationView.SetNavigationItemSelectedListener(this);
// start store activity
if (IsOnline() == true)
{
message = "items";
var intent = new Intent(this, typeof(StoreActivity));
intent.PutExtra("Data", "message");
StartActivity(intent);
}
}
```
Here is a simple demo which achieve your function.The main code is as follows:
The activity_main.axml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:fitsSystemWindows="true"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:background="#33B86C"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:layout_scrollFlags="scroll|enterAlways" />
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:layout_width="match_parent">
<FrameLayout
android:background="#android:color/holo_purple"
android:id="#+id/content_frame"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_height="match_parent"
android:layout_width="200dp"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="#menu/menu" />
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
MainActivity.cs
public class MainActivity : AppCompatActivity
{
DrawerLayout drawer;
NavigationView navigationView;
private string mDrawerTitle;
private string[] mContentTitles;
Toolbar toolbar;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
mDrawerTitle = this.Title;
mContentTitles= this.Resources.GetStringArray(Resource.Array.contents_array);
toolbar = FindViewById<Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
SupportActionBar.SetDisplayHomeAsUpEnabled(true);
SupportActionBar.SetDisplayShowTitleEnabled(false);
SupportActionBar.SetHomeButtonEnabled(true);
SupportActionBar.SetHomeAsUpIndicator(Resource.Drawable.ic_menu);
// Get our button from the layout resource,
// and attach an event to it
drawer = FindViewById<DrawerLayout>(Resource.Id.drawer_layout);
navigationView = FindViewById<NavigationView>(Resource.Id.nav_view);
if (navigationView != null)
setupDrawerContent(navigationView);
ActionBarDrawerToggle toggle = new MyActionBarDrawerToggle(this, drawer, toolbar, Resource.String.drawer_open, Resource.String.drawer_close);
drawer.AddDrawerListener(toggle);
toggle.SyncState();
if (savedInstanceState == null) //first launch
{
toolbar.Title = mContentTitles[0];
var fragment = WebviewFragment.NewInstance(0);
var fragmentManager = this.FragmentManager;
var ft = fragmentManager.BeginTransaction();
ft.Replace(Resource.Id.content_frame, fragment);
ft.Commit();
}
}
void setupDrawerContent(NavigationView navigationView)
{
navigationView.NavigationItemSelected += (sender, e) => {
int ItemId = e.MenuItem.ItemId;
e.MenuItem.SetChecked(true);
int index = 0;
if (ItemId == Resource.Id.nav_home) {
index = 0;
} else if (ItemId == Resource.Id.nav_messages) {
index = 1;
}
else if (ItemId == Resource.Id.nav_about)
{
index = 2;
}
// update the main content by replacing fragments
var fragment = WebviewFragment.NewInstance(index);
var fragmentManager = this.FragmentManager;
var ft = fragmentManager.BeginTransaction();
ft.Replace(Resource.Id.content_frame, fragment);
ft.Commit();
// update selected item title, then close the drawer
mDrawerTitle = mContentTitles[index];
drawer.CloseDrawers();
};
}
internal class WebviewFragment : Fragment
{
public const string ARG_NUMBER = "planet_number";
public WebviewFragment()
{
// Empty constructor required for fragment subclasses
}
public static Fragment NewInstance(int position)
{
Fragment fragment = new WebviewFragment();
Bundle args = new Bundle();
args.PutInt(WebviewFragment.ARG_NUMBER, position);
fragment.Arguments = args;
return fragment;
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View rootView = inflater.Inflate(Resource.Layout.fragment_content2, container, false);
var i = this.Arguments.GetInt(ARG_NUMBER);
var url = this.Resources.GetStringArray(Resource.Array.weburls_array)[i];
var title = this.Resources.GetStringArray(Resource.Array.contents_array)[i];
var web_view = rootView.FindViewById<WebView>(Resource.Id.webview);
web_view.Settings.JavaScriptEnabled = true;
web_view.SetWebViewClient(new HelloWebViewClient());
web_view.LoadUrl(url);
this.Activity.Title = title;
return rootView;
}
}
internal class MyActionBarDrawerToggle : ActionBarDrawerToggle
{
MainActivity owner;
public MyActionBarDrawerToggle(MainActivity activity, DrawerLayout layout, Toolbar toolbar, int openRes, int closeRes)
: base(activity, layout, toolbar, openRes, closeRes)
{
owner = activity;
}
public override void OnDrawerClosed(View drawerView)
{
owner.toolbar.Title = owner.Title;
owner.InvalidateOptionsMenu();
}
public override void OnDrawerOpened(View drawerView)
{
owner.toolbar.Title = owner.mDrawerTitle;
owner.InvalidateOptionsMenu();
}
}
}
strings.xml
<resources>
<string name="app_name">DrawLayoutApp</string>
<string name="action_settings">Settings</string>
<string name="drawer_open">Open navigation drawer</string>
<string name="drawer_close">Close navigation drawer</string>
<string-array name="contents_array">
<item>Home</item>
<item>Messages</item>
<item>About</item>
</string-array>
<string-array name="weburls_array">
<item>https://www.google.com/</item>
<item>https://msdn.itellyou.cn/</item>
<item>https://www.baidu.com/</item>
</string-array>
</resources>
menu.xml
<?xml version="1.0" encoding="utf-8" ?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_home"
android:title="Home" />
<item
android:id="#+id/nav_messages"
android:title="Messages" />
<item
android:id="#+id/nav_about"
android:title="About" />
</group>
</menu>
The effect is as follows:

RecyclerView in Fragment of ViewPager results in InflateException

I have a TabLayout with Fragments. In one of the Fragments, I want to add a RecyclerView. I have implemented the code for it and deployed it, but when I start the app I get the following error at tabLayout.SetupWithViewPager(viewPager):
Android.Views.InflateException: Binary XML file line #15: android.support.v7.widget.AppCompatTextView cannot be cast to android.widget.Button
and sometimes just
Android.Views.InflateException: Timeout exceeded getting exception details
I tried to copy the same code for the RecyclerView in a new Project but there just in the MainActivity and it worked. So I'm doing something else wrong...
My Code:
Main.axml:
<LinearLayout 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">
<android.support.design.widget.TabLayout
android:id="#+id/tablayout_navigation"
android:layout_width="match_parent"
app:tabTextColor="#ffffff"
app:tabSelectedTextColor="#08aeab"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="?attr/colorPrimary"
android:elevation="4dp" />
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_margin="0dp" />
</LinearLayout>
Overview.axml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal|center_vertical"
android:minWidth="25px"
android:minHeight="25px">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
AppointmentListItem.axml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:text="Name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/txtName"
android:textColor="#fff"/>
</LinearLayout>
RecyclerAdapter.cs:
class RecyclerAdapter : RecyclerView.Adapter
{
private List<Appointment> mAppointments;
public RecyclerAdapter(List<Appointment> appointments)
{
mAppointments = appointments;
}
public class MyView : RecyclerView.ViewHolder
{
public View mMainView { get; set; }
public TextView mName { get; set; }
public MyView(View view) : base(view)
{
mMainView = view;
}
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
View row = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.AppointmentListItem, parent, false);
TextView txtName = row.FindViewById<TextView>(Resource.Id.txtName);
MyView view = new MyView(row) { mName = txtName };
return view;
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
MyView myHolder = holder as MyView;
myHolder.mName.Text = mAppointments[position].Name;
}
public override int ItemCount
{
get { return mAppointments.Count; }
}
}
OverviewFragment.cs
class OverviewFragment : Android.Support.V4.App.Fragment
{
private RecyclerView mRecyclerView;
private RecyclerView.LayoutManager mLayoutManager;
private RecyclerView.Adapter mAdapter;
private List<Appointment> mAppointments;
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Use this to return your custom view for this Fragment
View view = inflater.Inflate(Resource.Layout.Overview, container, false);
mAppointments = new List<Appointment>();
mAppointments.Add(new Appointment("Test1"));
mAppointments.Add(new Appointment("Test2"));
mAppointments.Add(new Appointment("Test3"));
mAppointments.Add(new Appointment("Test4"));
mRecyclerView = view.FindViewById<RecyclerView>(Resource.Id.recyclerView);
mLayoutManager = new LinearLayoutManager(view.Context);
mRecyclerView.SetLayoutManager(mLayoutManager);
mAdapter = new RecyclerAdapter(mAppointments);
mRecyclerView.SetAdapter(mAdapter);
return view;
}
}
MainActivity.cs:
public class MainActivity : AppCompatActivity
{
private TabLayout tabLayout;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Main);
tabLayout = FindViewById<TabLayout>(Resource.Id.tablayout_navigation);
ViewPager viewPager = FindViewById<ViewPager>(Resource.Id.pager);
SetupViewPager(viewPager);
tabLayout.SetupWithViewPager(viewPager);
}
private void SetupViewPager(ViewPager viewPager)
{
viewPager.OffscreenPageLimit = 3;
PageAdapter adapter = new PageAdapter(SupportFragmentManager);
adapter.AddFragment(new OverviewFragment(), Resources.GetString(Resource.String.overview));
adapter.AddFragment(new CalendarFragment(), Resources.GetString(Resource.String.calendar));
adapter.AddFragment(new SharesFragment(), Resources.GetString(Resource.String.share));
viewPager.Adapter = adapter;
}
}

Can't set the textview in the navigation drawer using navigation view in main activity. Xamarin Android

This is the main activity where I am setting all the icons, menu, drawer and my navigation view. Here I set another view by inflating nav_header into the view and set the textview but I still can't seem to change the textview in the navigation drawer.
MainActivity
using Android.App;
using Android.Content.PM;
using Android.OS;
using Android.Support.V4.Widget;
using Android.Views;
using RoutineApp.Fragments;
using Android.Support.V7.App;
using Android.Support.V4.View;
using Android.Support.Design.Widget;
using Android.Widget;
using Android.Content;
namespace RoutineApp
{
[Activity(Label = "#string/app_name", MainLauncher = true, LaunchMode = LaunchMode.SingleTop)]
public class MainActivity : AppCompatActivity
{
DrawerLayout drawerLayout;
NavigationView navigationView;
IMenuItem previousItem;
TextView UserNameTxt;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.main);
var toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
if (toolbar != null)
{
SetSupportActionBar(toolbar);
SupportActionBar.SetDisplayHomeAsUpEnabled(true);
SupportActionBar.SetHomeButtonEnabled(true);
}
drawerLayout = FindViewById<DrawerLayout>(Resource.Id.drawer_layout);
SupportActionBar.SetHomeAsUpIndicator(Resource.Drawable.ic_menu);
navigationView = FindViewById<NavigationView>(Resource.Id.nav_view);
LayoutInflater inflater = (LayoutInflater)GetSystemService(Context.LayoutInflaterService);
View view = inflater.Inflate(Resource.Layout.nav_header, null);
UserNameTxt = view.FindViewById<TextView>(Resource.Id.UserNameTxt);
UserNameTxt.Text = "Yousuf";
navigationView.NavigationItemSelected += (sender, e) =>
{
if (previousItem != null)
previousItem.SetChecked(false);
navigationView.SetCheckedItem(e.MenuItem.ItemId);
previousItem = e.MenuItem;
switch (e.MenuItem.ItemId)
{
case Resource.Id.nav_home_1:
ListItemClicked(0);
break;
case Resource.Id.nav_home_2:
ListItemClicked(1);
break;
}
drawerLayout.CloseDrawers();
};
if (savedInstanceState == null)
{
navigationView.SetCheckedItem(Resource.Id.nav_home_1);
ListItemClicked(0);
}
}
int oldPosition = -1;
private void ListItemClicked(int position)
{
if (position == oldPosition)
return;
oldPosition = position;
Fragment fragment = null;
switch (position)
{
case 0:
fragment = Fragment1.NewInstance();
break;
}
FragmentTransaction fragmentTx = this.FragmentManager.BeginTransaction();
fragmentTx.Replace(Resource.Id.content_frame, fragment);
fragmentTx.AddToBackStack(null);
fragmentTx.Commit();
}
public override bool OnOptionsItemSelected(IMenuItem item)
{
switch (item.ItemId)
{
case Android.Resource.Id.Home:
drawerLayout.OpenDrawer(GravityCompat.Start);
return true;
}
return base.OnOptionsItemSelected(item);
}
}
}
This is the main layout axml where the navigation and drawer are set the header is called in the navigation.
main.axml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<!-- The main content view -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar"
app:layout_scrollFlags="scroll|enterAlways" />
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/toolbar_layout" />
</RelativeLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header"
app:menu="#menu/nav_menu" />
</android.support.v4.widget.DrawerLayout>
This is my the nav_header which I have called in the navigation view, which contains the textview which I'm trying to change on main activity.
nav_header.axml
<TextView
android:id="#+id/UserNameTxt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Username"
android:textAppearance="#style/TextAppearance.AppCompat.Body1" />
</LinearLayout>
The name doesn't change, please help.
You use LayoutInflator to inflate a view from nav_header, which means you created a total new View from nav_header.xml and changed it's sub textview's text and didn't use this new view in your activity. Thus the text of your original activity won't change.
solution:
Modify your activity codes like this:
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.main);
var toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
if (toolbar != null)
{
SetSupportActionBar(toolbar);
SupportActionBar.SetDisplayHomeAsUpEnabled(true);
SupportActionBar.SetHomeButtonEnabled(true);
}
drawerLayout = FindViewById<DrawerLayout>(Resource.Id.drawer_layout); SupportActionBar.SetHomeAsUpIndicator(Resource.Drawable.ic_menu);
navigationView = FindViewById<NavigationView>(Resource.Id.nav_view);
//LayoutInflater inflater = (LayoutInflater)GetSystemService(Context.LayoutInflaterService);
//View view = inflater.Inflate(Resource.Layout.nav_header, null);
//UserNameTxt = view.FindViewById<TextView>(Resource.Id.UserNameTxt);
//UserNameTxt.Text = "Yousuf";
LinearLayout header=(LinearLayout)navigationView.GetHeaderView(0);
UserNameTxt = header.FindViewById<TextView>(Resource.Id.UserNameTxt);
UserNameTxt.Text = "Yousuf";
...

Which is the best widget to display dynamic table with data in Xamarin.Android?

I have to display the following table:
So I want to know what is the best widget to use for the table. I want the table to be dynamic I mean if I choose some other group from the dropdown the number of items in the table to increase or to decrease and the total price to change depending on what I have in column price. What widget is the best widget to achieve that?
RecyclerView is the best UI control to achieve it. Because RecyclerView is Adapter pattern, so you can use the adapter to achieve dynamic what you have said.
I want the table to be dynamic I mean if I choose some other group from the dropdown the number of items in the table to increase or to decrease and the total price to change depending on what I have in column price
I have made a demo for you, you can test it and do some changes for your project:
Three .axml files:
Main.axml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Button
android:id="#+id/bt1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="group1"/>
<Button
android:id="#+id/bt2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="group2"/>
<Button
android:id="#+id/bt3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="group3"
/>
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
item_layout, every item's layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/item_tv"
android:layout_width="match_parent"
android:textSize="30dp"
android:layout_height="wrap_content" />
</LinearLayout>
item_layout, total price's layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/foot_tv"
android:gravity="end"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
MainActivity:
using Android.App;
using Android.Widget;
using Android.OS;
using System;
using System.Collections.Generic;
using Android.Support.V7.Widget;
using Android.Views;
using Android.Content;
namespace RecycleTest
{
[Activity(Label = "RecycleTest", MainLauncher = true)]
public class MainActivity : Activity
{
RecyclerView mRecyclerView;
MyAdapter adapter;
Button bt1, bt2, bt3;
List<double> list1, list2, list3;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
initView();
initData();
mRecyclerView = FindViewById<RecyclerView>(Resource.Id.rv);
mRecyclerView.SetLayoutManager(new LinearLayoutManager(this));
adapter = new MyAdapter(this, list1);
mRecyclerView.SetAdapter(adapter);
}
private void initData()
{
list1 = new List<double>();
list2 = new List<double>();
list3 = new List<double>();
list1.Add(1.1);
list1.Add(1.2);
list1.Add(1.3);
list2.Add(2.1);
list2.Add(2.2);
list2.Add(2.3);
list2.Add(2.4);
list3.Add(3.1);
list3.Add(3.2);
list3.Add(3.3);
list3.Add(3.4);
list3.Add(3.5);
}
public void initView() {
bt1 = FindViewById<Button>(Resource.Id.bt1);
bt2 = FindViewById<Button>(Resource.Id.bt2);
bt3 = FindViewById<Button>(Resource.Id.bt3);
bt1.Click += Bt1_Click;
bt2.Click += Bt2_Click;
bt3.Click += Bt3_Click;
}
private void Bt3_Click(object sender, System.EventArgs e)
{
adapter.change(list3);
}
private void Bt2_Click(object sender, System.EventArgs e)
{
adapter.change(list2);
}
private void Bt1_Click(object sender, System.EventArgs e)
{
adapter.change(list1);
}
}
class MyViewHolder : RecyclerView.ViewHolder
{
public TextView mtv;
public MyViewHolder(View itemView): base(itemView)
{
mtv = itemView.FindViewById<TextView>(Resource.Id.item_tv);
}
}
class MyFootViewHolder : RecyclerView.ViewHolder
{
public TextView mtv;
public MyFootViewHolder(View itemView):base(itemView)
{
mtv = itemView.FindViewById<TextView>(Resource.Id.foot_tv);
}
}
class MyAdapter :RecyclerView.Adapter{
Context mContext;
List<double> mList=new List<double>();
public override int ItemCount => mList.Count + 1;
public MyAdapter(Context context, List<Double> list)
{
this.mContext = context;
this.mList.AddRange(list);
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
if (GetItemViewType(position) == 0)
{
((MyViewHolder)holder).mtv.Text=(mList[position].ToString());
}
else
{
double price = 0;
for (int i = 0; i < mList.Count; i++)
{
price += mList[i];
}
((MyFootViewHolder)holder).mtv.Text=price + "";
}
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
RecyclerView.ViewHolder holder;
if (viewType == 0)
{
holder = new MyViewHolder(LayoutInflater.From(mContext).Inflate(Resource.Layout.item_layout, parent, false));
}
else
{
holder = new MyFootViewHolder(LayoutInflater.From(mContext).Inflate(Resource.Layout.foot_layout, parent, false));
}
return holder;
}
public override int GetItemViewType(int position)
{
int type;
if (position != mList.Count)
{
type = 0;
}
else
{
type = 1;
}
return type;
}
public void change(List<Double> list1)
{
mList.Clear();
mList.AddRange(list1);
NotifyDataSetChanged();
}
}
}

Resources