我已经为我的列表视图创建了一个自定义适配器,该适配器可扩展自定义视图,并允许用户过滤列表。

一切正常,但问题是我放置在列表视图项中的图标未遵循过滤的数据。



   

请注意,图标不会更改位置,但是名称已正确过滤。

这是完成自定义列表视图的我的自定义适配器

我正在使用Mono,所以它是用C#编写的,但希望您的Java专家也能够告诉我我在这里做什么...

/// <summary>
/// ArrayAdapter to handle displaying student with risk indicator
/// </summary>
private class StudentListAdapter : ArrayAdapter<Student>
{
    private IList<Student> items;
    private Context outer_context;

    public StudentListAdapter(Context context, int resource, int textViewResourceId, IList<Student> items)
        : base(context, resource, textViewResourceId, items)
    {
        this.items = items;
        this.outer_context = context;
    }

    public override View GetView(int position, View convertView, ViewGroup parent)
    {
        LayoutInflater vi = (LayoutInflater)outer_context.GetSystemService(Context.LayoutInflaterService);
        View tmpView = vi.Inflate(Resource.Layout.ItemStudent, null);

        // call base.GetView that uses Object.ToString() to keep sorting intact
        View v = base.GetView(position, tmpView, parent);

        Student s = items[position];
        if (s != null)
        {
            // determine correct risk image
            ImageView listRisk = v.FindViewById<ImageView>(Resource.Id.listRisk);
            if (s.R != null)
            {
                switch ((int)s.R.Value)
                {
                    case 1:
                        listRisk.SetImageResource(Resource.Drawable.risk_green);
                        break;
                    case 0:
                        listRisk.SetImageResource(Resource.Drawable.risk_yellow);
                        break;
                    case -1:
                        listRisk.SetImageResource(Resource.Drawable.risk_red);
                        break;
                    case -2:
                        listRisk.SetImageResource(Resource.Drawable.risk_red2);
                        break;
                    default:
                        listRisk.SetImageResource(Resource.Drawable.risk_gray);
                        break;
                }
            }
            else
            {
                listRisk.SetImageResource(Resource.Drawable.risk_gray);
            }
        }

        return v;
    }
}


更新

经过一些断点和检查后,我发现列表过滤时会在过滤之前重建整个列表

例如,当在过滤字段中键入字母时,通过GetView()进程运行的第一个学生(s)是Heath, Ackerson,它是列表中的第一个学生,即使过滤器与他不匹配也是如此。

因此,似乎在运行GetView之后进行了过滤,将图像保留在原位...仍然不确定如何修复它。

*完整解决方案*

http://jondavidjohn.com/blog/2011/08/android-custom-listview-filtering

最佳答案

我将执行以下操作:
将EditText和ListView放在您的布局中。
使用BaseAdapter而不是ArrayAdapter。其实是一样的,但是我不叫base.getView():

private class StudentListAdapter : BaseAdapter
{
    private IList<Student> items;
    private Context outer_context;

    public StudentListAdapter(Context context, IList<Student> items)
    {
        this.items = items;
        this.outer_context = context;
    }

    public override View GetView(int position, View convertView, ViewGroup parent)
    {
        LayoutInflater vi = (LayoutInflater)outer_context.GetSystemService(Context.LayoutInflaterService);
        View v = vi.Inflate(Resource.Layout.ItemStudent, null);

        Student s = items[position];

        v.FindViewById<TextView>(R.id.text_view_id).setText(s.Name);

        // determine correct risk image
        ImageView listRisk = v.FindViewById<ImageView>(Resource.Id.listRisk);
        if (s.R != null)
        {
            switch ((int)s.R.Value)
            {
                case 1:
                    listRisk.SetImageResource(Resource.Drawable.risk_green);
                    break;
                case 0:
                    listRisk.SetImageResource(Resource.Drawable.risk_yellow);
                    break;
                case -1:
                    listRisk.SetImageResource(Resource.Drawable.risk_red);
                    break;
                case -2:
                    listRisk.SetImageResource(Resource.Drawable.risk_red2);
                    break;
                default:
                    listRisk.SetImageResource(Resource.Drawable.risk_gray);
                    break;
            }
        }
        else
        {
            listRisk.SetImageResource(Resource.Drawable.risk_gray);
        }

        return v;
    }

    void displayNewData(IList<Student> new_items)
    {
        items=new_items;
        notifyDatasetChanged();
    }
}


因此,当更改过滤器文本时,您只需要使用displayNewData()方法将新数据放入适配器:

public class StudentsActivity extends Activity {

    public override void onCreate(Bundle savedInstanceState)
    {
        ...
        filterEditText.addTextChangedListener(filterTextWatcher);
    }

    private TextWatcher filterTextWatcher = new TextWatcher()
    {

        public void afterTextChanged(Editable s) {}
        public void beforeTextChanged(CharSequence s, int start, int count,int after) {}

        public void onTextChanged(CharSequence filter, int start, int before, int count)
        {
            IList<Student> items = getStudentsFiltered(filter);
            adapter.displayNewData(items);
        }
    };

    //getStudentsFiltered() method may look like that:
    getStudentsFiltered(String filter)
    {
        IList<Student> students_filtered=new List<Students>();
        foreach(Student student in students)
        if(student.Name.Contains(filter))
                students_filtered.Add(student);
        return students_filtered;
    }
}


我很确定这种方法会奏效。随意问任何问题。
我没有编译代码,因此可能存在一些小错误。

关于c# - ListView筛选器。图像不跟随筛选器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6833180/

10-16 10:04