android xamarin中的listview和评级栏

时间:2015-08-12 10:54:25

标签: c# android xamarin

我有一个列表视图,每个项目都有一个文本视图和一个评级栏。 项目布局是:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:minHeight="50dp"
    android:orientation="horizontal">
  <TextView
      android:id="@+id/name"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:lineSpacingExtra="3dp"
      android:paddingRight="10dp"
      android:paddingTop="5dp"
      android:textColor="#ffffff"
      android:textStyle="bold"
       android:textSize="15sp"
      android:typeface="sans"
       android:layout_alignParentRight="true"/>
  <RatingBar android:id="@+id/ratingbar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/name"

        android:numStars="5"
        android:stepSize="1.0"
             android:layout_alignParentLeft="true" />

</RelativeLayout>

这是我的ListAdapter的GetView方法:

public override View GetView(int position, View convertView, ViewGroup parent)
        {
            View view = convertView;

            RatingBar rate; 

            if (view == null)
                view = context.LayoutInflater.Inflate(Resource.Layout.QuestionListViewItemLayout, parent, false);
               // view = context.LayoutInflater.Inflate(Android.Resource.Layout.SimpleListItemActivated1, parent, false);

            question item = this[position];
            view.FindViewById<TextView>(Resource.Id.name).Text = item.text; 
            view.FindViewById<RatingBar>(Resource.Id.ratingbar).Rating = item.userrate;
            RatingBar rb = view.FindViewById<RatingBar>(Resource.Id.ratingbar);

            rb.RatingBarChange += (o, e) =>
            {
                item.userrate = System.Convert.ToInt32( e.Rating);
            };
            //view.FindViewById<TextView>(Resource.Id.SanadNumber).Text = item.sanadNumber.ToString();


            return view;
        }

在第:&#34; rb.RatingBarChange&#34;当我在列表视图中更改其中一个评级栏时,其他一些项目也会发生变化。每次我为我的一个评级栏设置评级时,委托执行mor的次数超过一次。

所以当我读到&#34; item.userrate&#34;由评级栏编辑,没有正确答案。

2 个答案:

答案 0 :(得分:1)

每次GetView运行时,都会为事件RatingBarChange创建一个新的事件处理程序,它会在当前“问题”(项目)实例周围创建一个闭包(有效地将每个项目实例保存在内存中并绑定到每个事件处理程序实例)。所有这些事件处理程序将每次触发并使用相同的值更新每个不同的项目实例。

您的RatingBarChange事件应该有一个处理程序来获取所选项目并应用评级。

答案 1 :(得分:1)

我想在列表视图中列出问题列表。 问题类是这样的:

public  class question
    {
        public int id { get; set; }
        public string text { get; set; }
        public int questionorder { get; set; }
        public int userrate { get; set; }

        public question()
        {
            userrate = 0;

        }

    }

现在我需要一个“QuestionListViewItemLayout.axml”文件来为我的列表视图设置样式:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:minHeight="50dp"
    android:orientation="horizontal">
  <TextView
      android:id="@+id/name"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:lineSpacingExtra="3dp"
      android:paddingRight="10dp"
      android:paddingTop="5dp"
      android:textColor="#ffffff"
      android:textStyle="bold"
       android:textSize="15sp"
      android:typeface="sans"now 
       android:layout_alignParentRight="true"/>
  <RatingBar android:id="@+id/ratingbar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/name"

        android:numStars="5"
        android:stepSize="1.0"
             android:layout_alignParentLeft="true" />

</RelativeLayout>

现在我需要一个ListAdapter来管理List视图中的Items,但首先我必须创建一个Wrapper类来保存视图:

 public class ViewWrapper : Java.Lang.Object
    {
        View base1;
        RatingBar rate = null;
        TextView label = null;

      public  ViewWrapper(View base1)
        {
            this.base1 = base1;
        }

      public  RatingBar getRatingBar()
        {
            if (rate == null)
            {
                rate = base1.FindViewById<RatingBar>(Resource.Id.ratingbar);
            }

            return (rate);
        }

       public TextView getLabel()
        {
            if (label == null)
            {
                label = base1.FindViewById<TextView>(Resource.Id.name);
            }

            return (label);
        }
    }

这个类只为我的问题类创建,也许你需要创建自己的包装器,类似于上面的代码

是时候创建List适配器类了:

public class QuestionListAdapter : BaseAdapter<question>
    {
        Activity context;
        List<question> list;
        public QuestionListAdapter(Activity _context, List<question> _list)
            : base()
        {
            this.context = _context;
            this.list = _list;
        }

        public override int Count
        {
            get { return list.Count; }
        }
        public override long GetItemId(int position)
        {
            return position;
        }
        public List<question> GetList()
        {
            return list;
        }
        public override question this[int index]
        {
            get { return list[index]; }
        }

        public override View GetView(int position, View convertView, ViewGroup parent)
        {
            View view = convertView;

            ViewWrapper wrapper;
            RatingBar rate;    

            question item = this[position];
            if (view == null)
            {
                view = context.LayoutInflater.Inflate(Resource.Layout.QuestionListViewItemLayout, parent, false);
                wrapper = new ViewWrapper(view);
                view.SetTag(Resource.Id.holder, wrapper);
                rate = wrapper.getRatingBar();

                rate.RatingBarChange += (o, e) =>
                {
                    RatingBar ratingBar = o as RatingBar;
                    int myPosition = (int)ratingBar.GetTag(Resource.Id.holder);
                    question model = list[myPosition];
                    model.userrate = System.Convert.ToInt32(e.Rating);
                };
            }
            else
            {

                wrapper = (ViewWrapper)view.GetTag(Resource.Id.holder);
                rate = wrapper.getRatingBar();

            }

            question model1 = list[position];

            wrapper.getLabel().Text = model1.text;
            rate.SetTag(Resource.Id.holder, position);
            rate.Rating = model1.userrate;

            return view;
        }

每次创建视图时,我都会为它创建一个包装器并将其放入视图的标签中 部分:[if(view == null)] 并设置一个评级栏率变化的事件。

其他时间视图加载我得到标签并设置评级栏的评级。