Quantcast
Channel: Recent Threads — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 204402

Need help with expandable views in RecyclerView

$
0
0

Hello everyone,

Working on a small application that uses CardView in RecyclerView. Cardview has two layouts, main one with title and hidden one with item data. When user clicks on CardView that CardView is expanded and that hidden view holding data about selected item is shown to user. If user clicks on CardView again view is collapsed back to original position and so on like shown in picture below.

Hire is the basic code

Main Activity

[Activity(Label = "AppTypewriter", MainLauncher = true)]
    public class MainActivity : AppCompatActivity
    {
        RelativeLayout MainLayout;
        RelativeLayout HidenLayout;
        CardView cardView;
        Button btn1;
        Button btn2;
        Button StartAnimation;
        TextView lblText;
        List<string> podaci;
        RecyclerView mRecyclerView;
        RecyclerView.LayoutManager mLayoutManager;
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            SetContentView(Resource.Layout.Main);
            mRecyclerView = (RecyclerView)FindViewById(Resource.Id.recyclerView);
            podaci = new List<string>();
            podaci.Add("Podatak 1");
            podaci.Add("Podatak 2");
            podaci.Add("Podatak 3");
            podaci.Add("Podatak 4");
            podaci.Add("Podatak 5");
            podaci.Add("Podatak 6");
            podaci.Add("Podatak 7");
            podaci.Add("Podatak 8");
            podaci.Add("Podatak 9");
            podaci.Add("Podatak 10");
            podaci.Add("Podatak 11");
            podaci.Add("Podatak 12");
            mLayoutManager = new LinearLayoutManager(this);
            mRecyclerView.SetLayoutManager(mLayoutManager);
            MyRecyclerViewAdapter myRAdapter = new MyRecyclerViewAdapter(podaci);
            mRecyclerView.SetAdapter(myRAdapter);
        }

My RecyclerView Adapter

public class MyRecyclerViewAdapter : RecyclerView.Adapter
    {
        List<string> myData;
        public MyRecyclerViewAdapter(List<string> items)
        {
            myData = items;
        }
        public override int ItemCount
        {
            get
            {
                return myData.Count;
            }
        }
        public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
        {
            MyRecyclerViewHolder viewHolder = holder as MyRecyclerViewHolder;
            string s = (string)myData[position];
            viewHolder.lblText.Text = s;
            viewHolder.cardView.Click += (sender,e)=>
                {
                    if (viewHolder.LayoutPosition == position)
                    {
                        Animation animation = null;
                        if (viewHolder.HidenLayout.Visibility == ViewStates.Invisible)
                        {
                            animation = new MyAnimator(viewHolder.cardView, viewHolder.cardView.Height,
                                                                             viewHolder.cardView.Height + viewHolder.HidenLayout.Height);
                            viewHolder.HidenLayout.Visibility = ViewStates.Visible;
                            Console.WriteLine("Set visible");
                        }
                        else
                        {
                            animation = new MyAnimator(viewHolder.cardView, viewHolder.cardView.Height,
                                                                              (viewHolder.cardView.Height - viewHolder.HidenLayout.Height));
                            animation.AnimationEnd += delegate
                            {
                                viewHolder.HidenLayout.Visibility = ViewStates.Invisible;
                            };
                            Console.WriteLine("Set INvisible");
                        }
                        animation.Interpolator = new AccelerateInterpolator();
                        animation.Duration = 300;
                        viewHolder.cardView.Animation = animation;
                        viewHolder.cardView.StartAnimation(animation);
                        viewHolder.btn1.Click += delegate
                        {
                            myData.RemoveAt(position);
                            this.NotifyDataSetChanged();
                            Toast.MakeText(viewHolder.btn1.Context, "Obrisan je " + s, ToastLength.Short).Show();
                        };
                        viewHolder.btn2.Click += delegate
                        {
                            viewHolder.lblText.Text = "Ovo je novi dodani text u ovaj sadržaj";
                            viewHolder.lblText.SetTextColor(Color.DarkRed);
                        };
                    }
                };
        }
        public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
        {
            View itemView = LayoutInflater.From(parent.Context).
            Inflate(Resource.Layout.list_item, parent, false);
            MyRecyclerViewHolder vh = new MyRecyclerViewHolder(itemView);
            return vh;
        }
    }
    public class MyRecyclerViewHolder : RecyclerView.ViewHolder
    {
        public RelativeLayout MainLayout;
        public RelativeLayout HidenLayout;
        public CardView cardView;
        public Button btn1;
        public Button btn2;
        public TextView lblText;
        public MyRecyclerViewHolder(View itemView) : base(itemView)
        {
            MainLayout = (RelativeLayout)itemView.FindViewById(Resource.Id.MainLayoutList);
            HidenLayout = (RelativeLayout)itemView.FindViewById(Resource.Id.HiddenLayoutList);
            lblText = (TextView)itemView.FindViewById(Resource.Id.lblText);
            cardView = (CardView)itemView.FindViewById(Resource.Id.CardViewList);
            btn1 = (Button)itemView.FindViewById(Resource.Id.Btn1);
            btn2 = (Button)itemView.FindViewById(Resource.Id.btn2);
        }
    }

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.CardView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:background="@drawable/pressable_item_background"
        android:id="@+id/CardViewList"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:animateLayoutChanges="true"
        android:layout_margin="8dp">
        <RelativeLayout
            android:id="@+id/HiddenLayoutList"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:background="#f3f3f3"
            android:layout_marginTop="50dp"
            android:padding="6dp"
            android:visibility="invisible">
            <TextView
                android:id="@+id/lblText"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Ovo je sakriveni sadržaj koji se ne vidi" />
            <Button
                android:id="@+id/Btn1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:layout_alignParentBottom="true"
                style="@style/Widget.AppCompat.Button.Colored"
                android:text="Gumb 1"/>
            <Button
                android:id="@+id/btn2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:layout_alignParentBottom="true"
                android:layout_marginLeft="100dp"
                style="@style/Widget.AppCompat.Button.Colored"
                android:text="Gumb 2"/>
        </RelativeLayout>
        <RelativeLayout
            android:id="@+id/MainLayoutList"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:background="#ffffff">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Klikni za animaciju"
                android:padding="6dp"
                style="@style/Base.TextAppearance.AppCompat.Headline"/>
        </RelativeLayout>
    </android.support.v7.widget.CardView>

Now the result of this code is that it is working for Views in on the screen but as soon there is more items added to recyclerView and it enters a scroll it opens (expands) multiple random CardViews with the one that is clicked and that behaver is , I suspect, because of reuse of views in RecyclerView.

I tryed to add ItemClick EventHandler ass demonstrated in RecyclerView demo on Xamarin site - linkhttps://developer.xamarin.com/guides/android/user_interface/recyclerview/ but it didn't help. I am stil having same behavior. Then i tryed to add tags to views in OnBindViewHolder method

viewHolder.cardView.SetTag(Resource.Id.CardViewList, position);
viewHolder.HidenLayout.SetTag(Resource.Id.HiddenLayoutList, position);

So i can access this Views through ItemClick event in Main Activity like this

View view = mLayoutManager.FindViewByPosition(position);
var myCard = (CardView)view.FindViewById(Resource.Id.CardViewList);
var myHiddenLayout = (RelativeLayout)view.FindViewById(Resource.Id.HiddenLayoutList);
myHiddenLayout.FindViewWithTag(position);
myCard.FindViewWithTag(position);

I am stil having same behavior with opening random views alongside clicked one. So I am basically needing some help to figure out what is up with this and if this kind of thing could be even implemented plus I suspect i will be having similar issues with that buttons in hidden layout as well.

Thanks in advance
Ivan


Viewing all articles
Browse latest Browse all 204402

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>