How can I handle onListItemClick(…) based on what view inside the row was clicked?

旧城冷巷雨未停 提交于 2019-12-24 17:29:56

问题


Question

I have a listView inside a DialogFragment and I want to fire certain callbacks only when certain particular items inside a row are fired. How can I do that?

Basically, I want to do something like this

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    final int viewId = view.getId();
    if ((viewId == R.id.textView1) || (viewId == R.id.textView2)) {
        // do something...
    }

which I can't. Read further if you don't know why.

What I tried

I tried to look into the documentation, but the OnItemClickListener callback doesn't offer as a parameter the exact clicked view (the View you can see in the signature is the whole row).

Also, I tried to set a simple onClick callback on the single view in the adapter, but this overrides the listSelector and other behavior a list should have. Reading in the documentation, I found it's explicitly written that we should set callbacks via the onListItemClick(...) method (not via onClick(...)), so I'm looking for a way to do that, using this method, not to override any default list behavior.

I was trying to get this done by working on the xml. To my surprise, I found that if I set a view android:clickable property to true, the onListItemClick callback won't fire (I thought it was the opposite), so a partial solution would be to set to android:clickable=true every view in the row apart from the one I want to fire the callback, but that is not a solution because if the user clicks where there is padding or white space, the callback will fire. Also, I found that if I set the parent of the row's view to android:clickable=true and the child views I want to handle with the callback to android:clickable=false, this won't work, because apparently the property is not overwritten.

EDIT Sorry for the really bad title this question had before, I didn't even noticed I submitted the question.


回答1:


new Answer, hope I understood now :)

In your adapters getView, attach an OnClickListener to any view in your layout you want to fire. (more pseudocode)

public class Adapter extends ArrayAdapter<XYZ> {

    private int resource;

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if(convertView==null) convertView = ((LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(this.resource, parent, false);

        ((Button)convertView.findViewById(R.id.YOUR_BUTTON_IN_LAYOUT)).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                DOSTUFF();
            }
        });

        return convertView ;
    }


}

old Answer: The position indicates where you are in the list (pseudocode).

listView.setOnItemClickListener(new OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, final int position,long arg3) {

        YOUR_ITEM_BACKED_BY_ADAPTER item = listView.getItemAtPosition(position);

        if(item==THE_FIRST_ITEM_IN_LIST) doSomething();
        else if(item == THE_LAST_ITEM_IN_LIST) doSomethingElse();               
    }

});



回答2:


You can set listeners for other views inside the adapter's getView

public class MyAdapter extends ArrayAdapter<MyItem> implements View.OnClickListener  {
    public View getView(int position, View convertView, ViewGroup parent) {

        // setup the converView inflating it, for simplicity I've removed that code

        MyItem item = getItem(position);
        text1 = (TextView)convertView.findViewById(R.id.text1);
        text2 = (TextView)convertView.findViewById(R.id.text2);
        text1.setOnClickListener(this);
        // pass the item to use when clicked
        text1.setTag(item);

        text2.setOnClickListener(this);
        text2.setTag(item);
    }


    public void onClick(View v) {
        MyItem item = v.getTag();

        switch (v.getId()) {
            case R.id.text1:
                download(item);
                break;
            case R.id.text2:
                upload(item);
                break;
        }
    }
}

Instead of hardcoding action (eg download) inside the adapter you can pass to it an interface and for example the calling activity can implement that interface



来源:https://stackoverflow.com/questions/21024177/how-can-i-handle-onlistitemclick-based-on-what-view-inside-the-row-was-clic

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!