0

AutoCompleteTextView lets users choose a string from a list of valid values. Like, I imagine, every developer who wants to use this yoke, I am much more interested in the id of the user's selection than its string label. Is there any way to retrieve the id property of a chosen object, or its index in the source array?

The following C# code let's users pick from a list of SomeObject. I'm working in Xamarin, but don't let this put you off. Fix my problem in java and I'll happily make it work in C#

public class AutoCompleteField : PhysicalField
{
    protected AutoCompleteTextView actv;
    public AutoCompleteField(IList<SomeObject> choices, LogicalField logical, string id)
        : base(logical, id) 
    {
        _choices = choices;
    }
    protected ArrayAdapter<SomeObject> _adapter;

    public override void addToView(LayoutInflater inflater)
    {
        var ctx = App_NotMobility.CurrentActivity;
        actv = new AutoCompleteTextView(ctx);
        actv.Id = _form.generateId();

        // test choices
        var _choices = new List<SomeObject>();
        _choices.Add(new SomeObject(234, "Oranges"));
        _choices.Add(new SomeObject(456, "Apples"));
        _choices.Add(new SomeObject(789, "Bananas"));

        _adapter = new ArrayAdapter<SomeObject>(ctx, Android.Resource.Layout.SimpleDropDownItem1Line, _choices);
        actv.Adapter = _adapter;
        actv.ItemClick += delegate(object sender, AdapterView.ItemClickEventArgs e)
        {
            // HOW DO I ACCESS THE ID OR THE INDEX OF USER'S SELECTION ?????????????????
        };
       _form.AddView(actv);  
    }
}
public class SomeObject
{
    public int Id { get; set; }
    public string Label { get; set; }
    public SomeObject(int id, string label)
    {
        Id = id;
        Label = label;
    }
    public override string ToString()
    {
        return Label;
    }
}
bbsimonbb
  • 27,056
  • 15
  • 80
  • 110
  • see `android.widget.AdapterView.OnItemClickListener#onItemClick` documentation – pskink Oct 12 '15 at 09:47
  • You can use a Custom Adapter for that. However, post an example for more clarification will be better :) – BNK Oct 12 '15 at 09:59
  • Question is not clear..... update ur code please – Narendra Kumar Oct 12 '15 at 10:08
  • which Id you talking about?and paste your code here – Aditya Vyas-Lakhan Oct 12 '15 at 11:50
  • Read the following http://stackoverflow.com/questions/33047156/how-to-create-custom-baseadapter-for-autocompletetextview/33049491#33049491 – BNK Oct 12 '15 at 13:31
  • Ok I've read it, but it's not clear to me what problem that fixes. I gather in general people want me to implement a custom adapter, but which method do I override and how do I access an ID or index from this method? – bbsimonbb Oct 12 '15 at 13:59

3 Answers3

1

Once you have initialized the adapter and overdid the item click, all you need to do is get the particular object from your adapter at that particular position of item which you clicked. In java it would be somewhat similar to,

@Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
SomeObject someObject = (SomeObject) adapter.getItem(position);
int id = someObject.getId();
}

Thats all you would need. I am not sure about your code in xamarin, how you would get the position because i don't see any method where the position is input variable, may be you could add the tag to your view and can get the tag on your click method.

var position = ((View)sender).Tag;

But i would recommend , if you can create a class extend the base adapter, that way you will the method GetView to override and can easily do what you are looking for. You constructor could be like this for start,

List<SomeObjects> items;
Activity context;

public CustomAdapter(Activity context, List<SomeObjects> items)
        : base()
    {
        this.context = context;
        this.items = items;
    } 
Ankush Sharma
  • 913
  • 11
  • 20
  • I can get the position from the event, but it's the position in the _filtered_ list. If I could get a handle to this filtered list, my problem would be fixed. _adapter.Filter.FilterResults would do it, according to the docs. But this doesn't appear to be available from Xamarin. Don't know about java. How does extending BaseAdapter help me? It's not event filterable. What does its GetView() method do? – bbsimonbb Oct 12 '15 at 15:39
  • By extending a base adapter , in the get view you could assign a tag to your text view. That way in the click method of yours you can have that tag which will serve you as the position of the item you clicked and you can then locate the id of the object in your holder object. – Ankush Sharma Oct 12 '15 at 16:29
  • I think in getview you can also declare your click method instead of in the activity class itself. – Ankush Sharma Oct 12 '15 at 16:30
  • Well this has been painful and fruitless. To give myself every chance, I derived AutoCompleteTextView then implemented IOnItemClickListener in the derived class. I hunted high and low in parent, view, this, etc. Nowhere can I find a trace of the filtered array of objects, or the selected object. I can't even override the default behaviour that sets the text of the TextView. My handler is executed as well as, not instead of, the default. The OnItemSelected handler appears never to execute. Perhaps this is a xamarin limitation, but the behaviour of this component would appear to be set in stone. – bbsimonbb Oct 13 '15 at 10:34
  • Ok this answer works and I'm accepting. I just needed to cast the adapter, as shown in the C# code I've just posted. – bbsimonbb Oct 13 '15 at 13:40
  • glad, i could help :) – Ankush Sharma Oct 13 '15 at 14:52
0

Here searchText is an Autocompletetextview..

searchText.setOnItemClickListener(new OnItemClickListener() 
        {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) 
            {

                int position = position;     //Adapter selection position

            }

        });
halfer
  • 19,824
  • 17
  • 99
  • 186
Narendra Kumar
  • 551
  • 5
  • 16
0

Ankush's answer worked. I'm posting the C# code here because there are some subtleties with casting and generics...

public class myActv : AutoCompleteTextView, AdapterView.IOnItemClickListener
{
    PhysicalField _physical;
    public myActv(Activity ctx, PhysicalField physical) : base(ctx)
    {
        OnItemClickListener = this;
        _physical = physical;
    }

    public void OnItemClick(AdapterView parent, View view, int position, long id)
    {
         // This is the punchline...
         SomeObject whatIwant = ((ArrayAdapter<SomeObject>)this.Adapter).GetItem(position);
    }
}
bbsimonbb
  • 27,056
  • 15
  • 80
  • 110