Xamarin.Android
RecyclerView
수색…
RecyclerView 기본 사항
다음은 Android Support Library V7 RecyclerView
를 사용하는 예입니다. 지원 라이브러리는 일반적으로 새 기능의 이전 버전과 호환되는 버전을 제공하고 프레임 워크에 포함되지 않은 유용한 UI 요소를 제공하며 앱에서 그릴 수있는 다양한 유틸리티를 제공하므로 권장됩니다.
RecyclerView
를 받으려면 필요한 Nuget 패키지를 설치합니다. 먼저 v7 recyclerview
검색합니다. Xamarin Android Support Library - v7 RecyclerView
가 나타날 때까지 아래로 스크롤하십시오. 패키지를 선택하고 패키지 추가를 클릭 하십시오 .
또는 Android Support Library V7 RecyclerView
Xamarin 구성 요소로 사용할 수 있습니다. 구성 요소를 추가하려면, 마우스 오른쪽 버튼으로 클릭 한 Components
솔루션 탐색기에서 안드로이드 프로젝트 내에서 클릭 Get More Components
.
나타나는 Component Store 창에서 RecyclerView를 검색하십시오. 검색 목록에서 Android Support Library V7 RecyclerView
선택합니다. 그런 다음 Add to App
에 Add to App
클릭하십시오. 구성 요소가 프로젝트에 추가됩니다.
다음 단계는 RecyclerView를 페이지에 추가하는 것입니다. axml
(레이아웃) 파일 내에서 RecyclerView
를 아래와 같이 추가 할 수 있습니다.
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" />
RecyclerView는 Adapter
와 ViewHolder
기본 표준 구현을 위해 최소한 두 개의 헬퍼 클래스가 필요합니다. Adapter
는 항목 레이아웃을 확장하고 RecyclerView에 표시되는보기에 데이터를 바인딩합니다. ViewHolder는 뷰 참조를 검색하고 저장합니다. 또한보기 소유자는 항목보기 클릭 수를 감지하는 데 도움을줍니다.
다음은 어댑터 클래스의 기본 예제입니다.
public class MyAdapter : RecyclerView.Adapter
{
string [] items;
public MyAdapter (string [] data)
{
items = data;
}
// Create new views (invoked by the layout manager)
public override RecyclerView.ViewHolder OnCreateViewHolder (ViewGroup parent, int viewType)
{
// set the view's size, margins, paddings and layout parameters
var tv = new TextView (parent.Context);
tv.SetWidth (200);
tv.Text = "";
var vh = new MyViewHolder (tv);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
public override void OnBindViewHolder (RecyclerView.ViewHolder viewHolder, int position)
{
var item = items [position];
// Replace the contents of the view with that element
var holder = viewHolder as MyViewHolder;
holder.TextView.Text = items[position];
}
public override int ItemCount {
get {
return items.Length;
}
}
}
OnCreateViewHolder
메서드에서 먼저 View를 확장하고 ViewHolder 클래스의 인스턴스를 만듭니다. 이 인스턴스를 반환해야합니다. 이 메소드는 ViewHolder의 새 인스턴스가 필요할 때 어댑터에 의해 호출됩니다. 이 메서드는 모든 단일 셀에 대해 호출되지 않습니다. RecyclerView에 뷰를 채우기에 충분한 셀이 있으면 View에서 스크롤 된 이전 셀을 다음 셀로 다시 사용합니다.
OnBindViewHolder
콜백은 Adapter에 의해 호출되어 지정된 위치에 데이터를 표시합니다. 이 메소드는 itemView의 내용을 업데이트하여 지정된 위치의 항목을 반영해야합니다.
셀에는 단 하나의 TextView
만 있으므로 다음과 같이 간단한 ViewHolder를 가질 수 있습니다.
public class MyViewHolder : RecyclerView.ViewHolder
{
public TextView TextView { get; set; }
public MyViewHolder (TextView v) : base (v)
{
TextView = v;
}
}
다음 단계는 Activity
에서 일을 연결하는 것입니다.
RecyclerView mRecyclerView;
MyAdapter mAdapter;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SetContentView (Resource.Layout.Main);
mRecyclerView = FindViewById<RecyclerView> (Resource.Id.recyclerView);
// Plug in the linear layout manager:
var layoutManager = new LinearLayoutManager (this) { Orientation = LinearLayoutManager.Vertical };
mRecyclerView.SetLayoutManager (layoutManager);
mRecyclerView.HasFixedSize = true;
var recyclerViewData = GetData();
// Plug in my adapter:
mAdapter = new MyAdapter (recyclerViewData);
mRecyclerView.SetAdapter (mAdapter);
}
string[] GetData()
{
string[] data;
.
.
.
return data;
}
LayoutManager 클래스는 사용자가 더 이상 볼 수없는 항목보기를 언제 재사용 할 것인지에 대한 정책을 결정할뿐만 아니라 RecyclerView 내에서 항목보기를 측정하고 배치하는 일을 담당합니다. RecyclerView
를 사용하기 전에 ListView
를 사용하여 셀을 세로 스크롤 목록처럼 정렬하고 GridView
를 사용하여 항목을 2 차원의 스크롤 가능한 그리드로 표시해야했습니다. 그러나 이제는 다른 LayoutManger를 설정하여 RecyclerView로 두 가지를 모두 달성 할 수 있습니다. LinearLayoutManager
는 ListView처럼 셀을 정렬하고 GridLayoutManager
는 셀 그리드 방식으로 정렬합니다.
클릭 이벤트가있는 RecyclerView
이 예제는 Xamarin.Android RecyclerView에서 Click EventHandlers를 설정하는 방법을 보여줍니다.
Android Java 에서 클릭에 대한 수신기를 설정하는 방법은 다음과 같이 클릭 할보기에 대해 onClickListener를 사용하고 있습니다.
ImageView picture = findViewById(R.id.item_picture);
picture.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// do stuff
}
});
그러나 Xamarin.Android에서 Click 이벤트에 대한 수신기를 설정하는 방법은 다음과 같은 방법으로 EventHandler를 추가 하는 것입니다.
1.
ImageView picture = FindViewById<ImageView>(Resource.Id.item_picture);
picture.Click += delegate {
// do stuff
};
2.
ImageView picture = FindViewById<ImageView>(Resource.Id.item_picture);
picture.Click += async delegate {
// await DoAsyncMethod();
// do async stuff
};
삼.
ImageView picture = FindViewById<ImageView>(Resource.Id.item_picture);
picture.Click += Picture_Click;
... // rest of your method
private void Picture_Click(object sender, EventArgs e)
{
// do stuff
}
EventHandler가 추가되고 설정되지는 않습니다. Click EventHandler가 GridView / ListView 어댑터의 GetView 메서드 또는 RecyclerView.Adapter의 OnBindViewHolder 메서드에 추가되면 항목 뷰가 만들어 질 때마다 새 EventHandler가 추가됩니다. 여러 번 스크롤 한 후에 여러 EventHandler가 추가되고 뷰가 클릭되면 모든 이벤트가 실행됩니다.
이 문제를 피하려면 EventHandler를 GetView 또는 OnBindViewHolder 메서드에서 구독 취소하고 구독해야합니다. 또한, 그들은 EventHandler를 설정하기 위해 숫자 3 방법을 사용해야하며, 그렇지 않으면 EventHandler의 구독을 취소 할 수 없습니다.
Click 이벤트가있는 RecyclerView.Adapter의 예제는 다음과 같습니다.
public class ViewHolderPerson : Android.Support.V7.Widget.RecyclerView.ViewHolder
{
public View Item { get; private set; }
public ImageView Picture { get; private set; }
public TextView Name { get; private set; }
public ViewHolderPerson(View itemView) : base(itemView)
{
this.Item = itemView;
this.Picture = itemView.FindViewById<ImageView>(Resource.Id.Item_Person_Picture);
this.Name = itemView.FindViewById<TextView>(Resource.Id.Item_Person_Name);
}
}
public class AdapterPersons : Android.Support.V7.Widget.RecyclerView.Adapter
{
private Context context;
private Android.Support.V7.Widget.RecyclerView recyclerView;
private List<Person> persons;
public AdapterPersons(Context context, Android.Support.V7.Widget.RecyclerView recyclerView, List<Person> persons)
{
this.context = context;
this.recyclerView = recyclerView;
this.persons = persons;
}
public override int ItemCount => persons.Count;
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
Person person = this.persons[position];
((ViewHolderPerson)holder).Name.Text = person.Name;
((ViewHolderPerson)holder).Picture.SetImageBitmap(person.Picture);
// Unsubscribe and subscribe the method, to avoid setting multiple times.
((ViewHolderPerson)holder).Item.Click -= Person_Click;
((ViewHolderPerson)holder).Item.Click += Person_Click;
}
private void Person_Click(object sender, EventArgs e)
{
int position = this.recyclerView.GetChildAdapterPosition((View)sender);
Person personClicked = this.persons[position];
if(personClicked.Gender == Gender.Female)
{
Toast.MakeText(this.context, "The person clicked is a female!", ToastLength.Long).Show();
}
else if(personClicked.Gender == Gender.Male)
{
Toast.MakeText(this.context, "The person clicked is a male!", ToastLength.Long).Show();
}
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.item_person, parent, false);
return new ViewHolderPerson(itemView);
}
}