수색…


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 AppAdd 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는 AdapterViewHolder 기본 표준 구현을 위해 최소한 두 개의 헬퍼 클래스가 필요합니다. 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);
    }

}


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow