Coming Soon!

Segera hadir Ebook Tutorial Xamarin Form Berbahasa Indonesia !!

- Sabtu, 29 Juli 2017

Tutorial Xamarin Android : CardView Material Design

Selamat pagi, diweekend ini saya sempatkan bereksperiment dengan CardView xamarin android, sebenarnya di website developer.xamarin.com sudah disediakan banyak tutorial, namun karena masih berbahasa inggris sehingga kita terkadang masih kesulitan untuk memahaminya. Oleh karena itu saya coba mempraktekannya dan saya ulas kembali dengan bahasa Indonesia. Demo CardView seperti berikut ini.

Langkah 1
Buatlah sebuah project dengan nama ListViewGambar pada Xamarin anda.

Langkah 2
Untuk membuat CardView kita harus menginstal Components antara lain adalah :

  1. Android Support Library v7 RecyclerView
  2. Android Support Library v7 CardView 
  3. Android Support Design Library
Langkah 3
Masukan gambar foto ini ke dalam folder Drawable, kalian bisa mendownload fotonya di sini, kemudia masukan ke folder drawable.

Langkah 4
Buka file Main.axml pada folder layout lalu ubah dengan code sebagai berikut

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <Button
        android:id="@+id/randPickButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Random Pick" />
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:scrollbars="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />
</LinearLayout>

Langkah 5
Buatlah sebuah Layout baru dengan nama PhotoCardView.axml dengan code sebagai berikut

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        card_view:cardElevation="4dp"
        card_view:cardUseCompatPadding="true"
        card_view:cardCornerRadius="5dp">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:padding="8dp">
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/imageView"
                android:scaleType="centerCrop" />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:textColor="#ffbdbdbd"
                android:text="Caption"
                android:id="@+id/textView"
                android:layout_gravity="center_horizontal"
                android:layout_marginLeft="4dp"
                android:textStyle="bold" />
        </LinearLayout>
    </android.support.v7.widget.CardView>
</FrameLayout>

Langkah 6
Buatlah sebuah class baru dengan nama PhotoAlbum.cs lalu masukan code berikut
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Android.Support.V7.Widget;
using System.Collections.Generic;

namespace ListViewGambar
{
	// Photo: contains image resource ID and caption:
	public class Photo
	{
		// Photo ID for this photo:
		public int mPhotoID;

		// Caption text for this photo:
		public string mCaption;

		// Return the ID of the photo:
		public int PhotoID
		{
			get { return mPhotoID; }
		}

		// Return the Caption of the photo:
		public string Caption
		{
			get { return mCaption; }
		}
	}

	// Photo album: holds image resource IDs and caption:
	public class PhotoAlbum
	{
		// Built-in photo collection - this could be replaced with
		// a photo database:

		static Photo[] mBuiltInPhotos = {
			new Photo { mPhotoID = Resource.Drawable.buckingham_guards,
						mCaption = "Buckingham Palace" },
			new Photo { mPhotoID = Resource.Drawable.la_tour_eiffel,
						mCaption = "The Eiffel Tower" },
			new Photo { mPhotoID = Resource.Drawable.louvre_1,
						mCaption = "The Louvre" },
			new Photo { mPhotoID = Resource.Drawable.before_mobile_phones,
						mCaption = "Before mobile phones" },
			new Photo { mPhotoID = Resource.Drawable.big_ben_1,
						mCaption = "Big Ben skyline" },
			new Photo { mPhotoID = Resource.Drawable.big_ben_2,
						mCaption = "Big Ben from below" },
			new Photo { mPhotoID = Resource.Drawable.london_eye,
						mCaption = "The London Eye" },
			new Photo { mPhotoID = Resource.Drawable.eurostar,
						mCaption = "Eurostar Train" },
			new Photo { mPhotoID = Resource.Drawable.arc_de_triomphe,
						mCaption = "Arc de Triomphe" },
			new Photo { mPhotoID = Resource.Drawable.louvre_2,
						mCaption = "Inside the Louvre" },
			new Photo { mPhotoID = Resource.Drawable.versailles_fountains,
						mCaption = "Versailles fountains" },
			new Photo { mPhotoID = Resource.Drawable.modest_accomodations,
						mCaption = "Modest accomodations" },
			new Photo { mPhotoID = Resource.Drawable.notre_dame,
						mCaption = "Notre Dame" },
			new Photo { mPhotoID = Resource.Drawable.inside_notre_dame,
						mCaption = "Inside Notre Dame" },
			new Photo { mPhotoID = Resource.Drawable.seine_river,
						mCaption = "The Seine" },
			new Photo { mPhotoID = Resource.Drawable.rue_cler,
						mCaption = "Rue Cler" },
			new Photo { mPhotoID = Resource.Drawable.champ_elysees,
						mCaption = "The Avenue des Champs-Elysees" },
			new Photo { mPhotoID = Resource.Drawable.seine_barge,
						mCaption = "Seine barge" },
			new Photo { mPhotoID = Resource.Drawable.versailles_gates,
						mCaption = "Gates of Versailles" },
			new Photo { mPhotoID = Resource.Drawable.edinburgh_castle_2,
						mCaption = "Edinburgh Castle" },
			new Photo { mPhotoID = Resource.Drawable.edinburgh_castle_1,
						mCaption = "Edinburgh Castle up close" },
			new Photo { mPhotoID = Resource.Drawable.old_meets_new,
						mCaption = "Old meets new" },
			new Photo { mPhotoID = Resource.Drawable.edinburgh_from_on_high,
						mCaption = "Edinburgh from on high" },
			new Photo { mPhotoID = Resource.Drawable.edinburgh_station,
						mCaption = "Edinburgh station" },
			new Photo { mPhotoID = Resource.Drawable.scott_monument,
						mCaption = "Scott Monument" },
			new Photo { mPhotoID = Resource.Drawable.view_from_holyrood_park,
						mCaption = "View from Holyrood Park" },
			new Photo { mPhotoID = Resource.Drawable.tower_of_london,
						mCaption = "Outside the Tower of London" },
			new Photo { mPhotoID = Resource.Drawable.tower_visitors,
						mCaption = "Tower of London visitors" },
			new Photo { mPhotoID = Resource.Drawable.one_o_clock_gun,
						mCaption = "One O'Clock Gun" },
			new Photo { mPhotoID = Resource.Drawable.victoria_albert,
						mCaption = "Victoria and Albert Museum" },
			new Photo { mPhotoID = Resource.Drawable.royal_mile,
						mCaption = "The Royal Mile" },
			new Photo { mPhotoID = Resource.Drawable.museum_and_castle,
						mCaption = "Edinburgh Museum and Castle" },
			new Photo { mPhotoID = Resource.Drawable.portcullis_gate,
						mCaption = "Portcullis Gate" },
			new Photo { mPhotoID = Resource.Drawable.to_notre_dame,
						mCaption = "Left or right?" },
			new Photo { mPhotoID = Resource.Drawable.pompidou_centre,
						mCaption = "Pompidou Centre" },
			new Photo { mPhotoID = Resource.Drawable.heres_lookin_at_ya,
						mCaption = "Here's Lookin' at Ya!" },
			};

		// Array of photos that make up the album:
		private Photo[] mPhotos;

		// Random number generator for shuffling the photos:
		Random mRandom;

		// Create an instance copy of the built-in photo list and
		// create the random number generator:
		public PhotoAlbum()
		{
			mPhotos = mBuiltInPhotos;
			mRandom = new Random();
		}

		// Return the number of photos in the photo album:
		public int NumPhotos
		{
			get { return mPhotos.Length; }
		}

		// Indexer (read only) for accessing a photo:
		public Photo this[int i]
		{
			get { return mPhotos[i]; }
		}

		// Pick a random photo and swap it with the top:
		public int RandomSwap()
		{
			// Save the photo at the top:
			Photo tmpPhoto = mPhotos[0];

			// Generate a next random index between 1 and 
			// Length (noninclusive):
			int rnd = mRandom.Next(1, mPhotos.Length);

			// Exchange top photo with randomly-chosen photo:
			mPhotos[0] = mPhotos[rnd];
			mPhotos[rnd] = tmpPhoto;

			// Return the index of which photo was swapped with the top:
			return rnd;
		}

		// Shuffle the order of the photos:
		public void Shuffle()
		{
			// Use the Fisher-Yates shuffle algorithm:
			for (int idx = 0; idx < mPhotos.Length; ++idx)
			{
				// Save the photo at idx:
				Photo tmpPhoto = mPhotos[idx];

				// Generate a next random index between idx (inclusive) and 
				// Length (noninclusive):
				int rnd = mRandom.Next(idx, mPhotos.Length);

				// Exchange photo at idx with randomly-chosen (later) photo:
				mPhotos[idx] = mPhotos[rnd];
				mPhotos[rnd] = tmpPhoto;
			}
		}
	}
}


Langkah 7
Buatlah sebuah class ViewHolder dengan nama PhotoViewHolder.cs dengan code sebagai berikut

using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Android.Support.V7.Widget;
using System.Collections.Generic;

namespace ListViewGambar
{
	//----------------------------------------------------------------------
	// VIEW HOLDER

	// Implement the ViewHolder pattern: each ViewHolder holds references
	// to the UI components (ImageView and TextView) within the CardView 
	// that is displayed in a row of the RecyclerView:
	public class PhotoViewHolder : RecyclerView.ViewHolder
	{
		public ImageView Image { get; private set; }
		public TextView Caption { get; private set; }

		// Get references to the views defined in the CardView layout.
		public PhotoViewHolder(View itemView, Action listener): base(itemView)
		{
			// Locate and cache view references:
			Image = itemView.FindViewById(Resource.Id.imageView);
			Caption = itemView.FindViewById(Resource.Id.textView);

			// Detect user clicks on the item view and report which item
			// was clicked (by position) to the listener:
			itemView.Click += (sender, e) => listener(base.Position);
		}
	}
}


Langkah 8
Buatlah sebuah class Adapter dengan nama PhotoAlbumAdapter.cs dengan code sebagai berikut

using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Android.Support.V7.Widget;
using System.Collections.Generic;

namespace ListViewGambar
{
	//----------------------------------------------------------------------
	// ADAPTER
	// Adapter to connect the data set (photo album) to the RecyclerView: 
	public class PhotoAlbumAdapter : RecyclerView.Adapter
	{
		// Event handler for item clicks:
		public event EventHandler ItemClick;

		// Underlying data set (a photo album):
		public PhotoAlbum mPhotoAlbum;

		// Load the adapter with the data set (photo album) at construction time:
		public PhotoAlbumAdapter(PhotoAlbum photoAlbum)
		{
			mPhotoAlbum = photoAlbum;
		}

		// Create a new photo CardView (invoked by the layout manager): 
		public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
		{
			// Inflate the CardView for the photo:
			View itemView = LayoutInflater.From(parent.Context).
						Inflate(Resource.Layout.PhotoCardView, parent, false);

			// Create a ViewHolder to find and hold these view references, and 
			// register OnClick with the view holder:
			PhotoViewHolder vh = new PhotoViewHolder(itemView, OnClick);
			return vh;
		}

		// Fill in the contents of the photo card (invoked by the layout manager):
		public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
		{
			PhotoViewHolder vh = holder as PhotoViewHolder;

			// Set the ImageView and TextView in this ViewHolder's CardView 
			// from this position in the photo album:
			vh.Image.SetImageResource(mPhotoAlbum[position].PhotoID);
			vh.Caption.Text = mPhotoAlbum[position].Caption;
		}

		// Return the number of photos available in the photo album:
		public override int ItemCount
		{
			get { return mPhotoAlbum.NumPhotos; }
		}

		// Raise an event when the item-click takes place:
		void OnClick(int position)
		{
			if (ItemClick != null)
				ItemClick(this, position);
		}
	}
}

Langkah 9
Bukalah file MainActivity.cs dan modifikasi code sebagai berikut

using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Android.Support.V7.Widget;
using System.Collections.Generic;

namespace ListViewGambar
{
	[Activity(Label = "RecyclerViewer", MainLauncher = true ,Theme = "@android:style/Theme.Material.Light.DarkActionBar")]
	public class MainActivity : Activity
	{
		// RecyclerView instance that displays the photo album:
		RecyclerView mRecyclerView;

		// Layout manager that lays out each card in the RecyclerView:
		RecyclerView.LayoutManager mLayoutManager;

		// Adapter that accesses the data set (a photo album):
		PhotoAlbumAdapter mAdapter;

		// Photo album that is managed by the adapter:
		PhotoAlbum mPhotoAlbum;

		protected override void OnCreate(Bundle bundle)
		{
			base.OnCreate(bundle);

			// Instantiate the photo album:
			mPhotoAlbum = new PhotoAlbum();

			// Set our view from the "main" layout resource:
			SetContentView(Resource.Layout.Main);

			// Get our RecyclerView layout:
			mRecyclerView = FindViewById<RecyclerView>(Resource.Id.recyclerView);

			//............................................................
			// Layout Manager Setup:

			// Use the built-in linear layout manager:
			mLayoutManager = new LinearLayoutManager(this);

			// Or use the built-in grid layout manager (two horizontal rows):
			// mLayoutManager = new GridLayoutManager
			//        (this, 2, GridLayoutManager.Horizontal, false);

			// Plug the layout manager into the RecyclerView:
			mRecyclerView.SetLayoutManager(mLayoutManager);

			//............................................................
			// Adapter Setup:

			// Create an adapter for the RecyclerView, and pass it the
			// data set (the photo album) to manage:
			mAdapter = new PhotoAlbumAdapter(mPhotoAlbum);

			// Register the item click handler (below) with the adapter:
			mAdapter.ItemClick += OnItemClick;

			// Plug the adapter into the RecyclerView:
			mRecyclerView.SetAdapter(mAdapter);

			//............................................................
			// Random Pick Button:

			// Get the button for randomly swapping a photo:
			Button randomPickBtn = FindViewById<Button>(Resource.Id.randPickButton);

			// Handler for the Random Pick Button:
			randomPickBtn.Click += delegate
			{
				if (mPhotoAlbum != null)
				{
					// Randomly swap a photo with the top:
					int idx = mPhotoAlbum.RandomSwap();

					// Update the RecyclerView by notifying the adapter:
					// Notify that the top and a randomly-chosen photo has changed (swapped):
					mAdapter.NotifyItemChanged(0);
					mAdapter.NotifyItemChanged(idx);
				}
			};
		}

		// Handler for the item click event:
		void OnItemClick(object sender, int position)
		{
			// Display a toast that briefly shows the enumeration of the selected photo:
			int photoNum = position + 1;
			Toast.MakeText(this, "This is photo number " + photoNum, ToastLength.Short).Show();
		}
	}




}


Salam

Terimakasih