【问题标题】:Xamarin.Android: Changing a specific value in a list during runtimeXamarin.Android:在运行时更改列表中的特定值
【发布时间】:2019-02-01 15:45:17
【问题描述】:

我有一个简单的 Xamarin.Android-App。

在这个应用的Activity上,有一个列表显示。请参阅以下 MyActivity.axml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android        ="http://schemas.android.com/apk/res/android"
android:orientation  ="vertical"
android:layout_width ="match_parent"
android:layout_height="match_parent">
<Button
    android:layout_width ="match_parent"
    android:layout_height="wrap_content"
    android:text         ="Click Me"
    android:layout_marginTop   ="20dp"
    android:layout_marginLeft   ="25dp"
    android:layout_marginRight   ="25dp"
    android:id="@+id/button" />
<Space
    android:layout_width="match_parent"
    android:layout_height="25dp"
    android:id="@+id/space" />
<ListView
    android:minWidth="25px"
    android:minHeight="25px"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/list" />
</LinearLayout>

此列表的一行仅包含两个条目,请参阅 ListRow.axml:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
xmlns:android="http://schemas.android.com/apk/res/android"     
android:orientation="horizontal"     
android:layout_width="fill_parent"     
android:layout_height="fill_parent">        
    <TextView             
        android:id="@+id/name"            
        android:layout_width="wrap_content"          
        android:layout_height="wrap_content" 
        android:layout_marginLeft  ="5dp"
        android:layout_marginTop   ="10dp"
        android:layout_marginBottom="10dp"
        android:layout_marginRight ="5dp" />
    <TextView             
        android:id="@+id/value"            
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"
        android:layout_marginLeft  ="5dp"
        android:layout_marginTop   ="10dp"
        android:layout_marginBottom="10dp"
        android:layout_marginRight ="5dp" />
</RelativeLayout>

因此,该活动的代码隐藏如下所示:

public class MyActivity : Activity
{
    List<Entry> List = null;

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

        SetContentView(Resource.Layout.MyActivity);

        List = PopulateList();
        var lv = FindViewById<ListView>(Resource.Id.list);
        var adapter = new ListAdapter(this, Resource.Layout.List, List);
        lv.Adapter = adapter;

        FindViewById<Button>(Resource.Id.button).Click += OnButtonClick;
    }
}

为了完整起见,这里是我的 ListAdapter.cs-class 的代码:

class ListAdapter : ArrayAdapter
{
    List<Entry> List;
    public ListAdapter(Context Context, int ListId, List<Entry> List) : base(Context, ListId, List)
    {
        this.List = List;
    }
    public override int Count
    {
        get { return List.Count; }
    }
    public override View GetView(int position, View convertView, ViewGroup parent)
    {
        View v = convertView;
        if (v == null)
        {
            LayoutInflater inflater = (LayoutInflater)Context.GetSystemService(Context.LayoutInflaterService);
            v = inflater.Inflate(Resource.Layout.List, parent, false);
        }
        v.FindViewById<TextView>(Resource.Id.name).Text = List[position].Name;
        v.FindViewById<TextView>(Resource.Id.value).Text = "Original Value";
        return v;
    }
}

所以我现在的问题如下:假设该列表中有多个项目。单击按钮后,我想更改该列表中的一个特定文本。假设列表中的第二个条目(Resource.Id.value).Text(现在说“原始值”)到“更改值”或类似的东西。但仅限于第二个。所有其他项目应保持不变。

请看下面的输出示例,也许更容易理解我想要做什么:

名称  值
- - - - - - - - - - - - - - - --
No.1    原始价值
No.2    原值
No.3    原始价值

[按钮点击]

名称  值
- - - - - - - - - - - - - - - --
No.1    原始价值
No.2    更改值
No.3    原始价值

谁能帮助我/告诉我该怎么做?我的private void OnButtonClick(object sender, EventArgs e)-方法必须是什么样子?如何访问该列表中的单个条目?

提前感谢所有回答和问候

【问题讨论】:

  • 如果您的按钮在列表视图之外,您能否获得指示,例如当您单击 Clicked 事件时 Item 需要更改哪个位置?如果可以的话,你可以在适配器中定义一个方法,单击按钮通过适配器传递位置,然后刷新数据以更改该项的值。或者你可以给每个listitem添加一个按钮,然后点击按钮来改变对应item的值
  • 您好@LeoZhu,非常感谢您的帮助。正如试图在上面的两个表中显示的那样,在这个例子中,需要更改的项目的位置是int positionToChange = 1;(从 0 开始计数)。不是第一项,不是最后一项,只有第二项。如何通过适配器传递位置?
  • 你的意思是点击按钮后永远改变第二项的值吗?
  • 是的。至少现在是这样。

标签: list listview xamarin.android listadapter


【解决方案1】:

你可以在适配器中添加一个方法到notifyDataSetChanged();

class ListAdapter : ArrayAdapter
    {
      List<Entry> List;
      private int ItemPositionToChange = -1;
      public ListAdapter(Context Context, int ListId, List<Entry> List) : 
          base(Context, ListId, List)
        {
          this.List = List;
        }

      //this method to let adapter notify
      public void ChangeItemValue(int position)
        {
            ItemPositionToChange = position;
            NotifyDataSetChanged();
        }

      public override int Count
        {
          get { return List.Count; }
        }
      public override View GetView(int position, View convertView, ViewGroup parent)
        {
          View v = convertView;
          if (v == null)
            {
              LayoutInflater inflater = 
             (LayoutInflater)Context.GetSystemService(Context.LayoutInflaterService);
              v = inflater.Inflate(Resource.Layout.List, parent, false);
            }
              v.FindViewById<TextView>(Resource.Id.name).Text = List[position].Name;

              //change the item value according to your needs
              if(position == ItemPositionToChange ){
                v.FindViewById<TextView>(Resource.Id.value).Text = "Changed Value";
              }else{
                v.FindViewById<TextView>(Resource.Id.value).Text = "Original Value";
              }

              return v;
           }
    }

然后在你的按钮点击监听器:

void OnButtonClick(object sender, EventArgs e)
    {
       //positionToChange is which item you want to change
       adapter.ChangeItemValue(positionToChange);
    }

【讨论】:

    【解决方案2】:

    我对Entry类不太熟悉,但它似乎有一个Text属性。

    假设你知道字符串的索引(myIndex 下面):

    private void OnButtonClick(object sender, EventArgs e) {
        List[myIndex].Text = "Changed Value";
        adapter.notifyDataSetChanged();
    }
    

    【讨论】:

    • 詹姆斯您好,非常感谢您的回答。我很确定我们最后需要调用adapter.notifyDataSetChanged();,但不幸的是入口类没有文本属性(或者至少我不知道如何访问它)。如果我这样做 private void OnButtonClick(object sender, EventArgs e){FindViewById&lt;TextView&gt;(Resource.Id.pinTextView).Text = "Changed Value";} 只有第一项更改(而不是预期的第二项)。如果我添加 adapter.notifyDataSetChanged(); 这将停止并且单击按钮时不再发生任何事情。
    • 您不想在 OnButtonClick 中编辑 TextView 文本。适配器的重点是管理视图和 List 之间的交互。 ListAdapter 包含对此数据的引用,这是您应该更新的内容。单击后没有任何反应的原因是因为您没有更改列表中的数据。您使用的是这个 Entry 类吗?:docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/… 这是我的活动代码,使用 List 而不是 List,这应该会给您一个想法:pastebin.com/3XZ1MDh4
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-22
    • 2021-03-29
    • 2019-05-30
    • 2013-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多